Skip to content

Tutorials

YOLO Real time detection on CPU

We’re going to learn in this tutorial how to detect objects in real time running YOLO on a CPU.

If you’re a complete beginner about YOLO I highly suggest to check out my other tutorial about YOLO object detection on images, before proceding with realtime detection, as I’m going to use most of the same code I explained there.

Why did I specify that we’re going to perform the detection using the CPU?

I did specify this as with the deep learning frameworks it’s possible to do the detection using the CPU or the GPU.

YOLO on CPU vs YOLO on GPU?

I’m going to quickly to compare yolo on a cpu versus yolo on the gpu explaining advantages and disadvantages for both of them.

YOLO on CPU

The big advantage of running YOLO on the CPU is that it’s really easy to set up and it works right away on Opencv withouth doing any further installations. You only need Opencv 3.4.2 or greater.

The disadvantage is that YOLO, as any deep neural network runs really slow on a CPU and we will be able to process only a few frames per second.
Not really good for a realtime detection.

YOLO on GPU

Instead YOLO on a GPU is really fast, and with a good gpu you can process 45 or more frames per seconds.
So we’re not talking about a small speed difference between a CPU and a GPU, but a huge difference where the GPU greatly outperform the CPU by 20 times faster or more.

The disadvantage is that for a beginner setting up a deep neural network on a GPU can be a really harsh process.
Also it doesn’t work with all the GPUs but only with NVIDIA GPUs wich are compatible with CUDA.
For example right now I’m using a laptop with an AMD Radeon GPU, so it won’t work.

We import the libraries and we load the Network.

import cv2
import numpy as np
import time

# Load Yolo
net = cv2.dnn.readNet("weights/yolov3-tiny.weights", "cfg/yolov3-tiny.cfg")
classes = []
with open("coco.names", "r") as f:
    classes = [line.strip() for line in f.readlines()]
layer_names = net.getLayerNames()
output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
colors = np.random.uniform(0, 255, size=(len(classes), 3))

We then load the the camera.

We get the starting time and the frame ID in order to calculate later how many frames per second FPS we are processing.

# Loading camera
cap = cv2.VideoCapture(0)

font = cv2.FONT_HERSHEY_PLAIN
starting_time = time.time()
frame_id = 0

We run the while loop and we extract the frame from the camera.

while True:
    _, frame = cap.read()
    frame_id += 1

    height, width, channels = frame.shape

We perform the detection.
All this code below is explained in my other tutorial.

    # Detecting objects
    blob = cv2.dnn.blobFromImage(frame, 0.00392, (416, 416), (0, 0, 0), True, crop=False)

    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.2:
                # 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, 0.4, 0.3)

    for i in range(len(boxes)):
        if i in indexes:
            x, y, w, h = boxes[i]
            label = str(classes[class_ids[i]])
            confidence = confidences[i]
            color = colors[class_ids[i]]
            cv2.rectangle(frame, (x, y), (x + w, y + h), color, 2)
            cv2.rectangle(frame, (x, y), (x + w, y + 30), color, -1)
            cv2.putText(frame, label + " " + str(round(confidence, 2)), (x, y + 30), font, 3, (255,255,255), 3)

We then calculate the FPS by deviding the elapsed time by the number of the frames and we show everything on the screen.

    elapsed_time = time.time() - starting_time
    fps = frame_id / elapsed_time
    cv2.putText(frame, "FPS: " + str(round(fps, 2)), (10, 50), font, 3, (0, 0, 0), 3)
    cv2.imshow("Image", frame)
    key = cv2.waitKey(1)
    if key == 27:
        break

cap.release()
cv2.destroyAllWindows()

