A A
[CV] OpenCV DNN ํŒจํ‚ค์ง€ & SSD ๊ธฐ๋ฐ˜ Object Detection ์ˆ˜ํ–‰

Tensorflow์—์„œ Pretrained ๋œ ๋ชจ๋ธ ํŒŒ์ผ์„ OpenCV์—์„œ ๋กœ๋“œํ•˜์—ฌ ์ด๋ฏธ์ง€์™€ ์˜์ƒ์— ๋Œ€ํ•œ Object Detection์„ ์ˆ˜ํ–‰ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ž…๋ ฅ ์ด๋ฏธ์ง€๋กœ ์‚ฌ์šฉ๋  ์ด๋ฏธ์ง€ ๋ณด๊ธฐ

import cv2
import matplotlib.pyplot as plt
%matplotlib inline

img = cv2.imread('../../data/image/beatles01.jpg')
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

print('image shape:', img.shape)
plt.figure(figsize=(12, 12))
plt.imshow(img_rgb)
image shape: (633, 806, 3)
<matplotlib.image.AxesImage at 0x7fda701ddc88>

OpenCV๋กœ ๋กœ๋”ฉ


Inference ๋ชจ๋ธ ์ƒ์„ฑ

Tensorflow์—์„œ Pretrained ๋œ Inference๋ชจ๋ธ(Frozen graph)์™€ ํ™˜๊ฒฝํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œ ๋ฐ›์€ ํ›„ ์ด๋ฅผ ์ด์šฉํ•ด OpenCV์—์„œ Inference ๋ชจ๋ธ์„ ์ƒ์„ฑํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
  • ๋‹ค์šด๋กœ๋“œ URL์€ ์•„๋ž˜ ๋งํฌ์— ์žˆ์Šต๋‹ˆ๋‹ค.
 

Home

Open Source Computer Vision Library. Contribute to opencv/opencv development by creating an account on GitHub.

github.com

 

 

opencv_extra/testdata/dnn/ssd_inception_v2_coco_2017_11_17.pbtxt at master · opencv/opencv_extra

OpenCV extra data. Contribute to opencv/opencv_extra development by creating an account on GitHub.

github.com

  • download๋œ ๋ชจ๋ธ ํŒŒ์ผ๊ณผ config ํŒŒ์ผ์„ ์ธ์ž๋กœ ํ•˜์—ฌ inference ๋ชจ๋ธ์„ DNN์—์„œ ๋กœ๋”ฉํ•ฉ๋‹ˆ๋‹ค.

  • ์ด Model ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ณด๋ฉด, MobileNet-SSD v2, Inception-SSD v2 ๋ชจ๋ธ์€ ์ €์‚ฌ์–‘ ๋””๋ฐ”์ด์Šค์—์„œ Object Detection์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ํ•œ๋ฒˆ ์ˆ˜ํ–‰ ์„ฑ๋Šฅ์„ ๋น„๊ตํ•ด ๋ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
# mkdir pretrained; cd pretrained
# wget http://download.tensorflow.org/models/object_detection/ssd_inception_v2_coco_2017_11_17.tar.gz
# wget https://raw.githubusercontent.com/opencv/opencv_extra/master/testdata/dnn/ssd_inception_v2_coco_2017_11_17.pbtxt
# cd ssd_inception_v2_coco_2017_11_17; mv ssd_inception_v2_coco_2017_11_17.pbtxt graph.pbtxt
# https://github.com/opencv/opencv_extra/blob/master/testdata/dnn/ssd_inception_v2_coco_2017_11_17.pbtxt?raw=true -O ./graph.pbtxt
!pwd
!ls pretrained/ssd_inception_v2_coco_2017_11_17
/home/younggi.kim999/DLCV/Detection/ssd
checkpoint		   model.ckpt.data-00000-of-00001  saved_model
frozen_inference_graph.pb  model.ckpt.index
graph.pbtxt		   model.ckpt.meta
  • ์—ฌ๊ธฐ ์žˆ๋Š” Directory๋“ค์€ Pre-Trained๋œ Mdoel๋“ค์ด ์žˆ๋Š” Directory์ž…๋‹ˆ๋‹ค.
    • frozen_inference_graph.pb, graph.pbtxt ๊ฐ€ ํ•ด๋‹น๋ฉ๋‹ˆ๋‹ค.
