| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -168,4 +168,6 @@ code_126 | [DNN- Face Detection based on Residual Network](python/code_126) | | |||
| 168 | 168 | code_127 | [DNN- Video Face Detection based on Residual Network](python/code_127) | ✔️ | |
| 169 | 169 | code_128 | [DNN- Call the Detection Model of Tensorflow](python/code_128) | ✔️ | |
| 170 | 170 | code_129 | [DNN- Call the Openpose Implementation Attitude Assessment](python/code_129) | ✔️ | |
| 171 | - code_130 | [DNN- Call YOLO Object Detection Network](python/code_130) | ✔️ | ||
| 171 | + code_130 | [DNN- Call YOLO Object Detection Network](python/code_130) | ✔️ | ||
| 172 | + code_131 | [DNN- YOLOv3-tiny Real-time Object Detection](python/code_131) | ✔️ | ||
| 173 | + code_132 | [DNN- Single and Multiple Image Detection](python/code_132) | ✔️ | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -167,4 +167,6 @@ code_126 | [DNN- 基于残差网络的人脸检测](python/code_126) | ✔️ | |||
| 167 | 167 | code_127 | [DNN- 基于残差网络的视频人脸检测](python/code_127) | ✔️ | |
| 168 | 168 | code_128 | [DNN- 调用tensorflow的检测模型](python/code_128) | ✔️ | |
| 169 | 169 | code_129 | [DNN- 调用openpose模型实现姿态评估](python/code_129) | ✔️ | |
| 170 | - code_130 | [DNN- 调用YOLO对象检测网络](python/code_130) | ✔️ | ||
| 170 | + code_130 | [DNN- 调用YOLO对象检测网络](python/code_130) | ✔️ | ||
| 171 | + code_131 | [DNN- YOLOv3-tiny版本实时对象检测](python/code_131) | ✔️ | ||
| 172 | + code_132 | [DNN- 单张与多张图像的推断](python/code_132) | ✔️ | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,6 @@ | |||
| 1 | + ## OpenCV DNN 支持YOLOv3-tiny版本实时对象检测 | ||
| 2 | + | ||
| 3 | + | ||
| 4 | + YOLOv3的模型在CPU上无法做到实时运行,而YOLO作者提供了个YOLOv3版本的精简版对象检测模型,大小只有30MB左右,它可以在CPU上做到实时运行,这个模型就是YOLOv3-tiny模型。 | ||
| 5 | + | ||
| 6 | + 相比YOLOv3,YOLOv3-tiny只有两个输出层,而且权重参数层与参数文件大小都大大的下降,可以在嵌入式设备与前端实时运行。 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,82 @@ | |||
| 1 | + import cv2 as cv | ||
| 2 | + import numpy as np | ||
| 3 | + | ||
| 4 | + yolo_tiny_model = "../model/yolov3-tiny-coco/yolov3-tiny.weights"; | ||
| 5 | + yolo_tiny_cfg = "../model/yolov3-tiny-coco/yolov3-tiny.cfg"; | ||
| 6 | + | ||
| 7 | + # Load names of classes | ||
| 8 | + classes = None | ||
| 9 | + with open("../model/yolov3-tiny-coco/object_detection_classes_yolov3.txt", 'rt') as f: | ||
| 10 | + classes = f.read().rstrip('\n').split('\n') | ||
| 11 | + | ||
| 12 | + # load tensorflow model | ||
| 13 | + net = cv.dnn.readNetFromDarknet(yolo_tiny_cfg, yolo_tiny_model) | ||
| 14 | + # set back-end | ||
| 15 | + net.setPreferableBackend(cv.dnn.DNN_BACKEND_OPENCV) | ||
| 16 | + net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU) | ||
| 17 | + | ||
| 18 | + cap = cv.VideoCapture() | ||
| 19 | + height = cap.get(cv.CAP_PROP_FRAME_HEIGHT) | ||
| 20 | + width = cap.get(cv.CAP_PROP_FRAME_WIDTH) | ||
| 21 | + vw_out = cv.VideoWriter("1.mp4", cv.VideoWriter_fourcc('D', 'I', 'V', 'X'), 10, (np.int(width), np.int(height)), True) | ||
| 22 | + index = 0 | ||
| 23 | + while True: | ||
| 24 | + ret, image = cap.read() | ||
| 25 | + if ret is False: | ||
| 26 | + break | ||
| 27 | + image = cv.flip(image, 1) | ||
| 28 | + h, w = image.shape[:2] | ||
| 29 | + # 基于多个Region层输出getUnconnectedOutLayersNames | ||
| 30 | + blobImage = cv.dnn.blobFromImage(image, 1.0/255.0, (416, 416), None, True, False); | ||
| 31 | + outNames = net.getUnconnectedOutLayersNames() | ||
| 32 | + net.setInput(blobImage) | ||
| 33 | + outs = net.forward(outNames) | ||
| 34 | + | ||
| 35 | + # Put efficiency information. | ||
| 36 | + t, _ = net.getPerfProfile() | ||
| 37 | + fps = 1000 / (t * 1000.0 / cv.getTickFrequency()) | ||
| 38 | + label = 'FPS: %.2f' % fps | ||
| 39 | + cv.putText(image, label, (0, 15), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0)) | ||
| 40 | + | ||
| 41 | + # 绘制检测矩形 | ||
| 42 | + classIds = [] | ||
| 43 | + confidences = [] | ||
| 44 | + boxes = [] | ||
| 45 | + for out in outs: | ||
| 46 | + for detection in out: | ||
| 47 | + scores = detection[5:] | ||
| 48 | + classId = np.argmax(scores) | ||
| 49 | + confidence = scores[classId] | ||
| 50 | + # numbers are [center_x, center_y, width, height] | ||
| 51 | + if confidence > 0.5: | ||
| 52 | + center_x = int(detection[0] * w) | ||
| 53 | + center_y = int(detection[1] * h) | ||
| 54 | + width = int(detection[2] * w) | ||
| 55 | + height = int(detection[3] * h) | ||
| 56 | + left = int(center_x - width / 2) | ||
| 57 | + top = int(center_y - height / 2) | ||
| 58 | + classIds.append(classId) | ||
| 59 | + confidences.append(float(confidence)) | ||
| 60 | + boxes.append([left, top, width, height]) | ||
| 61 | + | ||
| 62 | + # 使用非最大抑制 | ||
| 63 | + indices = cv.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4) | ||
| 64 | + for i in indices: | ||
| 65 | + i = i[0] | ||
| 66 | + box = boxes[i] | ||
| 67 | + left = box[0] | ||
| 68 | + top = box[1] | ||
| 69 | + width = box[2] | ||
| 70 | + height = box[3] | ||
| 71 | + cv.rectangle(image, (left, top), (left+width, top+height), (0, 0, 255), 2, 8, 0) | ||
| 72 | + cv.putText(image, classes[classIds[i]], (left, top), | ||
| 73 | + cv.FONT_HERSHEY_SIMPLEX, 1.0, (255, 255, 0), 2) | ||
| 74 | + c = cv.waitKey(1) | ||
| 75 | + if c == 27: | ||
| 76 | + break | ||
| 77 | + index += 1 | ||
| 78 | + if 100 < index < 200: | ||
| 79 | + vw_out.write(image) | ||
| 80 | + cv.imshow('YOLOv3-tiny-Detection-Demo', image) | ||
| 81 | + cv.waitKey(0) | ||
| 82 | + cv.destroyAllWindows() | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,50 @@ | |||
| 1 | + ## OpenCV DNN单张与多张图像的推断 | ||
| 2 | + | ||
| 3 | + OpenCV DNN中支持单张图像推断,同时还支持分批次方式的图像推断,对应的两个相关API分别为blobFromImage与blobFromImages,它们的返回对象都是一个四维的Mat对象-按照顺序分别为NCHW 其组织方式详解如下: | ||
| 4 | + | ||
| 5 | + N --> 表示多张图像 | ||
| 6 | + | ||
| 7 | + C --> 表示接受输入图像的通道数目 | ||
| 8 | + | ||
| 9 | + H --> 表示接受输入图像的高度 | ||
| 10 | + | ||
| 11 | + W --> 表示接受输入图像的宽度 | ||
| 12 | + ```python | ||
| 13 | + cv2.dnn.blobFromImage( | ||
| 14 | + image, | ||
| 15 | + scalefactor = 1.0, | ||
| 16 | + size = Size(), | ||
| 17 | + mean = Scalar(), | ||
| 18 | + swapRB = false, | ||
| 19 | + crop = false, | ||
| 20 | + ddepth = CV_32F | ||
| 21 | + ) | ||
| 22 | + ``` | ||
| 23 | + ```python | ||
| 24 | + cv2.dnn.blobFromImages( | ||
| 25 | + images, | ||
| 26 | + scalefactor = 1.0, | ||
| 27 | + size = Size(), | ||
| 28 | + mean = Scalar(), | ||
| 29 | + swapRB = false, | ||
| 30 | + crop = false, | ||
| 31 | + ddepth = CV_32F | ||
| 32 | + ) | ||
| 33 | + ``` | ||
| 34 | + | ||
| 35 | + 参数解释: | ||
| 36 | + | ||
| 37 | + - Images表示多张图像,image表示单张图像 | ||
| 38 | + - Scalefactor表示放缩 | ||
| 39 | + - Size表示图像大小 | ||
| 40 | + - Mean表示均值 | ||
| 41 | + - swapRB是否交换通道 | ||
| 42 | + - crop是否剪切 | ||
| 43 | + - ddepth 输出的类型,默认是浮点数格式 | ||
| 44 | + | ||
| 45 | + | ||
| 46 | + 输出: | ||
| 47 | + | ||
| 48 | + <img src='0.jpg'> | ||
| 49 | + | ||
| 50 | + <img src='1.jpg'> | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,44 @@ | |||
| 1 | + import cv2 as cv | ||
| 2 | + import numpy as np | ||
| 3 | + | ||
| 4 | + bin_model = "../model/google/bvlc_googlenet.caffemodel" | ||
| 5 | + protxt = "../model/google/bvlc_googlenet.prototxt" | ||
| 6 | + | ||
| 7 | + # Load names of classes | ||
| 8 | + classes = None | ||
| 9 | + with open("../model/google/classification_classes_ILSVRC2012.txt", 'rt') as f: | ||
| 10 | + classes = f.read().rstrip('\n').split('\n') | ||
| 11 | + | ||
| 12 | + # load CNN model | ||
| 13 | + net = cv.dnn.readNetFromCaffe(protxt, bin_model) | ||
| 14 | + | ||
| 15 | + # read input data | ||
| 16 | + image1 = cv.imread("cats.jpg") | ||
| 17 | + image2 = cv.imread("car.jpg") | ||
| 18 | + images = [] | ||
| 19 | + images.append(image1) | ||
| 20 | + images.append(image2) | ||
| 21 | + blobs = cv.dnn.blobFromImages(np.asarray(images), 1.0, (224, 224), (104, 117,123), False, crop=False) | ||
| 22 | + print(blobs.shape) | ||
| 23 | + | ||
| 24 | + # Run a model | ||
| 25 | + net.setInput(blobs) | ||
| 26 | + out = net.forward() | ||
| 27 | + # Put efficiency information. | ||
| 28 | + t, _ = net.getPerfProfile() | ||
| 29 | + label = 'Inference time: %.2f ms' % (t * 1000.0 / cv.getTickFrequency()) | ||
| 30 | + print(out.shape) | ||
| 31 | + | ||
| 32 | + # Get a class with a highest score. | ||
| 33 | + for i in range(len(out)): | ||
| 34 | + classId = np.argmax(out[i]) | ||
| 35 | + confidence = out[i][classId] | ||
| 36 | + cv.putText(images[i], label, (0, 15), cv.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0)) | ||
| 37 | + | ||
| 38 | + # Print predicted class. | ||
| 39 | + text_label = '%s: %.4f' % (classes[classId] if classes else 'Class #%d' % classId, confidence) | ||
| 40 | + cv.putText(images[i], text_label, (50, 50), cv.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2) | ||
| 41 | + cv.imshow("googlenet-demo", images[i]) | ||
| 42 | + cv.imwrite("%d.jpg"%i, images[i]) | ||
| 43 | + cv.waitKey(0) | ||
| 44 | + cv.destroyAllWindows() | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments