Why is my Opencv not responding or doing any action?

1.1k Views Asked by At

I am doing the YOLO Object detection in Python Opencv. But for some reason it's not responding. If I just simply turn on the camera without the object detection code, it works fine. But if I add the object detection code it is not responding at all. This is my code:

import cv2
import numpy as np
net = cv2.dnn.readNet('yolov3.cfg', 'yolov3.weights')
classes = []
cap = cv2.VideoCapture(0)
with open('coco.names', 'r') as f:
    classes = f.read().splitlines()
while True:
    _, img = cap.read()
    height, width, _ = img.shape
    blob = cv2.dnn.blobFromImage(img, 1/255, (416, 416), (0, 0, 0), swapRB=True, crop=False)
    net.setInput(blob)
    output_layers_names = net.getUnconnectedOutLayersNames()
    layerOutputs = net.forward(output_layers_names)
    boxes = []
    confidence = []
    class_ids = []
    for output in layerOutputs:
        for detection in output:
            scores = detection[5:]
            class_id = np.argmax(scores)
            if confidence > [0.5]:
                center_x = int(detection[0]*width)
                center_y = int(detection[1]*height)
                w = int(detection[2]*width)
                h = int(detection[3]*height)
                x = int(center_x - w/2)
                y = int(center_y - h/2)
                boxes.append([x, y, w, h])
                confidence.append((float(confidence)))
                class_ids.append(class_id)
    indexes = cv2.dnn.NMSBoxes(boxes, confidence, 0.5, 0.4)
    font = cv2.FONT_HERSHEY_PLAIN
    colors = np.random.uniform(0, 255, size=(len(boxes), 3))
    if len(indexes)>0:
        for i in indexes.flatten():
            x,y,w,h = boxes[i]
            label = str(classes[class_ids[i]])
            confidence = str(round(confidence[i], 2))
            color = colors[i]
            cv2.rectangle(img, (x, y), (x+w, y+h), color, 2)
            cv2.putText(img, label + '' + confidence, (x, y+20), font, 2, (255, 255, 255), 2)
    cv2.imshow("Video", img)
if cv2.waitKey(0) & 0xFF == ord('q'):
    break

If I run this code the camera opens but then if I move my hand, it does not move my hand. Is this my code problem or my PC problem? Please help me

And btw the code got a little bit of more spaces or something while uploading to stack overflow, I apologize for that.

1

There are 1 best solutions below

13
On

Try give more time to waitKey() function:

cv2.waitKey(10) & 0xFF == ord('q')
            ^^

Read the doc here for reference waitKey():

The function waitKey waits for a key event infinitely (when ≤0 ) or for delay milliseconds, when it is positive. Since the OS has a minimum time between switching threads, the function will not wait exactly delay ms, it will wait at least delay ms, depending on what else is running on your computer at that time. It returns the code of the pressed key or -1 if no key was pressed before the specified time had elapsed.

Also, check the indentation of your code. Try run this smaller version, if it works, add object detection step by step to find out any other issue:

import cv2 as cv2
import numpy as np
cap = cv2.VideoCapture(0)
while True:
    _, img = cap.read()
    cv2.imshow("Video", img)
    if cv2.waitKey(10) & 0xFF == ord('q'):
        break

Or more readable:

keypressed = cv2.waitKey(10)
if keypressed == ord('q'):
    break

Try this to test the detector

Try this loop, if the detector is working, you should see on terminal a list of detections. If you place yourself in front of the camere, you should see an high score at index 0, which is the coco.names class person.

while True:
    _, img = cap.read()
    img = cv2.resize(img, None, fx=0.5, fy=0.5) # just for more room on my screen
    height, width, _ = img.shape
    blob = cv2.dnn.blobFromImage(img, 1/255, (416, 416), [0, 0, 0], swapRB=True, crop=False)
    net.setInput(blob)
    output_layers_names = net.getUnconnectedOutLayersNames()
    print(output_layers_names) # <-- prints out the list of detections
    layerOutputs = net.forward('yolo_82') # <-- try one layer at a time

    for out in layerOutputs:
        if not np.all(out[5:] == 0): print(out[5:])
    print('-'*50)

    cv2.imshow("Video", img)
    keypressed = cv2.waitKey(10)
    if keypressed == ord('q'):
        break

Once it works, add the rest of the code step by step, checking the result.