cv_net = cv2.dnn.readNetFromTensorflow('./pretrained/ssd_inception_v2_coco_2017_11_17/frozen_inference_graph.pb', 
                                     './pretrained/ssd_inception_v2_coco_2017_11_17/graph.pbtxt')
  • ์ฒซ๋ฒˆ์งธ 'frozen_inference_graph.pb'๋Š” wait file
  • ๋‘๋ฒˆ์งธ 'graph.pbtxt'๋Š” config file ์ž…๋‹ˆ๋‹ค.

CoCo ๋ฐ์ดํ„ฐ์…‹์˜ ํด๋ž˜์Šค ID๋ณ„ ํด๋ž˜์Šค๋ช… ์ง€์ •

labels_to_names_seq= {0:'person',1:'bicycle',2:'car',3:'motorcycle',4:'airplane',5:'bus',6:'train',7:'truck',8:'boat',9:'traffic light',
                    10:'fire hydrant',11:'street sign',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:'hat',26:'backpack',27:'umbrella',28:'shoe',29:'eye glasses',
                    30:'handbag',31:'tie',32:'suitcase',33:'frisbee',34:'skis',35:'snowboard',36:'sports ball',37:'kite',38:'baseball bat',39:'baseball glove',
                    40:'skateboard',41:'surfboard',42:'tennis racket',43:'bottle',44:'plate',45:'wine glass',46:'cup',47:'fork',48:'knife',49:'spoon',
                    50:'bowl',51:'banana',52:'apple',53:'sandwich',54:'orange',55:'broccoli',56:'carrot',57:'hot dog',58:'pizza',59:'donut',
                    60:'cake',61:'chair',62:'couch',63:'potted plant',64:'bed',65:'mirror',66:'dining table',67:'window',68:'desk',69:'toilet',
                    70:'door',71:'tv',72:'laptop',73:'mouse',74:'remote',75:'keyboard',76:'cell phone',77:'microwave',78:'oven',79:'toaster',
                    80:'sink',81:'refrigerator',82:'blender',83:'book',84:'clock',85:'vase',86:'scissors',87:'teddy bear',88:'hair drier',89:'toothbrush',
                    90:'hair brush'}

OpenCV์™€ Tensorflow์˜ CoCo ํด๋ž˜์Šค ID์™€ Name Mapping


์ด๋ฏธ์ง€๋ฅผ Preprocessing์„ ์ˆ˜ํ–‰ํ•˜์—ฌ Network์— ์ž…์‚ฌํ•˜๊ณ  Object Detection ์ˆ˜ํ–‰ ํ›„ ๊ฒฐ๊ณผ๋ฅผ ์ด๋ฏธ์ง€๋ฅผ ์‹œ๊ฐํ™”

# ์›๋ณธ ์ด๋ฏธ์ง€ (633, 806)๋ฅผ ๋„คํŠธ์›์— ์ž…๋ ฅ์‹œ์—๋Š” (300, 300)๋กœ resize ํ•จ. 
# ์ดํ›„ ๊ฒฐ๊ณผ๊ฐ€ ์ถœ๋ ฅ๋˜๋ฉด resize๋œ ์ด๋ฏธ์ง€ ๊ธฐ๋ฐ˜์œผ๋กœ bounding box ์œ„์น˜๊ฐ€ ์˜ˆ์ธก ๋˜๋ฏ€๋กœ ์ด๋ฅผ ๋‹ค์‹œ ์›๋ณตํ•˜๊ธฐ ์œ„ํ•ด ์›๋ณธ ์ด๋ฏธ์ง€ shape์ •๋ณด ํ•„์š”
rows = img.shape[0]
cols = img.shape[1]
# cv2์˜ rectangle()์€ ์ธ์ž๋กœ ๋“ค์–ด์˜จ ์ด๋ฏธ์ง€ ๋ฐฐ์—ด์— ์ง์ ‘ ์‚ฌ๊ฐํ˜•์„ ์—…๋ฐ์ดํŠธ ํ•˜๋ฏ€๋กœ ๊ทธ๋ฆผ ํ‘œํ˜„์„ ์œ„ํ•œ ๋ณ„๋„์˜ ์ด๋ฏธ์ง€ ๋ฐฐ์—ด ์ƒ์„ฑ. 
draw_img = img.copy()