35 comments

  1. Having the same problem as in the last proyect. (-212:Parsing error) Failed to parse NetParameter file: yolov3-tiny.cfg in function. Any idea? I got opencv-python 4.1.0+contrib installed by PIP. No idea why this happens.

      1. can you set up a new virtual environment and jsut install the minimum packages?

        if I download all from the source above (reply to your question) it works fine

  2. hellow sir!! your all codes are working properly but in this code I am not able to grab frames ? this taking too much time for loading the webcam what should I do ?

  3. Thanks for sharing such a good tutorial. I have applied it and it works like a charm. And I also tryied few more things on top of this
    1) Saving the image detected video: works well
    2) Saving only those frames when it encounters a particular label in the video for example “umbrella” in walking.mp4 video. I have tried couple of things in this and its not giving me the proper results. Will appreciate your suggestions:
    # Attempt1
    # saving video frame by frame
    if i != ”:
    if label == ‘umbrella’:
    out_vid.write(frame)
    # Result: first continuous frame of umbrella object. It doesn’t save umbrella frames that appears later
    # Attempt2
    # saving video frame by frame
    total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
    for frame_numb in range(total_frames):
    if i == ”:
    pass
    else:
    if “umbrella” in label:
    print(“umbrella in labels”)

    # Issue causing part where I may need some change
    out_vid.write(frame[frame_numb])
    # Result: It creates only 256kb file and files fail to open/ not writing anything

    Attempt3:
    # saving video frame by frame
    for frame_numb in range(total_frames):
    if i == ”:
    pass
    else:
    if “umbrella” in label:
    print(“umbrella in labels”)

    # Issue causing part where I may need some change
    out_vid.write(frame)
    # Result: First frame of umbrella saved for whole time.

    Please suggest what changes I could make.

  4. I am getting error
    AttributeError Traceback (most recent call last)
    in ()
    2 while True:
    3 _, frame = cap.read()
    —-> 4 height, width, channels = frame.shape[:]
    5 blob = cv2.dnn.blobFromImage(frame, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
    6 net.setInput(blob)

    AttributeError: ‘NoneType’ object has no attribute ‘shape’

    how to solve this . i tried manyways

    1. frame can’t specify the shape as height & weight
      Try:
      height, width, channels = frame.shape[:3]
      OR => height, width = frame.shape[:2]

      hope it works.

    1. If you want to detect only “person” means you need to modify your class. If you follow up this code, just modify the classes below:

      write => `classes = [“person”]` instead of `classes = []`

      remove these 2 lines from your code:
      with open(“coco.names”, “r”) as f:
      classes = [line.strip() for line in f.readlines()]

      That’s it.

      Let me know if it helps.

      1. Hey raju,
        I did what you said, it worked but when the camera detects anything else in the list for example a “clock” it stops and occurs an error like this :
        Traceback (most recent call last):
        File “C:/Users/asus/AppData/Local/Temp/real_time_yolo.py/onlyperson.py”, line 61, in
        label = str(classes[“person”])
        TypeError: list indices must be integers or slices, not str
        [ WARN:1] global C:\projects\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (674) SourceReaderCB::~SourceReaderCB terminating async callback

        what can we do ? and also is there a way to increase FPS by removing unnecessary objects from list? or another way..? Thanks for your help.

  5. Love your tutorial and thank you for code, It helped me a lot. Can you tell me how to use GPU for this code ? My code is almost similar to yours but almost using other functions too. I want to make my image processing faster with GPU. I have installed CUDA and cudnn its working fine. I would appreciate if you can provide a code for running this process in GPU. Im using Opencv for importing and export Images.

    1. For GPU, add these:
      net.setPreferableBackend(cv.dnn.DNN_BACKEND_CUDA)
      net.setPreferableTarget(cv.dnn.DNN_TARGET_CUDA)

      Make sure your OpenCV is installed properly with CUDA.

  6. Hey i run this code but it wont show me the rectangle box
    like if we detect person then this code does not show me the label ‘person’ at the top
    any one guide me plz! Thanks in advance

  7. Hi ,
    I’m having an issue while running the code . im getting the below issue.
    cv2.error: OpenCV(4.2.0) C:\projects\opencv-python\opencv\modules\dnn\src\darknet\darknet_importer.cpp:214: error: (-212:Parsing error) Failed to parse NetParameter file: weights/yolov3-tiny.weights in function ‘cv::dnn::dnn4_v20191202::readNetFromDarknet’
    can you give me a solution for this please?

  8. I keep getting the same error :
    AttributeError: ‘NoneType’ object has no attribute ‘shape’
    when I try to execute the code in the cap = cv2.VideoCapture() line for both webcam footage as well as a video file saved in the same folder as the code. Can you please tell me how to clear this error?

    1. “AttributeError: ‘NoneType’ object has no attribute ‘shape’”
      This error happens when there is no frame. You have to make sure that the file path is correct and that the webcam is loaded correctly.

      1. I’ve checked the if other applications can access the camera and they can.
        The video file is also in the same folder as the code file.

  9. AttributeError Traceback (most recent call last)

    in ()
    7 _, frame = cap.read()
    8 frame_id += 1
    —-> 9 height, width, channels = frame.shape

    AttributeError: ‘NoneType’ object has no attribute ‘shape’

    i am getting this error please help…

Join the discussion