2025-08-08 20:09:17 +00:00
|
|
|
import json
|
2025-08-07 18:23:53 +00:00
|
|
|
import os
|
|
|
|
|
import depthai as dai
|
|
|
|
|
import numpy as np
|
|
|
|
|
import cv2
|
|
|
|
|
import time
|
|
|
|
|
from utils import converter_mask_ids_para_rgb, carregar_labelmap_completo
|
|
|
|
|
|
|
|
|
|
# ⚙️ Configurações
|
2025-08-08 20:09:17 +00:00
|
|
|
with open("config.json", "r") as f:
|
|
|
|
|
config = json.load(f)
|
|
|
|
|
MODELO = config["camera"]
|
2025-08-11 23:11:23 +00:00
|
|
|
MODEL_NAME = config["model_name"]
|
2025-08-08 20:09:17 +00:00
|
|
|
RESOLUCAO = config["resolucao"]
|
2025-09-15 10:23:07 +00:00
|
|
|
SHAVES = config["shaves"]
|
2025-08-07 18:23:53 +00:00
|
|
|
ROI_INICIO = 0.0
|
|
|
|
|
ROI_TAMANHO = 1.0
|
2025-08-11 23:11:23 +00:00
|
|
|
MAIN_CLASS_NAME = config["main_class_name"]
|
2025-09-15 10:23:07 +00:00
|
|
|
model_to_use = config["model_to_use"]
|
2025-08-07 18:23:53 +00:00
|
|
|
labelmap_path = os.path.join(MODELO, "dataset", "labelmap.txt")
|
2025-09-15 10:23:07 +00:00
|
|
|
model_path = os.path.join(MODELO, "backup", config["modelo"], MODEL_NAME)
|
|
|
|
|
model_name = ""
|
|
|
|
|
if model_to_use == "geral":
|
2025-10-03 21:42:51 +00:00
|
|
|
model_name = f"{MODEL_NAME}_best"
|
2025-09-15 10:23:07 +00:00
|
|
|
elif model_to_use == "main_class":
|
|
|
|
|
MAIN_CLASS_NAME = config["main_class_name"]
|
2025-10-03 21:42:51 +00:00
|
|
|
model_name = f"{MODEL_NAME}_best_f1_{MAIN_CLASS_NAME}"
|
2025-09-15 10:23:07 +00:00
|
|
|
elif model_to_use == "es":
|
|
|
|
|
ES_CLASSES_NAME = config["es_classes"]
|
2025-10-03 21:42:51 +00:00
|
|
|
model_name = f"{MODEL_NAME}_best_es_{ES_CLASSES_NAME}"
|
2025-09-15 10:23:07 +00:00
|
|
|
else:
|
2025-10-03 21:42:51 +00:00
|
|
|
model_name = f"{MODEL_NAME}_best"
|
2025-09-15 10:23:07 +00:00
|
|
|
|
2025-10-03 21:42:51 +00:00
|
|
|
blob_path = os.path.join(model_path, f"{model_name}_openvino_2022.1_{SHAVES}shave.blob")
|
2025-08-07 18:23:53 +00:00
|
|
|
|
|
|
|
|
# Carregar mapa de cores
|
|
|
|
|
_, colormap_rgb, classes, ignore_rgb = carregar_labelmap_completo(labelmap_path)
|
|
|
|
|
NUM_CLASSES = len(classes)
|
|
|
|
|
IGNORE_ID = ignore_rgb[0]
|
|
|
|
|
|
|
|
|
|
# Criar pipeline
|
|
|
|
|
pipeline = dai.Pipeline()
|
|
|
|
|
|
|
|
|
|
# Câmera
|
|
|
|
|
cam = pipeline.createColorCamera()
|
|
|
|
|
cam.setBoardSocket(dai.CameraBoardSocket.CAM_A)
|
|
|
|
|
cam.setResolution(dai.ColorCameraProperties.SensorResolution.THE_1080_P)
|
|
|
|
|
cam.setInterleaved(False)
|
|
|
|
|
cam.setColorOrder(dai.ColorCameraProperties.ColorOrder.RGB)
|
|
|
|
|
cam.setFps(30)
|
|
|
|
|
|
|
|
|
|
# ImageManip (redimensiona para a entrada da rede)
|
|
|
|
|
manip = pipeline.createImageManip()
|
|
|
|
|
|
|
|
|
|
y1 = 1.0 - (ROI_INICIO + ROI_TAMANHO)
|
|
|
|
|
y2 = 1.0 - ROI_INICIO
|
|
|
|
|
|
|
|
|
|
manip.initialConfig.setCropRect(0.0, y1, 1.0, y2)
|
2025-08-08 20:09:17 +00:00
|
|
|
manip.initialConfig.setResize(RESOLUCAO[0], RESOLUCAO[1])
|
2025-08-07 18:23:53 +00:00
|
|
|
manip.initialConfig.setFrameType(dai.RawImgFrame.Type.RGB888p)
|
2025-08-08 20:09:17 +00:00
|
|
|
manip.initialConfig.setKeepAspectRatio(False)
|
|
|
|
|
cam.video.link(manip.inputImage)
|
2025-08-07 18:23:53 +00:00
|
|
|
|
|
|
|
|
# Neural network
|
|
|
|
|
nn = pipeline.createNeuralNetwork()
|
|
|
|
|
nn.setBlobPath(blob_path)
|
|
|
|
|
manip.out.link(nn.input)
|
|
|
|
|
|
|
|
|
|
# Saída RGB para overlay (sem redimensionar)
|
|
|
|
|
xout_rgb = pipeline.createXLinkOut()
|
|
|
|
|
xout_rgb.setStreamName("rgb")
|
2025-08-08 20:09:17 +00:00
|
|
|
cam.video.link(xout_rgb.input)
|
2025-08-07 18:23:53 +00:00
|
|
|
|
|
|
|
|
# Saída NN
|
|
|
|
|
xout_nn = pipeline.createXLinkOut()
|
|
|
|
|
xout_nn.setStreamName("nn")
|
|
|
|
|
nn.out.link(xout_nn.input)
|
|
|
|
|
|
2025-08-08 20:09:17 +00:00
|
|
|
# E garanta que o video stream é 16:9
|
|
|
|
|
#cam.setVideoSize(384, 384) # ou 1280x720
|
|
|
|
|
|
2025-08-07 18:23:53 +00:00
|
|
|
# Rodar pipeline
|
|
|
|
|
with dai.Device(pipeline) as device:
|
|
|
|
|
rgb_queue = device.getOutputQueue("rgb", maxSize=1, blocking=False)
|
|
|
|
|
nn_queue = device.getOutputQueue("nn", maxSize=1, blocking=False)
|
|
|
|
|
|
|
|
|
|
print("Rodando inferência na OAK... Pressione 'q' para sair.")
|
|
|
|
|
prev_time = time.time()
|
|
|
|
|
|
2025-08-08 20:09:17 +00:00
|
|
|
H, W = RESOLUCAO[1], RESOLUCAO[0]
|
|
|
|
|
|
|
|
|
|
in_rgb = rgb_queue.get()
|
|
|
|
|
frame = in_rgb.getCvFrame()
|
|
|
|
|
frame_h, frame_w = frame.shape[:2]
|
|
|
|
|
|
|
|
|
|
y_start = int(y1 * frame_h)
|
|
|
|
|
y_end = int(y2 * frame_h)
|
|
|
|
|
roi_h = y_end - y_start
|
|
|
|
|
roi_w = frame_w
|
|
|
|
|
|
|
|
|
|
pred_ids = np.empty((H, W), dtype=np.uint8)
|
|
|
|
|
pred_rgb = np.empty((H, W, 3), dtype=np.uint8)
|
|
|
|
|
overlay = np.empty((H, W, 3), dtype=np.uint8)
|
|
|
|
|
|
|
|
|
|
lut = np.zeros((256, 3), dtype=np.uint8)
|
|
|
|
|
for i, color in enumerate(colormap_rgb):
|
|
|
|
|
lut[i] = color
|
|
|
|
|
lut[IGNORE_ID] = (255, 255, 255)
|
|
|
|
|
|
2025-08-07 18:23:53 +00:00
|
|
|
while True:
|
|
|
|
|
in_rgb = rgb_queue.get()
|
|
|
|
|
in_nn = nn_queue.get()
|
|
|
|
|
|
|
|
|
|
# Inferência - saída é um vetor flat [num_classes * H * W]
|
2025-08-08 20:09:17 +00:00
|
|
|
out_raw = in_nn.getFirstLayerFp16()
|
|
|
|
|
arr16 = np.frombuffer(np.asarray(out_raw, dtype=np.float16), dtype=np.float16)
|
|
|
|
|
arr16 = arr16.reshape(NUM_CLASSES, H, W)
|
|
|
|
|
pred_ids = arr16.argmax(axis=0).astype(np.uint8, copy=False)
|
2025-08-07 18:23:53 +00:00
|
|
|
|
2025-08-08 20:09:17 +00:00
|
|
|
pred_rgb[:] = lut[pred_ids]
|
|
|
|
|
|
|
|
|
|
frame = in_rgb.getCvFrame()
|
|
|
|
|
cv2.resize(frame, (W, H), interpolation=cv2.INTER_AREA, dst=overlay)
|
|
|
|
|
cv2.addWeighted(overlay, 0.4, pred_rgb, 0.6, 0, dst=overlay)
|
|
|
|
|
|
2025-08-07 18:23:53 +00:00
|
|
|
# FPS
|
|
|
|
|
now = time.time()
|
2025-08-08 20:09:17 +00:00
|
|
|
fps_inst = 1.0 / (now - prev_time)
|
2025-08-07 18:23:53 +00:00
|
|
|
prev_time = now
|
2025-08-08 20:09:17 +00:00
|
|
|
fps = 0.9 * fps + 0.1 * fps_inst if 'fps' in locals() else fps_inst
|
2025-08-07 18:23:53 +00:00
|
|
|
|
2025-08-08 20:09:17 +00:00
|
|
|
cv2.putText(overlay, f"FPS: {fps:.1f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)
|
|
|
|
|
#cv2.imshow("Segmentacao - OAK (on-board)", cv2.cvtColor(overlay, cv2.COLOR_RGB2BGR))
|
|
|
|
|
cv2.imshow("Segmentacao - OAK (on-board)", overlay)
|
2025-08-07 18:23:53 +00:00
|
|
|
if cv2.waitKey(1) & 0xFF == ord('q'):
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
cv2.destroyAllWindows()
|