# ์›๋ณธ ์ด๋ฏธ์ง€ ๋ฐฐ์—ด์„ ์‚ฌ์ด์ฆˆ (300, 300)์œผ๋กœ, BGR์„ RGB๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๋ฐฐ์—ด ์ž…๋ ฅ
cv_net.setInput(cv2.dnn.blobFromImage(img,  size=(300, 300), swapRB=True, crop=False))
# Object Detection ์ˆ˜ํ–‰ํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ cv_out์œผ๋กœ ๋ฐ˜ํ™˜ 
cv_out = cv_net.forward()
print(cv_out.shape)

# bounding box์˜ ํ…Œ๋‘๋ฆฌ์™€ caption ๊ธ€์ž์ƒ‰ ์ง€์ •
green_color=(0, 255, 0)
red_color=(0, 0, 255)

# detected ๋œ object๋“ค์„ iteration ํ•˜๋ฉด์„œ ์ •๋ณด ์ถ”์ถœ
for detection in cv_out[0,0,:,:]:
    score = float(detection[2])
    class_id = int(detection[1])
    # detected๋œ object๋“ค์˜ score๊ฐ€ 0.4 ์ด์ƒ๋งŒ ์ถ”์ถœ
    if score > 0.4:
        # detected๋œ object๋“ค์€ image ํฌ๊ธฐ๊ฐ€ (300, 300)์œผ๋กœ scale๋œ ๊ธฐ์ค€์œผ๋กœ ์˜ˆ์ธก๋˜์—ˆ์œผ๋ฏ€๋กœ ๋‹ค์‹œ ์›๋ณธ ์ด๋ฏธ์ง€ ๋น„์œจ๋กœ ๊ณ„์‚ฐ
        left = detection[3] * cols
        top = detection[4] * rows
        right = detection[5] * cols
        bottom = detection[6] * rows
        # labels_to_names ๋”•์…”๋„ˆ๋ฆฌ๋กœ class_id๊ฐ’์„ ํด๋ž˜์Šค๋ช…์œผ๋กœ ๋ณ€๊ฒฝ. opencv์—์„œ๋Š” class_id + 1๋กœ ๋งคํ•‘ํ•ด์•ผํ•จ.
        caption = "{}: {:.4f}".format(labels_to_names[class_id], score)
        
        #cv2.rectangle()์€ ์ธ์ž๋กœ ๋“ค์–ด์˜จ draw_img์— ์‚ฌ๊ฐํ˜•์„ ๊ทธ๋ฆผ. ์œ„์น˜ ์ธ์ž๋Š” ๋ฐ˜๋“œ์‹œ ์ •์ˆ˜ํ˜•.
        cv2.rectangle(draw_img, (int(left), int(top)), (int(right), int(bottom)), color=green_color, thickness=2)
        cv2.putText(draw_img, caption, (int(left), int(top - 5)), cv2.FONT_HERSHEY_SIMPLEX, 0.7, red_color, 2)
        print(caption, class_id)

img_rgb = cv2.cvtColor(draw_img, cv2.COLOR_BGR2RGB)

plt.figure(figsize=(12, 12))
plt.imshow(img_rgb)

 

(1, 1, 100, 7)
person: 0.9696 1
person: 0.9660 1
person: 0.8916 1
person: 0.6298 1
car: 0.8609 3
car: 0.7223 3
car: 0.7184 3
car: 0.7095 3
car: 0.5949 3
car: 0.5511 3
<matplotlib.image.AxesImage at 0x7fda6c0c92b0>

 

