Untitled

 avatar
unknown
python
3 months ago
7.0 kB
4
Indexable
import cv2
import numpy as np
from openvino.runtime import Core

# Load mô hình OpenVINO
ie = Core()
model_path = "openvino_model.xml"  # Đảm bảo đúng tên file XML đã lưu
compiled_model = ie.compile_model(model_path, "CPU")

# Đọc video đầu vào
video_path = r"C:\Users\Huy\Pictures\video1.mp4"  # Đường dẫn video của bạn
cap = cv2.VideoCapture(video_path)

# Kiểm tra video có mở được không
if not cap.isOpened():
    print(f"Không thể mở video: {video_path}")
    exit()

# Lấy thông tin video và in ra để kiểm tra
fps = cap.get(cv2.CAP_PROP_FPS)
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
print(f"Video FPS: {fps}")
print(f"Video size: {frame_width}x{frame_height}")

# Lấy thông tin kích thước đầu vào của mô hình
input_blob = compiled_model.input(0).any_name
input_shape = compiled_model.input(0).shape  # (1, 3, 640, 640)
input_size = (input_shape[2], input_shape[3])  # (640, 640)

# Danh sách các class của YOLOv8 (80 class COCO)
class_names = ["person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat",
               "traffic light", "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat",
               "dog", "horse", "sheep", "cow", "elephant", "bear", "zebra", "giraffe", "backpack",
               "umbrella", "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball",
               "kite", "baseball bat", "baseball glove", "skateboard", "surfboard", "tennis racket",
               "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple",
               "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake",
               "chair", "couch", "potted plant", "bed", "dining table", "toilet", "TV", "laptop",
               "mouse", "remote", "keyboard", "cell phone", "microwave", "oven", "toaster",
               "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear",
               "hair drier", "toothbrush"]

# Đọc từng frame của video
while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        print("Không thể đọc tiếp frame. Thoát...")
        break

    try:
        # Kiểm tra frame có rỗng không
        if frame is None:
            print("Frame rỗng")
            continue

        # Kiểm tra kích thước frame
        print(f"Frame shape: {frame.shape}")

        # Resize & Chuẩn hóa ảnh về [0,1]
        resized_frame = cv2.resize(frame, input_size)
        normalized_frame = resized_frame.astype(np.float32) / 255.0
        input_tensor = np.expand_dims(normalized_frame.transpose(2, 0, 1), axis=0)

        # Chạy mô hình OpenVINO
        results = compiled_model([input_tensor])[compiled_model.output(0).any_name]
        
        # Chuyển đổi kết quả (1, 84, 8400) -> (8400, 84)
        predictions = np.transpose(results[0])
        
        # Lấy scores và class_ids
        conf_threshold = 0.05  # Giảm ngưỡng xuống thấp hơn
        nms_threshold = 0.3    # Giảm ngưỡng NMS
        
        # Xử lý predictions
        object_scores = predictions[:, 4]
        class_scores = predictions[:, 5:]
        
        print(f"Max confidence score: {np.max(object_scores):.4f}")
        
        # Lọc các dự đoán có confidence > threshold
        mask = object_scores > conf_threshold
        boxes_detected = predictions[mask, :4]
        scores_detected = object_scores[mask]
        class_scores_detected = class_scores[mask]
        class_ids_detected = np.argmax(class_scores_detected, axis=1)
        
        print(f"Number of detections before NMS: {len(boxes_detected)}")
        
        if len(boxes_detected) > 0:
            # Chuyển đổi tọa độ box về tỷ lệ của frame gốc
            img_h, img_w = frame.shape[:2]
            
            # Tạo danh sách boxes cho NMS
            nms_boxes = []
            nms_scores = []
            nms_class_ids = []
            
            for i in range(len(boxes_detected)):
                # Lấy tọa độ box
                x, y, w, h = boxes_detected[i]
                
                # Chuyển từ xywh sang xyxy trong tọa độ gốc
                x1 = int((x - w/2) * img_w)
                y1 = int((y - h/2) * img_h)
                x2 = int((x + w/2) * img_w)
                y2 = int((y + h/2) * img_h)
                
                # Kiểm tra box có nằm trong frame không
                if (x1 >= -10 and y1 >= -10 and x2 < img_w + 10 and y2 < img_h + 10 and 
                    w > 0 and h > 0 and x2 > x1 and y2 > y1):
                    nms_boxes.append([x1, y1, x2, y2])
                    nms_scores.append(scores_detected[i])
                    nms_class_ids.append(class_ids_detected[i])
            
            print(f"Number of valid boxes before NMS: {len(nms_boxes)}")
            
            # Áp dụng NMS nếu có boxes hợp lệ
            if len(nms_boxes) > 0:
                indices = cv2.dnn.NMSBoxes(
                    nms_boxes,
                    nms_scores,
                    conf_threshold,
                    nms_threshold
                )
                
                print(f"Number of boxes after NMS: {len(indices)}")
                
                # Vẽ các box sau NMS
                for i in indices:
                    box = nms_boxes[i]
                    x1, y1, x2, y2 = box
                    
                    # Giới hạn tọa độ trong frame
                    x1 = max(0, min(x1, img_w-1))
                    y1 = max(0, min(y1, img_h-1))
                    x2 = max(0, min(x2, img_w-1))
                    y2 = max(0, min(y2, img_h-1))
                    
                    # Vẽ box
                    cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
                    
                    # Vẽ label
                    label = f"{class_names[nms_class_ids[i]]}: {nms_scores[i]:.2f}"
                    cv2.putText(frame, label, (x1, y1 - 10), 
                               cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
                    
                    print(f"Drawing box: ({x1}, {y1}, {x2}, {y2}) for {label}")

        # Hiển thị kết quả
        cv2.imshow("YOLOv8 OpenVINO Video Detection", frame)
        
        # Thêm độ trễ phù hợp với FPS của video
        key = cv2.waitKey(1) & 0xFF  # Giảm độ trễ xuống 1ms
        if key == ord('q'):
            break

    except Exception as e:
        print(f"\nLỗi xử lý frame: {str(e)}")
        import traceback
        traceback.print_exc()
        break

# Giải phóng tài nguyên
cap.release()
cv2.destroyAllWindows()
Editor is loading...
Leave a Comment