记录一下win10 下调用yolov3的笔记,方便查阅
1 从GitHub上下载AlexeyAB修改的yolo版本
https://github.com/AlexeyAB/darknet
2 修改一下darknet源代码,增加对python传输图片数据的支持,鉴于水平有限,darknet自带的函数没有调通,
所以新添加了一个,但这一步不是必须的
(1)在yolo_v2_class.cpp中添加如下代码
int detect_mat2(const uint8_t* data, const int height, const int width, bbox_t_container &container) {
#ifdef OPENCV
/* std::vector<char> vdata(data, data + data_length);
cv::Mat image = imdecode(cv::Mat(vdata), 1);*/
int count = 0;
cv::Mat image(height,width, CV_8UC3);
memcpy(image.data, data, sizeof(uchar) * width * height * 3);
std::vector<bbox_t> detection = detector->detect(image);
for (size_t i = 0; i < detection.size() && i < C_SHARP_MAX_OBJECTS; ++i)
container.candidates[i] = detection[i];
return detection.size();
#else
return -1;
#endif // OPENCV
}
(2)在yolo_v2_class.hpp中添加如下代码
extern "C" LIB_API int detect_mat2(const uint8_t* data, const int height, const int widtd, bbox_t_container &container);
3 按照如下的文章生成动态库文件yolo_cpp_dll.dll
https://blog.csdn.net/wxtcstt/article/details/85063755
4 新建python工程
将 yolo_cpp_dll.dll ,pthreadVC2.dll,pthreadGC2.dll,opencv_world340.dll放在工程目录下
目录结构如下:
5 测试目标检测
使用ctype的方式调用C++ dll
app.py 的内容是
import os
import sys
import cv2
import ctypes
import numpy as np
from ctypes import Structure,c_uint,c_int,c_float,byref,c_char_p
libpath=os.path.dirname(sys.argv[0])+"\\yolo_cpp_dll.dll"
detectlib = ctypes.windll.LoadLibrary(libpath)
print(detectlib.detect_mat)
print("successful")
cfgfile=os.path.dirname(sys.argv[0])+"\\yolov3.cfg"
cfgfile = bytes(cfgfile,encoding="utf8")
weights=os.path.dirname(sys.argv[0])+"\\yolov3.weights"
weights = bytes(weights,encoding="utf8")
gpu = 0
#初始化yolo 检测器
detectlib.init(cfgfile,weights,0)
C_SHARP_MAX_OBJECTS=1000
class bbox_t(Structure):
_fields_=[("x",c_uint),("y",c_uint),("w",c_uint),("h",c_uint)
,("prob",c_float),("obj_id",c_int),("track_id",c_int),("frames_counter",c_int),("x_3d",c_float),("y_3d",c_float),("z_3d",c_float) ]
class bbox_t_container(Structure):
_fields_ = [("candidates",bbox_t * C_SHARP_MAX_OBJECTS)]
boxContainer = bbox_t_container()
testimg=os.path.dirname(sys.argv[0])+"\\dog.jpg"
#使用传图片路径的方式调用yolov3
n=detectlib.detect_image(bytes(testimg,encoding='utf8'),byref(boxContainer))
print("\nn:",n)
print(boxContainer.candidates)
for i in range(n):
print(boxContainer.candidates[i].x)
#使用传输图片字节的方式调用yolov3
img=cv2.imread("dog.jpg")
h,w,channel=img.shape
# 获取numpy对象的数据指针
frame_data = np.asarray(img, dtype=np.uint8)
h,w,channel=img.shape
frame_data = frame_data.ctypes.data_as(ctypes.c_char_p)
detectlib.detect_mat.restype = ctypes.c_int8
m = detectlib.detect_mat2(frame_data,h,w,byref(boxContainer))
print("\nn:",m)
for i in range(m):
print(boxContainer.candidates[i].x)
detectlib.dispose()
6 结束