๊ฒฐ๊ณผ ๋ฐฐ์—ด์˜ ํ˜•ํƒœ (1, 1, 100, 7)
- ๊ฐ์ฒด ๊ฒ€์ถœ ๋„คํŠธ์›Œํฌ์˜ ์ถœ๋ ฅ ํ˜•ํƒœ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
- (1, 1, 100, 7)๋Š” ๋ฐฐ์น˜ ํฌ๊ธฐ 1, ์ฑ„๋„ 1, 100๊ฐœ์˜ ๊ฒ€์ถœ๋œ ๊ฐ์ฒด, ๊ฐ ๊ฐ์ฒด๋‹น 7๊ฐœ์˜ ์ •๋ณด(ํด๋ž˜์Šค ID, ์‹ ๋ขฐ๋„ ์ ์ˆ˜, bounding box ์ขŒํ‘œ)๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

๊ฐ์ฒด ๊ฒ€์ถœ ๊ฒฐ๊ณผ
- ๊ฐ์ฒด ๊ฒ€์ถœ ๊ฒฐ๊ณผ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ๋‚˜์—ดํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
- person: 0.9696 1: ๊ฒ€์ถœ๋œ ๊ฐ์ฒด๊ฐ€ 'person'์ด๊ณ , ์‹ ๋ขฐ๋„ ์ ์ˆ˜๋Š” 0.9696์ด๋ฉฐ, ํด๋ž˜์Šค ID๋Š” 1์ž…๋‹ˆ๋‹ค.
- ๋™์ผํ•œ ํ˜•์‹์œผ๋กœ ๋‹ค๋ฅธ ๊ฐ์ฒด๋“ค๋„ ๋‚˜์—ด๋ฉ๋‹ˆ๋‹ค.
- ์˜ˆ๋ฅผ ๋“ค์–ด, car: 0.8609 3์€ ๊ฒ€์ถœ๋œ ๊ฐ์ฒด๊ฐ€ 'car'์ด๊ณ , ์‹ ๋ขฐ๋„ ์ ์ˆ˜๋Š” 0.8609์ด๋ฉฐ, ํด๋ž˜์Šค ID๋Š” 3์ž…๋‹ˆ๋‹ค.
  • ์ด ์ฝ”๋“œ๋Š” ์ด๋ฏธ์ง€ ๊ฐ์ฒด ๊ฒ€์ถœ(Object Detection)์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ์›๋ณธ ์ด๋ฏธ์ง€์— ๊ฒ€์ถœ๋œ ๊ฐ์ฒด์˜ ๊ฒฝ๊ณ„ ์ƒ์ž(bounding box)์™€ ํด๋ž˜์Šค๋ช…์„ ํ‘œ์‹œํ•˜๋Š” ๊ณผ์ •์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  • ๋จผ์ € ์›๋ณธ ์ด๋ฏธ์ง€์˜ ํฌ๊ธฐ์™€ ๋ณต์‚ฌ๋ณธ์„ ์ƒ์„ฑํ•˜๊ณ , ์ด๋ฏธ์ง€๋ฅผ (300, 300) ํฌ๊ธฐ๋กœ ๋ฆฌ์‚ฌ์ด์ฆˆํ•œ ํ›„ RGB๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๋„คํŠธ์›Œํฌ์— ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.
  • ๊ฐ์ฒด ๊ฒ€์ถœ์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ์ถ”์ถœํ•œ ๋’ค, ๊ฒ€์ถœ๋œ ๊ฐ ๊ฐ์ฒด์— ๋Œ€ํ•ด ๊ฒ€์ถœ ์ ์ˆ˜๊ฐ€ 0.4 ์ด์ƒ์ธ ๊ฒฝ์šฐ bounding box ์ขŒํ‘œ๋ฅผ ์›๋ณธ ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๋ณต์‚ฌ๋ณธ ์ด๋ฏธ์ง€์— ๊ฒฝ๊ณ„ ์ƒ์ž์™€ ํด๋ž˜์Šค๋ช…์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • ๋งˆ์ง€๋ง‰์œผ๋กœ ์ด๋ฏธ์ง€๋ฅผ RGB ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

