├── README.md ├── bus.jpg ├── coco.names ├── dog.jpg ├── main.cpp ├── main_nanodet.py ├── nanodet.onnx ├── nanodet_m.onnx ├── person.jpg └── street.png /README.md: -------------------------------------------------------------------------------- 1 | # nanodet-opncv-dnn-cpp-python 2 | 用opencv部署nanodet目标检测,包含C++和python两种版本程序的实现, 3 | 使用opencv里的dnn模块加载网络模型,图像预处理和后处理模块是使用C++和python编程实现。 4 | 整个程序运行,不依赖任何深度学习框架, 5 | 在windows系统和ubuntu系统,在cpu和gpu机器上都能运行。 6 | 7 | python版本的主程序是main_nanodet.py, c++版本的主程序是main.cpp 8 | 9 | 程序里提供输入图片尺寸320和416这两种选择,类别置信度阈值confThreshold,nms重叠率阈值nmsThreshold可自行调整 10 | 11 | nanodet的后处理模块的解读,可以参阅我写的csdn博客文章 12 | https://blog.csdn.net/nihate/article/details/113850913 13 | -------------------------------------------------------------------------------- /bus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpc203/nanodet-opncv-dnn-cpp-python/15dd99c651d53c824f51d1eb5faddbd4f3d69bbc/bus.jpg -------------------------------------------------------------------------------- /coco.names: -------------------------------------------------------------------------------- 1 | person 2 | bicycle 3 | car 4 | motorbike 5 | aeroplane 6 | bus 7 | train 8 | truck 9 | boat 10 | traffic light 11 | fire hydrant 12 | stop sign 13 | parking meter 14 | bench 15 | bird 16 | cat 17 | dog 18 | horse 19 | sheep 20 | cow 21 | elephant 22 | bear 23 | zebra 24 | giraffe 25 | backpack 26 | umbrella 27 | handbag 28 | tie 29 | suitcase 30 | frisbee 31 | skis 32 | snowboard 33 | sports ball 34 | kite 35 | baseball bat 36 | baseball glove 37 | skateboard 38 | surfboard 39 | tennis racket 40 | bottle 41 | wine glass 42 | cup 43 | fork 44 | knife 45 | spoon 46 | bowl 47 | banana 48 | apple 49 | sandwich 50 | orange 51 | broccoli 52 | carrot 53 | hot dog 54 | pizza 55 | donut 56 | cake 57 | chair 58 | sofa 59 | pottedplant 60 | bed 61 | diningtable 62 | toilet 63 | tvmonitor 64 | laptop 65 | mouse 66 | remote 67 | keyboard 68 | cell phone 69 | microwave 70 | oven 71 | toaster 72 | sink 73 | refrigerator 74 | book 75 | clock 76 | vase 77 | scissors 78 | teddy bear 79 | hair drier 80 | toothbrush 81 | -------------------------------------------------------------------------------- /dog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpc203/nanodet-opncv-dnn-cpp-python/15dd99c651d53c824f51d1eb5faddbd4f3d69bbc/dog.jpg -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #define _CRT_SECURE_NO_WARNINGS 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace cv; 10 | using namespace dnn; 11 | using namespace std; 12 | 13 | class NanoDet 14 | { 15 | public: 16 | NanoDet(int input_shape, float confThreshold, float nmsThreshold); 17 | void detect(Mat& srcimg); 18 | 19 | private: 20 | const int stride[3] = { 8, 16, 32 }; 21 | const string classesFile = "coco.names"; ////这个是存放COCO数据集的类名,如果你是用自己数据集训练的,那么需要修改 22 | int input_shape[2]; //// height, width 23 | const float mean[3] = { 103.53, 116.28, 123.675 }; 24 | const float std[3] = { 57.375, 57.12, 58.395 }; 25 | const int reg_max = 7; 26 | float prob_threshold; 27 | float iou_threshold; 28 | vector classes; 29 | int num_class; 30 | Net net; 31 | 32 | Mat resize_image(Mat srcimg, int* newh, int* neww, int* top, int* left); 33 | void normalize(Mat& srcimg); 34 | void softmax(float* x, int length); 35 | void post_process(vector outs, Mat& frame, int newh, int neww, int top, int left); 36 | void generate_proposal(vector& classIds, vector& confidences, vector& boxes, const int stride_, Mat out_score, Mat out_box); 37 | const bool keep_ratio = true; 38 | }; 39 | 40 | NanoDet::NanoDet(int input_shape, float confThreshold, float nmsThreshold) 41 | { 42 | assert(input_shape==320 || input_shape==416); 43 | this->input_shape[0] = input_shape; 44 | this->input_shape[1] = input_shape; 45 | this->prob_threshold = confThreshold; 46 | this->iou_threshold = nmsThreshold; 47 | 48 | ifstream ifs(this->classesFile.c_str()); 49 | string line; 50 | while (getline(ifs, line)) this->classes.push_back(line); 51 | this->num_class = this->classes.size(); 52 | if(input_shape==320) 53 | { 54 | this->net = readNet("nanodet.onnx"); 55 | } 56 | else 57 | { 58 | this->net = readNet("nanodet_m.onnx"); 59 | } 60 | } 61 | 62 | Mat NanoDet::resize_image(Mat srcimg, int* newh, int* neww, int* top, int* left) 63 | { 64 | int srch = srcimg.rows, srcw = srcimg.cols; 65 | *newh = this->input_shape[0]; 66 | *neww = this->input_shape[1]; 67 | Mat dstimg; 68 | if (this->keep_ratio && srch != srcw) 69 | { 70 | float hw_scale = (float)srch / srcw; 71 | if (hw_scale > 1) 72 | { 73 | *newh = this->input_shape[0]; 74 | *neww = int(this->input_shape[1] / hw_scale); 75 | resize(srcimg, dstimg, Size(*neww, *newh), INTER_AREA); 76 | *left = int((this->input_shape[1] - *neww) * 0.5); 77 | copyMakeBorder(dstimg, dstimg, 0, 0, *left, this->input_shape[1] - *neww - *left, BORDER_CONSTANT, 0); 78 | } 79 | else 80 | { 81 | *newh = (int)this->input_shape[0] * hw_scale; 82 | *neww = this->input_shape[1]; 83 | resize(srcimg, dstimg, Size(*neww, *newh), INTER_AREA); 84 | *top = (int)(this->input_shape[0] - *newh) * 0.5; 85 | copyMakeBorder(dstimg, dstimg, *top, this->input_shape[0] - *newh - *top, 0, 0, BORDER_CONSTANT, 0); 86 | } 87 | } 88 | else 89 | { 90 | resize(srcimg, dstimg, Size(*neww, *newh), INTER_AREA); 91 | } 92 | return dstimg; 93 | } 94 | 95 | void NanoDet::normalize(Mat& img) 96 | { 97 | img.convertTo(img, CV_32F); 98 | int i = 0, j = 0; 99 | for (i = 0; i < img.rows; i++) 100 | { 101 | float* pdata = (float*)(img.data + i * img.step); 102 | for (j = 0; j < img.cols; j++) 103 | { 104 | pdata[0] = (pdata[0] - this->mean[0]) / this->std[0]; 105 | pdata[1] = (pdata[1] - this->mean[1]) / this->std[1]; 106 | pdata[2] = (pdata[2] - this->mean[2]) / this->std[2]; 107 | pdata += 3; 108 | } 109 | 110 | // float* pdata = img.ptr(i); 111 | // for(j = 0; j < img.cols; j++) 112 | // { 113 | // pdata[3 * j] = (pdata[3 * j] - this->mean[0]) / this->std[0]; 114 | // pdata[3 * j + 1] = (pdata[3 * j + 1] - this->mean[1]) / this->std[1]; 115 | // pdata[3 * j + 2] = (pdata[3 * j + 2] - this->mean[2]) / this->std[2]; 116 | // } 117 | } 118 | } 119 | 120 | //Mat NanoDet::normalize(Mat src) 121 | //{ 122 | // vector bgrChannels(3); 123 | // split(src, bgrChannels); 124 | // for (auto i = 0; i < bgrChannels.size(); i++) 125 | // { 126 | // bgrChannels[i].convertTo(bgrChannels[i], CV_32FC1, 1.0 / this->std[i], (0.0 - this->mean[i]) / this->std[i]); 127 | // } 128 | // Mat dst; 129 | // merge(bgrChannels, dst); 130 | // return dst; 131 | //} 132 | 133 | void NanoDet::detect(Mat& srcimg) 134 | { 135 | int newh = 0, neww = 0, top = 0, left = 0; 136 | Mat dstimg = this->resize_image(srcimg, &newh, &neww, &top, &left); 137 | this->normalize(dstimg); 138 | Mat blob = blobFromImage(dstimg); 139 | 140 | this->net.setInput(blob); 141 | vector outs; 142 | this->net.forward(outs, this->net.getUnconnectedOutLayersNames()); 143 | this->post_process(outs, srcimg, newh, neww, top, left); 144 | } 145 | 146 | void NanoDet::softmax(float* x, int length) 147 | { 148 | float sum = 0; 149 | int i = 0; 150 | for (i = 0; i < length; i++) 151 | { 152 | x[i] = exp(x[i]); 153 | sum += x[i]; 154 | } 155 | for (i = 0; i < length; i++) 156 | { 157 | x[i] /= sum; 158 | } 159 | } 160 | 161 | void NanoDet::generate_proposal(vector& classIds, vector& confidences, vector& boxes, const int stride_, Mat out_score, Mat out_box) 162 | { 163 | const int num_grid_y = (int)this->input_shape[0]/stride_; 164 | const int num_grid_x = (int)this->input_shape[1]/stride_; 165 | const int reg_1max = this->reg_max + 1; 166 | 167 | if(out_score.dims==3) 168 | { 169 | out_score = out_score.reshape(0, num_grid_x*num_grid_y); 170 | } 171 | if(out_box.dims==3) 172 | { 173 | out_box = out_box.reshape(0, num_grid_x*num_grid_y); 174 | } 175 | for (int i = 0; i < num_grid_y; i++) 176 | { 177 | for (int j = 0; j < num_grid_x; j++) 178 | { 179 | const int idx = i * num_grid_x + j; 180 | Mat scores = out_score.row(idx).colRange(0, num_class); 181 | Point classIdPoint; 182 | double score; 183 | // Get the value and location of the maximum score 184 | minMaxLoc(scores, 0, &score, 0, &classIdPoint); 185 | if (score >= this->prob_threshold) 186 | { 187 | float* pbox = (float*)out_box.data + idx * reg_1max * 4; 188 | float dis_pred[4]; 189 | for (int k = 0; k < 4; k++) 190 | { 191 | this->softmax(pbox, reg_1max); 192 | float dis = 0.f; 193 | for (int l = 0; l < reg_1max; l++) 194 | { 195 | dis += l * pbox[l]; 196 | } 197 | dis_pred[k] = dis * stride_; 198 | pbox += reg_1max; 199 | } 200 | 201 | float pb_cx = (j + 0.5f) * stride_ - 0.5; 202 | float pb_cy = (i + 0.5f) * stride_ - 0.5; 203 | float x0 = pb_cx - dis_pred[0]; 204 | float y0 = pb_cy - dis_pred[1]; 205 | float x1 = pb_cx + dis_pred[2]; 206 | float y1 = pb_cy + dis_pred[3]; 207 | 208 | classIds.push_back(classIdPoint.x); 209 | confidences.push_back(score); 210 | boxes.push_back(Rect((int)x0, (int)y0, (int)(x1 - x0), (int)(y1 - y0))); 211 | } 212 | } 213 | } 214 | } 215 | 216 | void NanoDet::post_process(vector outs, Mat& frame, int newh, int neww, int top, int left) 217 | { 218 | /////generate proposals 219 | vector classIds; 220 | vector confidences; 221 | vector boxes; 222 | this->generate_proposal(classIds, confidences, boxes, this->stride[0], outs[0], outs[1]); 223 | this->generate_proposal(classIds, confidences, boxes, this->stride[1], outs[2], outs[3]); 224 | this->generate_proposal(classIds, confidences, boxes, this->stride[2], outs[4], outs[5]); 225 | 226 | // Perform non maximum suppression to eliminate redundant overlapping boxes with 227 | // lower confidences 228 | vector indices; 229 | NMSBoxes(boxes, confidences, this->prob_threshold, this->iou_threshold, indices); 230 | float ratioh = (float)frame.rows / newh; 231 | float ratiow = (float)frame.cols / neww; 232 | for (size_t i = 0; i < indices.size(); ++i) 233 | { 234 | int idx = indices[i]; 235 | Rect box = boxes[idx]; 236 | int xmin = (int)max((box.x - left)*ratiow, 0.f); 237 | int ymin = (int)max((box.y - top)*ratioh, 0.f); 238 | int xmax = (int)min((box.x - left + box.width)*ratiow, (float)frame.cols); 239 | int ymax = (int)min((box.y - top + box.height)*ratioh, (float)frame.rows); 240 | rectangle(frame, Point(xmin, ymin), Point(xmax, ymax), Scalar(0, 0, 255), 3); 241 | //Get the label for the class name and its confidence 242 | string label = format("%.2f", confidences[idx]); 243 | label = classes[classIds[idx]] + ":" + label; 244 | 245 | //Display the label at the top of the bounding box 246 | int baseLine; 247 | Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); 248 | ymin = max(ymin, labelSize.height); 249 | //rectangle(frame, Point(left, top - int(1.5 * labelSize.height)), Point(left + int(1.5 * labelSize.width), top + baseLine), Scalar(0, 255, 0), FILLED); 250 | putText(frame, label, Point(xmin, ymin), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 255, 0), 1); 251 | } 252 | } 253 | 254 | int main() 255 | { 256 | NanoDet nanonet(416, 0.35, 0.6); 257 | 258 | string imgpath = "street.png"; ///输入图片的路径,你也可以改成外部传参argv的方式,或者是读取视频文件 259 | Mat srcimg = imread(imgpath); 260 | nanonet.detect(srcimg); 261 | 262 | static const string kWinName = "Deep learning object detection in OpenCV"; 263 | namedWindow(kWinName, WINDOW_NORMAL); 264 | imshow(kWinName, srcimg); 265 | waitKey(0); 266 | destroyAllWindows(); 267 | } 268 | -------------------------------------------------------------------------------- /main_nanodet.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import argparse 4 | 5 | class my_nanodet(): 6 | def __init__(self, input_shape=320, prob_threshold=0.4, iou_threshold=0.3): 7 | with open('coco.names', 'rt') as f: 8 | self.classes = f.read().rstrip('\n').split('\n') 9 | self.num_classes = len(self.classes) 10 | self.strides = (8, 16, 32) 11 | self.input_shape = (input_shape, input_shape) 12 | self.reg_max = 7 13 | self.prob_threshold = prob_threshold 14 | self.iou_threshold = iou_threshold 15 | self.project = np.arange(self.reg_max + 1) 16 | self.mean = np.array([103.53, 116.28, 123.675], dtype=np.float32).reshape(1, 1, 3) 17 | self.std = np.array([57.375, 57.12, 58.395], dtype=np.float32).reshape(1, 1, 3) 18 | if input_shape==320: 19 | self.net = cv2.dnn.readNet('nanodet.onnx') 20 | else: 21 | self.net = cv2.dnn.readNet('nanodet_m.onnx') 22 | 23 | self.mlvl_anchors = [] 24 | for i in range(len(self.strides)): 25 | anchors = self._make_grid((int(self.input_shape[0] / self.strides[i]), int(self.input_shape[1] / self.strides[i])), self.strides[i]) 26 | self.mlvl_anchors.append(anchors) 27 | def _make_grid(self, featmap_size, stride): 28 | feat_h, feat_w = featmap_size 29 | shift_x = np.arange(0, feat_w) * stride 30 | shift_y = np.arange(0, feat_h) * stride 31 | xv, yv = np.meshgrid(shift_x, shift_y) 32 | xv = xv.flatten() 33 | yv = yv.flatten() 34 | cx = xv + 0.5 * (stride-1) 35 | cy = yv + 0.5 * (stride - 1) 36 | return np.stack((cx, cy), axis=-1) 37 | def softmax(self,x, axis=1): 38 | x_exp = np.exp(x) 39 | # 如果是列向量,则axis=0 40 | x_sum = np.sum(x_exp, axis=axis, keepdims=True) 41 | s = x_exp / x_sum 42 | return s 43 | 44 | def _normalize(self, img): ### c++: https://blog.csdn.net/wuqingshan2010/article/details/107727909 45 | img = img.astype(np.float32) 46 | img = (img - self.mean) / self.std 47 | return img 48 | def resize_image(self, srcimg, keep_ratio=True): 49 | top, left, newh, neww = 0, 0, self.input_shape[0], self.input_shape[1] 50 | if keep_ratio and srcimg.shape[0] != srcimg.shape[1]: 51 | hw_scale = srcimg.shape[0] / srcimg.shape[1] 52 | if hw_scale > 1: 53 | newh, neww = self.input_shape[0], int(self.input_shape[1] / hw_scale) 54 | img = cv2.resize(srcimg, (neww, newh), interpolation=cv2.INTER_AREA) 55 | left = int((self.input_shape[1] - neww) * 0.5) 56 | img = cv2.copyMakeBorder(img, 0, 0, left, self.input_shape[1] - neww - left, cv2.BORDER_CONSTANT, 57 | value=0) # add border 58 | else: 59 | newh, neww = int(self.input_shape[0] * hw_scale), self.input_shape[1] 60 | img = cv2.resize(srcimg, (neww, newh), interpolation=cv2.INTER_AREA) 61 | top = int((self.input_shape[0] - newh) * 0.5) 62 | img = cv2.copyMakeBorder(img, top, self.input_shape[0] - newh - top, 0, 0, cv2.BORDER_CONSTANT, value=0) 63 | else: 64 | img = cv2.resize(srcimg, self.input_shape, interpolation=cv2.INTER_AREA) 65 | return img, newh, neww, top, left 66 | def detect(self, srcimg): 67 | img, newh, neww, top, left = self.resize_image(srcimg) 68 | img = self._normalize(img) 69 | blob = cv2.dnn.blobFromImage(img) 70 | # Sets the input to the network 71 | self.net.setInput(blob) 72 | 73 | # Runs the forward pass to get output of the output layers 74 | outs = self.net.forward(self.net.getUnconnectedOutLayersNames()) 75 | det_bboxes, det_conf, det_classid = self.post_process(outs) 76 | 77 | drawimg = srcimg.copy() 78 | ratioh,ratiow = srcimg.shape[0]/newh,srcimg.shape[1]/neww 79 | for i in range(det_bboxes.shape[0]): 80 | xmin, ymin, xmax, ymax = max(int((det_bboxes[i,0] - left) * ratiow), 0), max(int((det_bboxes[i,1] - top) * ratioh), 0), min( 81 | int((det_bboxes[i,2] - left) * ratiow), srcimg.shape[1]), min(int((det_bboxes[i,3] - top) * ratioh), srcimg.shape[0]) 82 | self.drawPred(drawimg, det_classid[i], det_conf[i], xmin, ymin, xmax, ymax) 83 | return drawimg 84 | 85 | def post_process(self, preds): 86 | cls_scores, bbox_preds = preds[::2], preds[1::2] 87 | det_bboxes, det_conf, det_classid = self.get_bboxes_single(cls_scores, bbox_preds, 1, rescale=False) 88 | return det_bboxes.astype(np.int32), det_conf, det_classid 89 | def get_bboxes_single(self, cls_scores, bbox_preds, scale_factor, rescale=False): 90 | mlvl_bboxes = [] 91 | mlvl_scores = [] 92 | for stride, cls_score, bbox_pred, anchors in zip(self.strides, cls_scores, bbox_preds, self.mlvl_anchors): 93 | if cls_score.ndim==3: 94 | cls_score = cls_score.squeeze(axis=0) 95 | if bbox_pred.ndim==3: 96 | bbox_pred = bbox_pred.squeeze(axis=0) 97 | bbox_pred = self.softmax(bbox_pred.reshape(-1, self.reg_max + 1), axis=1) 98 | # bbox_pred = np.sum(bbox_pred * np.expand_dims(self.project, axis=0), axis=1).reshape((-1, 4)) 99 | bbox_pred = np.dot(bbox_pred, self.project).reshape(-1,4) 100 | bbox_pred *= stride 101 | 102 | # nms_pre = cfg.get('nms_pre', -1) 103 | nms_pre = 1000 104 | if nms_pre > 0 and cls_score.shape[0] > nms_pre: 105 | max_scores = cls_score.max(axis=1) 106 | topk_inds = max_scores.argsort()[::-1][0:nms_pre] 107 | anchors = anchors[topk_inds, :] 108 | bbox_pred = bbox_pred[topk_inds, :] 109 | cls_score = cls_score[topk_inds, :] 110 | 111 | bboxes = self.distance2bbox(anchors, bbox_pred, max_shape=self.input_shape) 112 | mlvl_bboxes.append(bboxes) 113 | mlvl_scores.append(cls_score) 114 | 115 | mlvl_bboxes = np.concatenate(mlvl_bboxes, axis=0) 116 | if rescale: 117 | mlvl_bboxes /= scale_factor 118 | mlvl_scores = np.concatenate(mlvl_scores, axis=0) 119 | 120 | bboxes_wh = mlvl_bboxes.copy() 121 | bboxes_wh[:, 2:4] = bboxes_wh[:, 2:4] - bboxes_wh[:, 0:2] ####xywh 122 | classIds = np.argmax(mlvl_scores, axis=1) 123 | confidences = np.max(mlvl_scores, axis=1) ####max_class_confidence 124 | 125 | indices = cv2.dnn.NMSBoxes(bboxes_wh.tolist(), confidences.tolist(), self.prob_threshold, self.iou_threshold) 126 | if len(indices)>0: 127 | mlvl_bboxes = mlvl_bboxes[indices[:, 0]] 128 | confidences = confidences[indices[:, 0]] 129 | classIds = classIds[indices[:, 0]] 130 | return mlvl_bboxes, confidences, classIds 131 | else: 132 | print('nothing detect') 133 | return np.array([]), np.array([]), np.array([]) 134 | def distance2bbox(self, points, distance, max_shape=None): 135 | x1 = points[:, 0] - distance[:, 0] 136 | y1 = points[:, 1] - distance[:, 1] 137 | x2 = points[:, 0] + distance[:, 2] 138 | y2 = points[:, 1] + distance[:, 3] 139 | if max_shape is not None: 140 | x1 = np.clip(x1, 0, max_shape[1]) 141 | y1 = np.clip(y1, 0, max_shape[0]) 142 | x2 = np.clip(x2, 0, max_shape[1]) 143 | y2 = np.clip(y2, 0, max_shape[0]) 144 | return np.stack([x1, y1, x2, y2], axis=-1) 145 | 146 | def drawPred(self, frame, classId, conf, left, top, right, bottom): 147 | # Draw a bounding box. 148 | cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), thickness=4) 149 | 150 | label = '%.2f' % conf 151 | label = '%s:%s' % (self.classes[classId], label) 152 | 153 | # Display the label at the top of the bounding box 154 | labelSize, baseLine = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1) 155 | top = max(top, labelSize[1]) 156 | # cv.rectangle(frame, (left, top - round(1.5 * labelSize[1])), (left + round(1.5 * labelSize[0]), top + baseLine), (255,255,255), cv.FILLED) 157 | cv2.putText(frame, label, (left, top - 10), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), thickness=2) 158 | return frame 159 | 160 | if __name__=='__main__': 161 | parser = argparse.ArgumentParser() 162 | parser.add_argument('--imgpath', type=str, default='street.png', help="image path") 163 | parser.add_argument('--input_shape', default=320, type=int, choices=[320, 416], help='input image shape') 164 | parser.add_argument('--confThreshold', default=0.35, type=float, help='class confidence') 165 | parser.add_argument('--nmsThreshold', default=0.6, type=float, help='nms iou thresh') 166 | args = parser.parse_args() 167 | 168 | srcimg = cv2.imread(args.imgpath) 169 | net = my_nanodet(input_shape=args.input_shape, prob_threshold=args.confThreshold, iou_threshold=args.nmsThreshold) 170 | import time 171 | a = time.time() 172 | srcimg = net.detect(srcimg) 173 | b = time.time() 174 | print('waste time', b-a) 175 | 176 | winName = 'Deep learning object detection in OpenCV' 177 | cv2.namedWindow(winName, cv2.WINDOW_NORMAL) 178 | cv2.imshow(winName, srcimg) 179 | cv2.waitKey(0) 180 | cv2.destroyAllWindows() 181 | -------------------------------------------------------------------------------- /nanodet.onnx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpc203/nanodet-opncv-dnn-cpp-python/15dd99c651d53c824f51d1eb5faddbd4f3d69bbc/nanodet.onnx -------------------------------------------------------------------------------- /nanodet_m.onnx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpc203/nanodet-opncv-dnn-cpp-python/15dd99c651d53c824f51d1eb5faddbd4f3d69bbc/nanodet_m.onnx -------------------------------------------------------------------------------- /person.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpc203/nanodet-opncv-dnn-cpp-python/15dd99c651d53c824f51d1eb5faddbd4f3d69bbc/person.jpg -------------------------------------------------------------------------------- /street.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpc203/nanodet-opncv-dnn-cpp-python/15dd99c651d53c824f51d1eb5faddbd4f3d69bbc/street.png --------------------------------------------------------------------------------