First of all here is my code :
image = cv2.imread(filePath)
height, width, channels = image.shape
# USing blob function of opencv to preprocess image
blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (416, 416),
swapRB=True, crop=False)
#Detecting objects
net.setInput(blob)
outs = net.forward(output_layers)
# Showing informations on the screen
class_ids = []
confidences = []
boxes = []
for out in outs:
for detection in out:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.7:
# Object detected
center_x = int(detection[0] * width)
center_y = int(detection[1] * height)
w = int(detection[2] * width)
h = int(detection[3] * height)
# Rectangle coordinates
x = int(center_x - w / 2)
y = int(center_y - h / 2)
boxes.append([x, y, w, h])
confidences.append(float(confidence))
class_ids.append(class_id)
indexes = cv2.dnn.NMSBoxes(boxes, confidences,score_threshold=0.4,nms_threshold=0.8,top_k=1)
font = cv2.FONT_HERSHEY_PLAIN
colors = np.random.uniform(0, 255, size=(len(classes), 3))
labels = ['bicycle','car','motorbike','bus','truck']
for i in range(len(boxes)):
if i in indexes:
label = str(classes[class_ids[i]])
if label in labels:
x, y, w, h = boxes[i]
color = colors[class_ids[i]]
cv2.rectangle(image, (x, y), (x + w, y + h), color, 2)
cv2.putText(image, label, (x, y + 30), font, 2, color, 3)
cv2.imshow(fileName,image)
My Question is : Isn't cv2.dnn.NMSBoxes
is suppose to eliminate multiple bounding boxes? then why I still get output like sample below :
What I expected is something like below :
Did I do something wrong with my code? Is there any better alternative? Thank you very much for your help.
The process of NMS goes something like this
Input - A list of Proposal boxes (B), corresponding confidence scores (S) and an overlap threshold (N)
Output - A list of filtered proposals (D)
Algorithm
The IOU threshold is the nms_threshold
.
So if you have a larger value for it, you're essentially enforcing two boxes to have a very high overlap (this will vary based on the type of object being detected) and the box will be removed only if it has an IOU more than 0.8 with another box. Since there's usually not this much overlap, the boxes won't be removed. Reducing this value will make it easier to remove redundant detections
I hope this makes sense.
You can read more about Non-Maxima Suppression here