๋‹จ์ผ ์ด๋ฏธ์ง€์˜ Object Detection์€ ํ•จ์ˆ˜๋กœ ์ƒ์„ฑ

import time

def get_detected_img(cv_net, img_array, score_threshold, use_copied_array=True, is_print=True):
    
    rows = img_array.shape[0]
    cols = img_array.shape[1]
    
    draw_img = None
    if use_copied_array:
        draw_img = img_array.copy()
        #draw_img = cv2.cvtColor(draw_img, cv2.COLOR_BGR2RGB)
    else:
        draw_img = img_array
    
    cv_net.setInput(cv2.dnn.blobFromImage(img_array, size=(300, 300), swapRB=True, crop=False))
    
    start = time.time()
    cv_out = cv_net.forward()
    
    green_color=(0, 255, 0)
    red_color=(0, 0, 255)

    # detected ๋œ object๋“ค์„ iteration ํ•˜๋ฉด์„œ ์ •๋ณด ์ถ”์ถœ
    for detection in cv_out[0,0,:,:]:
        score = float(detection[2])
        class_id = int(detection[1])
        # detected๋œ object๋“ค์˜ score๊ฐ€ 0.4 ์ด์ƒ๋งŒ ์ถ”์ถœ
        if score > score_threshold:
            # detected๋œ object๋“ค์€ image ํฌ๊ธฐ๊ฐ€ (300, 300)์œผ๋กœ scale๋œ ๊ธฐ์ค€์œผ๋กœ ์˜ˆ์ธก๋˜์—ˆ์œผ๋ฏ€๋กœ ๋‹ค์‹œ ์›๋ณธ ์ด๋ฏธ์ง€ ๋น„์œจ๋กœ ๊ณ„์‚ฐ
            left = detection[3] * cols
            top = detection[4] * rows
            right = detection[5] * cols
            bottom = detection[6] * rows
            # labels_to_names ๋”•์…”๋„ˆ๋ฆฌ๋กœ class_id๊ฐ’์„ ํด๋ž˜์Šค๋ช…์œผ๋กœ ๋ณ€๊ฒฝ. opencv์—์„œ๋Š” class_id + 1๋กœ ๋งคํ•‘ํ•ด์•ผํ•จ.
            caption = "{}: {:.4f}".format(labels_to_names[class_id], score)

            #cv2.rectangle()์€ ์ธ์ž๋กœ ๋“ค์–ด์˜จ draw_img์— ์‚ฌ๊ฐํ˜•์„ ๊ทธ๋ฆผ. ์œ„์น˜ ์ธ์ž๋Š” ๋ฐ˜๋“œ์‹œ ์ •์ˆ˜ํ˜•.
            cv2.rectangle(draw_img, (int(left), int(top)), (int(right), int(bottom)), color=green_color, thickness=2)
            cv2.putText(draw_img, caption, (int(left), int(top - 5)), cv2.FONT_HERSHEY_SIMPLEX, 0.7, red_color, 2)
    if is_print:
        print('Detection ์ˆ˜ํ–‰์‹œ๊ฐ„:',round(time.time() - start, 2),"์ดˆ")

    return draw_img

 

  • ์ด ์ฝ”๋“œ๋Š” ์ž…๋ ฅ๋œ ์ด๋ฏธ์ง€๋ฅผ ๋Œ€์ƒ์œผ๋กœ ๊ฐ์ฒด ๊ฒ€์ถœ(Object Detection)์„ ์ˆ˜ํ–‰ํ•˜๊ณ , ๊ฒ€์ถœ๋œ ๊ฐ์ฒด ์ฃผ์œ„์— ๊ฒฝ๊ณ„ ์ƒ์ž(bounding box)์™€ ํด๋ž˜์Šค๋ช…์„ ํ‘œ์‹œํ•œ ์ด๋ฏธ์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜ get_detected_img๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
  • ํ•จ์ˆ˜๋Š” OpenCV ๋”ฅ๋Ÿฌ๋‹ ๋„คํŠธ์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€๋ฅผ (300, 300) ํฌ๊ธฐ๋กœ ๋ฆฌ์‚ฌ์ด์ฆˆํ•œ ํ›„ ๋„คํŠธ์›Œํฌ์— ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.
  • ๊ฐ์ฒด ๊ฒ€์ถœ ๊ฒฐ๊ณผ์—์„œ ๊ฒ€์ถœ ์ ์ˆ˜๊ฐ€ ์ฃผ์–ด์ง„ ์ž„๊ณ„๊ฐ’๋ณด๋‹ค ๋†’์€ ๊ฐ์ฒด๋“ค๋งŒ ์„ ํƒํ•˜์—ฌ, ์›๋ณธ ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋กœ ๋ณ€ํ™˜๋œ bounding box๋ฅผ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.
  • ์ด๋•Œ, ๊ฒฝ๊ณ„ ์ƒ์ž์™€ ํด๋ž˜์Šค๋ช…์„ ์ด๋ฏธ์ง€์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋Š” ์ˆ˜ํ–‰ ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜์—ฌ ํ•„์š” ์‹œ ์ถœ๋ ฅํ•˜๋ฉฐ, ๊ฒฐ๊ณผ ์ด๋ฏธ์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

