opencv - 如何测试 OpenCV DNN 模块的准确性?它不能预测 YOLOv3 的正确检测。而暗网检测器可以正确检测
问题描述
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 链接中提供的输出图像。
上面的链接包括测试图像也用于测试步骤
# 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)
解决方案
我认为你的检测是正确的,因为你所有的标签都是汽车,问题是你在这一行的文字:
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 有更好的检测。
推荐阅读
- python-3.x - 在嵌套字典中查找特定键的值
- python-3.x - 从python中的大文件中读取一些特定的行
- r - 如何生成分组堆积条形图
- xcode11 - 如何在 Xcode 设置中删除空格并返回符号
- android - Android:无法使用 videoview 播放视频
- javascript - html css jquery modal 没有在浏览器中打开
- python - Python:列表索引超出范围/追加列表
- python - 从源代码构建 Python 性能
- header - 在 jupyter notebook 中带有自定义编号的 Markdown 标头
- tkinter - 如何创建比例,使用键盘箭头控制它,并使用 tkinter 记录单个值