AlexeyAB / darknet

YOLOv4 / Scaled-YOLOv4 / YOLO - Neural Networks for Object Detection (Windows and Linux version of Darknet )
http://pjreddie.com/darknet/
Other
21.63k stars 7.95k forks source link

inference using opencv-dnn module #6118

Open mailcorahul opened 4 years ago

mailcorahul commented 4 years ago

Hi!

I trained a model using darknet yolov4 and wanted to infer using opencv. Cloned opencv repo, checked out to branch 3.4 and built from source(along with contrib).

opencv version was updated to: 3.4.11-pre

Then, I made use of a python script for inference, but faced the following error:

AttributeError: module 'cv2' has no attribute 'dnn_DetectionModel'

Am I doing it right?

So next, I tried to load yolov4 weights and config files using cv2.dnn.readNet and the code executed without any issues. the inference time for one image, 608x608 was around 1.3-1.4 seconds on CPU. Machine configuration: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz, 8 core.

Is it correct to load yolov4 model using dnn.readNet module? And is this the desired inference time for 608x608 yolov4 model on cpu?

Any inputs would be appreciated! Thanks.

@AlexeyAB

marcusbrito commented 4 years ago

You have to load your model like this:

#Loading model
net = cv2.dnn_DetectionModel('yolov4.cfg', 'yolov4.weights')
net.setInputSize(608, 608)
net.setInputScale(1.0 / 255)
net.setInputSwapRB(True)

This works with OpenCV 4.2, I haven't tried it in version 3.4 yet.

the inference time for one image, 608x608 was around 1.3-1.4 seconds on CPU.

I'm also getting 1.3s on average, on a Ryzen 3 2200.

You can speed it up building OpenCV with OpenVino backend, or using GPU. Unfortunately, I still couldn't do either, and I still haven't found tutorials explaining how to do it in a simple way.

mailcorahul commented 4 years ago

@marcusbrito thanks for the reply. I installed opencv 4.2 using pip. The call net = cv2.dnn_DetectionModel('yolov4.cfg', 'yolov4.weights') produces Segmentation fault (core dumped).

Do you know what could be the reason?

AlexeyAB commented 4 years ago
    cv::dnn::Net net;
            net = cv::dnn::readNet(model_path, config_path, framework);
            net.setPreferableBackend(backend);
            net.setPreferableTarget(target);

            out_names = net.getUnconnectedOutLayersNames();
            cv::Mat blob;
            cv::dnn::blobFromImage(frame, blob, 1.0, inp_size, cv::Scalar(), swap_rb, false, CV_8U);
...
mailcorahul commented 4 years ago

@AlexeyAB so I can use readNet module to load and infer yolov4 models? Also, any idea why opencv 4.2 causes segmentation fault?

gachiemchiep commented 4 years ago

@mailcorahul @marcusbrito You shouldn't use the dnn_DetectionModel api. For now it only work for batch=1 (opencv doc). Instead of dnn_DetectionModel, you should use the old dnn.readNet api, it's more flexible and stable. You also need to compile the OpenCV with dnn + cuda enable if you want to use the CUDA (GPU) backend.

# Init network
    net = cv2.dnn.readNet(args.cfg, args.weight, 'darknet')
    net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
    if args.mode == 'fp32':
        net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)
    else:
        net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA_FP16)
    outNames = net.getUnconnectedOutLayersNames()

# create random image for test
  frame = (np.random.standard_normal([args.shape, args.shape, 3]) * 255).astype(np.uint8)
  images = []
  for i in range(args.batch_size):
        images.append(frame)
    # Create a 4D blob from a frame.
    blob = cv2.dnn.blobFromImages(images, size=(args.shape, args.shape), swapRB=True, ddepth=cv2.CV_8U)

# Run a model
net.setInput(blob, scalefactor=1/255.0)
outs = net.forward(outNames)

If you still struggle with opencv dnn then here's the full source code to run yolov4 on webcam.
https://github.com/gachiemchiep/source_code/blob/master/yolov4/opencv/demo_wc.py Here's the full step to step tutorial : https://gachiemchiep.github.io/cheatsheet/reproduce-yolov4-acceleration/#opencv

Hope this help.

mailcorahul commented 4 years ago

@gachiemchiep got it, thanks. i am using readNet function for yolov4 inference. Also the inference time(darknet compiled with opencv) in cpu for 608x608 is one second. is that the expected time?