Die Maske R-CNN ist ein Modell, das die Objekterkennung und Instanzsegmentierung durchführt. Da die Segmentierung pixelweise erfolgen kann, kann nur eine bestimmte Person maskiert werden. Die Echtzeitverarbeitung ist jedoch schwierig, da die Verarbeitung eines Frames einige Zeit in Anspruch nimmt. Daher habe ich versucht, den Rahmen zwischen der Objekterkennung zu interpolieren, indem ich die Änderung der Bewegung des Maskenbildes mit dem optischen Fluss abgeschätzt habe.
Mask R-CNN verwendet die Materieport-Version der Implementierung. Für den Code habe ich auf Artikel des AI-Koordinators verwiesen. Dazu haben wir die Interpolationsverarbeitung hinzugefügt. Wenn beispielsweise die Objekterkennung in Intervallen von 10 Bildern für ein 30-fps-Eingangsvideo durchgeführt wird, sind die 9 Bilder zwischen der Objekterkennung und der Objekterkennung die Bewegungsvektoren für jedes Pixel unter Verwendung des in Opencv implementierten "dichten optischen Flusses". Fragen Sie und aktualisieren Sie das Maskenbild.
Es ist fast so.
Anaconda3 2019.10 Python 3.7.6 opencv 3.4.9 tensorflow-gpu 2.1.0
Sie können den Vorgang überprüfen, indem Sie die folgenden Werte im Code ändern.
file = "input.mp4"
Geben Sie die Videodatei an, um das Objekt zu erkennen.
```width=640, height=320```
Ändert die Größe des Bilds auf die hier angegebene Größe, wenn ein Objekt erkannt wird.
Je kleiner die Größe, desto kürzer die Verarbeitungszeit.
```detect_fps = 1```
Gibt das Intervall (fps) für die Objekterkennung an.
```debug_restrict_class = 1```
Sie können die Klassenidentifikation bei der Objekterkennung einschränken.
Wenn dieser Wert auf 1 gesetzt ist, werden andere als die in der Liste class_filter angegebenen Erkennungen ignoriert.
Wenn Sie dies einschränken möchten, wird das Maskenbild in der für jede Klasse angegebenen Farbe gezeichnet.
#### **`debug_score_threshould = 0.900`**
```900
Sie können den Schwellenwert für den Identifikationswert bei der Objekterkennung angeben.
Erkennungsergebnisse unterhalb des Schwellenwerts werden ignoriert.
```debug_max_instances = 100```
Sie können die maximale Anzahl erkannter Objekte für die Objekterkennung angeben.
```debug_display_rect = 0```
Gibt an, ob ein Rechteck um das erkannte Objekt gezeichnet werden soll.
```debug_display_text = 0```
Gibt an, ob der Klassenname und der Bewertungswert oben im Rechteck des Erkennungsobjekts gezeichnet werden sollen.
```debug_display_mask = 1```
Gibt an, ob für jedes Pixel des erkannten Objekts ein Maskenbild gezeichnet werden soll.
```debug_update_masks = 1```
Gibt an, ob das Maskenbild durch optischen Fluss aktualisiert werden soll.
```debug_update_masks_adding = 0```
Gibt an, ob das Maskenbild des nächsten Frames über das Maskenbild des vorherigen Frames gezeichnet werden soll, wenn das Maskenbild durch den optischen Fluss aktualisiert wird.
# Überprüfung
――Der optische Fluss kann maximal 2 bis 3 Frames interpolieren.
- Wenn sich ein Objekt Ihnen nähert, erhöht sich die Anzahl der Pixel, aus denen das Objekt besteht. Selbst wenn Sie das Maskenbild mit optischem Fluss verschieben, wird eine Lücke erstellt. (Es ist natürlich ...)
- Wenn sich die Form bei Bewegung häufig ändert, z. B. bei einer Person mit Gliedmaßen, kann der optische Fluss nicht aufholen.
# Ergebnis
Zum Beispiel kann es ein wenig nützlich sein, um etwas mit einer festen Form wie ein Auto mit optischem Fluss zu interpolieren, aber es war nicht praktisch. Tohoho.
# Code
#### **`mask_rcnn_with_tracking.py`**
```python
"""
Based on https://ai-coordinator.jp/mask-r-cnn
"""
import os
import sys
import random
import math
import numpy as np
#import skimage.io
#import matplotlib
#import matplotlib.pyplot as plt
sys.path.append(os.path.abspath("matterport/Mask_RCNN"))
from samples.coco import coco
from mrcnn import utils
import mrcnn.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']
class_filter = ['person',
'bicycle',
'car',
'motorcycle',
'bus',
'truck',
'cat',
'backpack']
class_colors = [[ 0/255, 165/255, 255/255], # orange
[ 0/255, 255/255, 0/255], # lime
[255/255, 255/255, 0/255], # cyan
[130/255, 0/255, 75/255], # indigo
[ 0/255, 128/255, 128/255], # olive
[ 0/255, 128/255, 0/255], # green
[140/255, 230/255, 240/255], # khaki
[255/255, 0/255, 0/255]] # blue
file = "input.mp4"
cap = cv2.VideoCapture(file)
width = 640 # 640, 320
height = 360 # 360, 180
input_fps = cap.get(cv2.CAP_PROP_FPS)
detect_fps = 1
debug_restrict_class = 1
debug_score_threshould = 0.900
debug_max_instances = 100
debug_display_rect = 0
debug_display_text = 0
debug_display_mask = 1
debug_update_masks = 1
debug_update_masks_adding = 0
input_fps = round(input_fps)
if input_fps < 1: input_fps = 1
if detect_fps > input_fps: detect_fps = input_fps
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()
total_instance = 0
for i in range(N):
label = class_names[class_ids[i]]
score = scores[i] if scores is not None else None
total_instance = total_instance + 1
if check_ignore_instance(label, score, total_instance):
break
# Color
if debug_restrict_class != 0:
color = get_class_color(label)
else:
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)
if debug_display_rect != 0:
cv2.rectangle(masked_image, (x1, y1), (x2, y2), camera_color , 1)
# Label
if debug_display_text != 0:
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
if debug_display_mask != 0:
mask = masks[:, :, i]
masked_image = apply_mask(masked_image, mask, color)
return masked_image.astype(np.uint8)
def get_class_color(class_name):
return class_colors[class_filter.index(class_name)]
def check_ignore_instance(label, score, total_instance):
if (debug_restrict_class != 0) and (not label in class_filter):
return True
if score < debug_score_threshould:
return True
if total_instance > debug_max_instances:
return True
return False
def update_new_mask(new_mask, mask, width, height, flow):
index_list = np.where(mask == 1)
N = len(index_list[0])
for i in range(N):
x = index_list[1][i]
y = index_list[0][i]
index_list[1][i] = max(min(x + int(round(flow[y, x, 0])), (width - 1)), 0)
index_list[0][i] = max(min(y + int(round(flow[y, x, 1])), (height - 1)), 0)
new_mask[index_list] = 1
def update_masks_by_flow(masks, class_ids, class_names, scores, flow):
N = masks.shape[-1]
if debug_update_masks_adding == 0:
new_masks = np.zeros_like(masks)
else:
new_masks = np.copy(masks)
total_instance = 0
for i in range(N):
label = class_names[class_ids[i]]
score = scores[i] if scores is not None else None
total_instance = total_instance + 1
if check_ignore_instance(label, score, total_instance):
break
update_new_mask(new_masks[:, :, i], masks[:, :, i], width, height, flow)
return new_masks
def main():
frame_no = 0
image_base = []
r = []
while(True):
#Holen Sie sich Frames aus dem Videostream
ret, frame = cap.read()
if ret == False:
break
#Ändern Sie die Größe des Kamerabilds
image_cv2 = cv2.resize(frame,(width,height))
frame_no = frame_no + 1
if (input_fps == detect_fps) or frame_no % round(input_fps / detect_fps) == 1:
image_base = cv2.cvtColor(image_cv2, cv2.COLOR_BGR2GRAY)
results = model.detect([image_cv2])
r = results[0]
else:
if debug_update_masks != 0:
image_next = cv2.cvtColor(image_cv2, cv2.COLOR_BGR2GRAY)
flow = cv2.calcOpticalFlowFarneback(image_base, image_next, None, 0.5, 3, 15, 3, 5, 1.1, 0)
image_base = image_next
r['masks'] = update_masks_by_flow(r['masks'], r['class_ids'],
class_names, r['scores'], flow)
camera = display_instances(image_cv2, r['rois'], r['masks'], r['class_ids'],
class_names, r['scores'])
cv2.imshow("camera window", camera)
#Drücken Sie esc, um den Vorgang abzuschließen.
if cv2.waitKey(1) == 27:
break
#Ende
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
AttributeError: module 'tensorflow' has no attribute 'log'
das ist alles
Recommended Posts