python/c++ opencv dnn模块调用yolov5-onnx权重文件做检测
非常简单的yolov5应用,不需要pytorch环境库,只需要opencv库即可,可以很简单很轻松的部署!!!
项目中自带yolov5n.onnx,如果需要yolov5其他模型onnx权重文件,可以从我的百度网盘提取。提取码: 1cj3
项目地址
github地址,yolov5_onnx_dnn(代码已注释)
如何在windows Visual Studio中配置 c++ opencv环境
配置 c++ opencv环境
本项目支持对图片和视频进行检测,也支持摄像头实时检测。 有问题请及时留言,如果帮助到了你,请在github留下star!
yolov5_non_max_suppression模块,需要将原始pytorch写的非极大值抑制代码,都转为numpy格式,方便摆脱pytorch框架。
def non_max_suppression(self,prediction, conf_thres=0.25,agnostic=False):
xc = prediction[..., 4] > conf_thres
min_wh, max_wh = 2, 4096
max_nms = 30000
output = [np.zeros((0, 6))] * prediction.shape[0]
for xi, x in enumerate(prediction):
x = x[xc[xi]]
if not x.shape[0]:
continue
x[:, 5:] *= x[:, 4:5]
box = self.xywh2xyxy(x[:, :4])
conf = np.max(x[:, 5:], axis=1)
j = np.argmax(x[:, 5:],axis=1)
re = np.array(conf.reshape(-1)> conf_thres)
conf =conf.reshape(-1,1)
j = j.reshape(-1,1)
x = np.concatenate((box,conf,j),axis=1)[re]
n = x.shape[0]
if not n:
continue
elif n > max_nms:
x = x[x[:, 4].argsort(descending=True)[:max_nms]]
c = x[:, 5:6] * (0 if agnostic else max_wh)
boxes, scores = x[:, :4] + c, x[:, 4]
i = self.numpy_nms(boxes, scores, self.nmsThreshold)
output[xi] = x[i]
return output
yolov5_letterbox解释:以最长边放缩图片,然后最短边补灰边
def letterbox(self, im, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True, stride=32):
shape = im.shape[:2]
if isinstance(new_shape, int):
new_shape = (new_shape, new_shape)
r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
if not scaleup:
r = min(r, 1.0)
ratio = r, r
new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]
if auto:
dw, dh = np.mod(dw, stride), np.mod(dh, stride)
elif scaleFill:
dw, dh = 0.0, 0.0
new_unpad = (new_shape[1], new_shape[0])
ratio = new_shape[1] / shape[1], new_shape[0] / shape[0]
dw /= 2
dh /= 2
if shape[::-1] != new_unpad:
im = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR)
top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))
left, right = int(round(dw - 0.1)), int(round(dw + 0.1))
im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)
return im, ratio, (dw, dh)