Example

# image ๋กœ๋“œ 
img = cv2.imread('../../data/image/john_wick01.jpg')

#coco dataset ํด๋ž˜์Šค๋ช… ๋งคํ•‘

# tensorflow inference ๋ชจ๋ธ ๋กœ๋”ฉ
cv_net = cv2.dnn.readNetFromTensorflow('./pretrained/ssd_inception_v2_coco_2017_11_17/frozen_inference_graph.pb', 
                                     './pretrained/ssd_inception_v2_coco_2017_11_17/graph.pbtxt')
# Object Detetion ์ˆ˜ํ–‰ ํ›„ ์‹œ๊ฐํ™” 
draw_img = get_detected_img(cv_net, img, score_threshold=0.4, use_copied_array=True, is_print=True)

img_rgb = cv2.cvtColor(draw_img, cv2.COLOR_BGR2RGB)

plt.figure(figsize=(12, 12))
plt.imshow(img_rgb)

๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค


Video Object Detection ์ˆ˜ํ–‰

์›๋ณธ ์˜์ƒ ๋ณด๊ธฐ

from IPython.display import clear_output, Image, display, Video, HTML
Video('../../data/video/John_Wick_small.mp4') # ์ด๋ถ€๋ถ„์€ ๋””๋ ‰ํ† ๋ฆฌ์— ๋งž๊ฒŒ ์ˆ˜์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

VideoCapture์™€ VideoWriter ์„ค์ •ํ•˜๊ธฐ

  • VideoCapture๋ฅผ ์ด์šฉํ•˜์—ฌ Video๋ฅผ frame๋ณ„๋กœ capture ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  • VideoCapture์˜ ์†์„ฑ์„ ์ด์šฉํ•˜์—ฌ Video Frame์˜ ํฌ๊ธฐ ๋ฐ FPS๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. 
  • VideoWriter๋ฅผ ์œ„ํ•œ ์ธ์ฝ”๋”ฉ ์ฝ”๋ฑ ์„ค์ • ๋ฐ ์˜์ƒ write๋ฅผ ์œ„ํ•œ ์„ค์ •์„ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
์ด Frame ๋ณ„๋กœ iteration ํ•˜๋ฉด์„œ Object Detection ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
๊ฐœ๋ณ„ frame๋ณ„๋กœ ํ•˜๋ฉด? ๋‹จ์ผ ์ด๋ฏธ์ง€ Object Detection๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

Video Detection ์ „์šฉ ํ•จ์ˆ˜ ์ƒ์„ฑ

