【问题标题】:How to test OpenCV DNN module accuracy? It does not predict correct detections for YOLOv3. Whereas Darknet detector detects correctly如何测试 OpenCV DNN 模块的准确性?它不能预测 YOLOv3 的正确检测。而暗网检测器可以正确检测
【发布时间】:2021-04-09 22:19:10
【问题描述】:

OpenCV DNN 模块无法预测 YOLOv3 的正确检测。而暗网检测器检测正确。

系统信息(版本)

  • OpenCV => 4.2.1 和 4.4.x

  • 操作系统/平台 => Ubuntu 18.04 64Bit

我使用从源代码编译的 OpenCV 测试结果,我也尝试使用预构建的 opencv-python,但 OpenCV DNN 检测到错误的对象。

而暗网检测器检测正确。

使用暗网检测器进行正确检测:

OpenCV DNN 模块的错误检测:

YOLOv3 网络和模型权重来自https://github.com/AlexeyAB/darknet

  • 模型重量:yolov3.weights
  • 模型配置:yolov3.cfg
  • 类文件:coco.names

详细说明

请在下面附加的链接中查看输出图像。 (使用暗网检测器进行正确检测) 与错误检测相比(使用 OpenCV DNN

Google Drive link 中可用的输出图像。

上面的链接包括测试图像也用于测试步骤

    # The following code is partial to demonstrate steps 
    net = cv.dnn.readNetFromDarknet(modelConfiguration, modelWeights)
    layerNames = net.getLayerNames()
    layerNames = [layerNames[i[0] - 1] for i in net.getUnconnectedOutLayers()]
    
    # construct a blob from the input frame and then perform a forward pass of the YOLO object detector, 
    # giving us our bounding boxes and associated probabilities
    blob = cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416),
        swapRB=True, crop=False)
    net.setInput(blob)
    layerOutputs = net.forward(layerNames)
    
    # initialize our lists of detected bounding boxes, confidences,
    # and class IDs, respectively
    boxes = []
    confidences = []
    classIDs = []
 
    # loop over each of the layer outputs
    for output in layerOutputs:
        # loop over each of the detections
        for detection in output:
            # extract the class ID and confidence (i.e., probability)
            # of the current object detection
            scores = detection[5:]
            classID = np.argmax(scores)
            confidence = scores[classID]
 
            # filter out weak predictions by ensuring the detected
            # probability is greater than the minimum probability
            if confidence > args["confidence"]:
                # scale the bounding box coordinates back relative to
                # the size of the image, keeping in mind that YOLO
                # actually returns the center (x, y)-coordinates of
                # the bounding box followed by the boxes' width and
                # height
                box = detection[0:4] * np.array([W, H, W, H])
                (centerX, centerY, width, height) = box.astype("int")
 
                # use the center (x, y)-coordinates to derive the top
                # and and left corner of the bounding box
                x = int(centerX - (width / 2))
                y = int(centerY - (height / 2))
 
                # update our list of bounding box coordinates,
                # confidences, and class IDs
                boxes.append([x, y, int(width), int(height)])
                confidences.append(float(confidence))
                classIDs.append(classID)
                
 
    # apply non-maxima suppression to suppress weak, overlapping
    # bounding boxes
    idxs = cv2.dnn.NMSBoxes(boxes, confidences, args["confidence"], args["threshold"])
    
    dets = []
    if len(idxs) > 0:
        # loop over the indexes we are keeping
        for i in idxs.flatten():
            (x, y) = (boxes[i][0], boxes[i][1])
            (w, h) = (boxes[i][2], boxes[i][3])
            dets.append([x, y, x+w, y+h, confidences[i]])
    
    if len(boxes) > 0:
        i = int(0)
        for box in boxes:
            # extract the bounding box coordinates
            (x, y) = (int(box[0]), int(box[1]))
            (w, h) = (int(box[2]), int(box[3]))
 
            # draw a bounding box rectangle and label on the image
            # color = [int(c) for c in COLORS[classIDs[i]]]
            # cv2.rectangle(frame, (x, y), (x + w, y + h), color, 2)
            color = [int(c) for c in COLORS[indexIDs[i] % len(COLORS)]]
            cv2.rectangle(frame, (x, y), (w, h), color, 2)
     
            cv2.putText(frame, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.75, color, 2)# 1.0 0.5, color, 2)
            i += 1
 
    cv2.imwrite("detection-output.jpg", frame)


【问题讨论】:

    标签: opencv machine-learning neural-network yolo


    【解决方案1】:

    我认为你的检测是正确的,因为你所有的标签都是汽车,问题是你在这一行的文字:

    cv2.putText(frame, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.75, color, 2)
    

    您应该将类​​名放在文本中,但我找不到 text 的定义位置。你的代码应该是这样的:

    cv2.putText(frame, classes[class_ids[index]], (x + 5, y + 20), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, colors,2)
    

    但根据我的经验,darknet 比 opencv dnn 具有更好的检测能力。

    【讨论】:

    • 谢谢@Amir Karami。此代码简短且部分显示了在网络layerNames 上前向传递后,我在 OpenCV DNN 的输出中进行检测所采取的步骤。 text 没有问题。 text 变量在循环中使用类进行更新。 Yolo Model 也还行。问题是在for detection in output: 循环中OpenCV DNN 模块的输出检测错误,我的问题是如何测试OpenCV DNN 的检测精度?
    • @Zach 您可以使用this script 进行mAP 计算。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-07
    • 2019-12-31
    • 2020-01-17
    • 2020-03-05
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    相关资源
    最近更新 更多