在 OpenCV::dnn 模块中,为什么我在 python 中实现相同的代码比在 C++ 中实现更快?

问题描述 投票:0回答:0

这是 Python 中的代码:

import cv2
import cv2 as cv
import time
cvNet = cv.dnn.readNetFromTensorflow('frozen_inference_graph.pb', 'ssd_mobilenet_v3_large_coco_2020_01_14.pbtxt')
cap=cv2.VideoCapture(0);
video_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
video_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
while cv.waitKey(1)!=27:
    t1=time.perf_counter()
    ret, img = cap.read()
    rows = img.shape[0]
    cols = img.shape[1]
    cvNet.setInput(cv.dnn.blobFromImage(img, size=(video_width, video_height), swapRB=True, crop=False))
    cvOut = cvNet.forward()
    for detection in cvOut[0,0,:,:]:
        score = float(detection[2])
        if score > 0.5:
            left = detection[3] * cols
            top = detection[4] * rows
            right = detection[5] * cols
            bottom = detection[6] * rows
            cv.rectangle(img, (int(left), int(top)), (int(right), int(bottom)), (23, 230, 210), thickness=2)

    t2 = time.perf_counter()
    print("%f"%(t2-t1));
    cv.imshow('img', img)

这是 C++ 中的代码:

#include"opencv2/opencv.hpp"
#include<queue>
#include<mutex>
#include<thread>
#include<vector>
#include<chrono>
int main(){
    cv::VideoCapture cap(0);
    int video_height=cap.get(cv::CAP_PROP_FRAME_HEIGHT);
    int video_width=cap.get(cv::CAP_PROP_FRAME_WIDTH);
    cv::dnn::Net net=cv::dnn::readNetFromTensorflow(
        "./bin/frozen_inference_graph.pb",
        "./bin/ssd_mobilenet_v3_large_coco_2020_01_14.pbtxt"
    );
    std::vector<cv::String> outNames = net.getUnconnectedOutLayersNames();
    std::vector<int> outLayers = net.getUnconnectedOutLayers();
    std::string outLayerType = net.getLayer(outLayers[0])->type;
    while(cv::waitKey(1)!=27){
        auto start = std::chrono::system_clock::now();
        cv::Mat frame;
        cap.read(frame);
        cv::flip(frame,frame,1);
        cv::Mat input_blob;
        cv::dnn::blobFromImage(frame,input_blob,1.0,cv::Size(video_width,video_height),cv::Scalar(),true,false);
        net.setInput(input_blob);
        std::vector<cv::Mat> outs;
        net.forward(outs, outNames);
        for (size_t k = 0; k < outs.size(); k++){
                float* data = (float*)outs[k].data;
                for (size_t i = 0; i < outs[k].total(); i += 7)
                {
                    float confidence = data[i + 2];
                    if (confidence > 0.5)
                    {
                        int left   = (int)(data[i + 3]* video_width);
                        int top    = (int)(data[i + 4]* video_height);
                        int right  = (int)(data[i + 5]*video_width);
                        int bottom = (int)(data[i + 6]*video_height);
                        int width  = right - left + 1;
                        int height = bottom - top + 1;
                        cv::rectangle(frame,cv::Size(left,top),cv::Size(right,bottom),cv::Scalar(0,255,0),1);
                    }
                }

        }
        auto finish = std::chrono::system_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::seconds>(finish - start);
        std::cout<<duration.count()<<std::endl;
        cv::imshow("w",frame);
    }

    return 0;
}

我在OpenCV的dnn模块中使用readNetFromTensorflow构建了一个目标检测网络,并使用OpenCV打开摄像头进行实时目标检测

这是我使用的权重文件下载链接:

http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v3_large_coco_2020_01_14.tar.gz

这是我使用的config文件下载链接:

https://gist.github.com/dkurt/54a8e8b51beb3bd3f770b79e56927bd7

我发现python版本我电脑上的C++版本快得多,这是非常不直观的。

python c++ opencv object-detection object-detection-api
© www.soinside.com 2019 - 2024. All rights reserved.