๋น„๋””์˜ค ํŒŒ์ผ์„ ์ž…๋ ฅ๋ฐ›์•„ ๊ฐ ํ”„๋ ˆ์ž„์— ๋Œ€ํ•ด ๊ฐ์ฒด ๊ฒ€์ถœ(Object Detection)์„ ์ˆ˜ํ–‰ํ•˜๊ณ ,
๊ฒ€์ถœ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜์˜ํ•œ ๋น„๋””์˜ค๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ํ•จ์ˆ˜ do_detected_video๋ฅผ ์ •์˜ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
def do_detected_video(cv_net, input_path, output_path, score_threshold, is_print):
    
    cap = cv2.VideoCapture(input_path)

    codec = cv2.VideoWriter_fourcc(*'XVID')

    vid_size = (round(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),round(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
    vid_fps = cap.get(cv2.CAP_PROP_FPS)

    vid_writer = cv2.VideoWriter(output_path, codec, vid_fps, vid_size) 

    frame_cnt = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
    print('์ด Frame ๊ฐฏ์ˆ˜:', frame_cnt, )

    green_color=(0, 255, 0)
    red_color=(0, 0, 255)
    while True:
        hasFrame, img_frame = cap.read()
        if not hasFrame:
            print('๋” ์ด์ƒ ์ฒ˜๋ฆฌํ•  frame์ด ์—†์Šต๋‹ˆ๋‹ค.')
            break
        
        returned_frame = get_detected_img(cv_net, img_frame, score_threshold=score_threshold, use_copied_array=True, is_print=True)
        vid_writer.write(returned_frame)
    # end of while loop

    vid_writer.release()
    cap.release()

 

do_detected_video(cv_net, '../../data/video/John_Wick_small.mp4', '../../data/output/John_Wick_small_ssd01.avi', 0.4, True)
!gsutil cp ../../data/output/John_Wick_small_ssd01.avi gs://my_bucket_dlcv/data/output/John_Wick_small_ssd01.avi

๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด Detecion์ด ์ž˜๋˜์ง€๋งŒ, ์ž‘์€ Object๋Š” Detection์ด ์•ˆ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

์ฝ”๋“œ ์„ค๋ช…

  • ๋น„๋””์˜ค ํŒŒ์ผ ์—ด๊ธฐ ๋ฐ ์„ค์ •
    • input_path๋กœ ์ง€์ •๋œ ๋น„๋””์˜ค ํŒŒ์ผ์„ ์—ด๊ณ , ์ถœ๋ ฅ ๋น„๋””์˜ค ํŒŒ์ผ์„ output_path๋กœ ์ง€์ •๋œ ๊ฒฝ๋กœ์— ์ €์žฅํ•  ์ค€๋น„๋ฅผ ํ•ฉ๋‹ˆ๋‹ค.
    • ๋น„๋””์˜ค ์ฝ”๋ฑ์„ ์„ค์ •ํ•˜๊ณ , ์ž…๋ ฅ ๋น„๋””์˜ค์˜ ํ”„๋ ˆ์ž„ ํฌ๊ธฐ์™€ ํ”„๋ ˆ์ž„ ์†๋„(FPS)๋ฅผ ๊ฐ€์ ธ์™€์„œ ์ถœ๋ ฅ ๋น„๋””์˜ค ์„ค์ •์— ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    • ์ž…๋ ฅ ๋น„๋””์˜ค์˜ ์ด ํ”„๋ ˆ์ž„ ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
  • ํ”„๋ ˆ์ž„ ์ฒ˜๋ฆฌ ๋ฃจํ”„
    • ๋น„๋””์˜ค์˜ ๊ฐ ํ”„๋ ˆ์ž„์„ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ฝ์–ด ๋“ค์ž…๋‹ˆ๋‹ค.
    • ํ”„๋ ˆ์ž„์ด ๋” ์ด์ƒ ์—†์œผ๋ฉด ๋ฃจํ”„๋ฅผ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.
    • ๊ฐ ํ”„๋ ˆ์ž„์— ๋Œ€ํ•ด get_detected_img ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ฐ์ฒด ๊ฒ€์ถœ์„ ์ˆ˜ํ–‰ํ•˜๊ณ , ๊ฒ€์ถœ๋œ ๊ฒฐ๊ณผ๋ฅผ ํ”„๋ ˆ์ž„์— ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค.
    • ๊ฒ€์ถœ ๊ฒฐ๊ณผ๊ฐ€ ๋ฐ˜์˜๋œ ํ”„๋ ˆ์ž„์„ ์ถœ๋ ฅ ๋น„๋””์˜ค ํŒŒ์ผ์— ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ๋น„๋””์˜ค ํŒŒ์ผ ๋ฆด๋ฆฌ์Šค
    • ๋ชจ๋“  ํ”„๋ ˆ์ž„ ์ฒ˜๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด, ์ถœ๋ ฅ ๋น„๋””์˜ค ํŒŒ์ผ๊ณผ ์ž…๋ ฅ ๋น„๋””์˜ค ํŒŒ์ผ์„ ๋‹ซ๊ณ  ๋ฆฌ์†Œ์Šค๋ฅผ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค.

SSD + MobileNet์œผ๋กœ Object Detection ์ˆ˜ํ–‰

  • ์•„๋ž˜ ๋งํฌ๊ฐ€ Download URL ์ž…๋‹ˆ๋‹ค.
 

Home

Open Source Computer Vision Library. Contribute to opencv/opencv development by creating an account on GitHub.

github.com

  • Dataset ๋‹ค์šด๋กœ๋“œ ๋งํฌ

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

# !mkdir pretrained; cd pretrained
# !wget  http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v2_coco_2018_03_29.tar.gz
# !wget https://raw.githubusercontent.com/opencv/opencv_extra/master/testdata/dnn/ssd_mobilenet_v2_coco_2018_03_29.pbtxt
# cd ssd_mobilenet_v2_coco_2018_03_29; mv ssd_mobilenet_v2_coco_2018_03_29.pbtxt graph.pbtxt

 

cv_net_mobile = cv2.dnn.readNetFromTensorflow('./pretrained/ssd_mobilenet_v2_coco_2018_03_29/frozen_inference_graph.pb', 
                                     './pretrained/ssd_mobilenet_v2_coco_2018_03_29/graph.pbtxt')

์˜์ƒ Detection

do_detected_video(cv_net_mobile, '../../data/video/John_Wick_small.mp4', '../../data/output/John_Wick_small_ssd_mobile01.avi', 0.2, True)
# image ๋กœ๋“œ 
img = cv2.imread('../../data/image/beatles01.jpg')

#coco dataset ํด๋ž˜์Šค๋ช… ๋งคํ•‘

cv_net_mobile = cv2.dnn.readNetFromTensorflow('./pretrained/ssd_mobilenet_v2_coco_2018_03_29/frozen_inference_graph.pb', 
                                     './pretrained/ssd_mobilenet_v2_coco_2018_03_29/graph.pbtxt')
# Object Detetion ์ˆ˜ํ–‰ ํ›„ ์‹œ๊ฐํ™” 
draw_img = get_detected_img(cv_net_mobile, img, score_threshold=0.4, use_copied_array=True, is_print=True)

img_rgb = cv2.cvtColor(draw_img, cv2.COLOR_BGR2RGB)

plt.figure(figsize=(12, 12))
plt.imshow(img_rgb)

๊ฒฐ๊ณผ ์˜์ƒ์ค‘ ํ•œ๋ถ€๋ถ„์„ ์บก์ณํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ์บก์ณ ์‚ฌ์ง„์„ ๋ณด๋ฉด, ์ˆ˜ํ–‰์„ฑ๋Šฅ์ด Inception ๋ณด๋‹ค ์ข‹๋‹ค๋Š” ํŠน์ง•์ด ์žˆ์Šต๋‹ˆ๋‹ค.