2018年11月25日日曜日

Mask R-CNNを簡単にカメラ映像から試す方法

GitHubからMask R-CNNのソースコードをダウンロード

まずはMask R-CNNを紹介しているGitHubからソースコードをダウンロードしましょう。

ダウンロードしたフォルダ内に、「demo.ipynb」があるので、何も考えずにjupyter notebookで実行してみましょう。

映像からのMask R-CNN

続いてカメラ映像からのMask R-CNNを試してみましょう。

PC内蔵カメラからでも動画からでも実行できます。

ソースコードを適当に作成してみました。

とりあえず動けばなんでも良い感じで作成しています。

camera Mask R-CNN
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import os
import sys
import random
import math
import numpy as np
import skimage.io
import matplotlib
import matplotlib.pyplot as plt
 
import coco
import utils
import model as modellib
 
import cv2
import colorsys
 
ROOT_DIR = os.getcwd()
MODEL_DIR = os.path.join(ROOT_DIR, "logs")
 
COCO_MODEL_PATH = os.path.join(ROOT_DIR, "mask_rcnn_coco.h5")
if not os.path.exists(COCO_MODEL_PATH):
    utils.download_trained_weights(COCO_MODEL_PATH)
 
class InferenceConfig(coco.CocoConfig):
    GPU_COUNT = 1
    IMAGES_PER_GPU = 1
 
config = InferenceConfig()
 
model = modellib.MaskRCNN(mode="inference", model_dir=MODEL_DIR, config=config)
model.load_weights(COCO_MODEL_PATH, by_name=True)
 
class_names = ['BG', 'person', 'bicycle', 'car', 'motorcycle', 'airplane',
               'bus', 'train', 'truck', 'boat', 'traffic light',
               'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird',
               'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear',
               'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie',
               'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball',
               'kite', 'baseball bat', 'baseball glove', 'skateboard',
               'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup',
               'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
               'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza',
               'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed',
               'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote',
               'keyboard', 'cell phone', 'microwave', 'oven', 'toaster',
               'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors',
               'teddy bear', 'hair drier', 'toothbrush']
#cap = cv2.VideoCapture("1.mp4")
cap = cv2.VideoCapture(0)
 
height = 720
width  = 1280
 
def random_colors(N, bright=True):
    brightness = 1.0 if bright else 0.7
    hsv = [(i / N, 1, brightness) for i in range(N)]
    colors = list(map(lambda c: colorsys.hsv_to_rgb(*c), hsv))
    random.shuffle(colors)
    return colors
 
def apply_mask(image, mask, color, alpha=0.5):
    for c in range(3):
        image[:, :, c] = np.where(mask == 1,
                                  image[:, :, c] *
                                  (1 - alpha) + alpha * color[c] * 255,
                                  image[:, :, c])
    return image
 
def display_instances(image, boxes, masks, class_ids, class_names,
                      scores=None, title="",
                      figsize=(16, 16), ax=None):
    N = boxes.shape[0]
    if not N:
        print("\n*** No instances to display *** \n")
    else:
        assert boxes.shape[0] == masks.shape[-1] == class_ids.shape[0]
 
    colors = random_colors(N)
 
    masked_image = image.copy()
    for i in range(N):
        color = colors[i]
 
        # Bounding box
        if not np.any(boxes[i]):
            continue
        y1, x1, y2, x2 = boxes[i]
        camera_color = (color[0] * 255, color[1] * 255, color[2] * 255)
        cv2.rectangle(masked_image, (x1, y1), (x2, y2), camera_color , 1)
 
        # Label
        class_id = class_ids[i]
        score = scores[i] if scores is not None else None
        label = class_names[class_id]
        x = random.randint(x1, (x1 + x2) // 2)
        caption = "{} {:.3f}".format(label, score) if score else label
        camera_font = cv2.FONT_HERSHEY_PLAIN
        cv2.putText(masked_image,caption,(x1, y1),camera_font, 1, camera_color)
 
        # Mask
        mask = masks[:, :, i]
        masked_image = apply_mask(masked_image, mask, color)
 
    return masked_image.astype(np.uint8)
 
def main():
    while(True):
        # 動画ストリームからフレームを取得
        ret, frame = cap.read()
        
        # カメラ画像をリサイズ
        image_cv2 = cv2.resize(frame,(width,height))
        
        results = model.detect([image_cv2])
 
        r = results[0]
        camera = display_instances(image_cv2, r['rois'], r['masks'], r['class_ids'],
                            class_names, r['scores'])
 
        cv2.imshow("camera window", camera)
        # escを押したら終了。
        if cv2.waitKey(1) == 27:
            break
    
    #終了
    cap.release()
    cv2.destroyAllWindows()
if __name__ == '__main__':
    main()

cap = cv2.VideoCapture(0)を指定していますので、PC内臓のwebカメラが起動するはずです。

動画にしたい場合は、cap = cv2.VideoCapture('move.mp4')といった指定をすれば、動画でもMask R-CNNを試せます。

興味がある方はぜひ挑戦してみてください。

0 件のコメント:

コメントを投稿