Le masque R-CNN est un modèle qui effectue la détection d'objets et la segmentation d'instances. Comme la segmentation peut être effectuée pixel par pixel, il est possible de ne masquer qu'une personne spécifique. Cependant, le traitement en temps réel est difficile car il faut du temps pour traiter une image. Par conséquent, j'ai essayé d'interpoler le cadre entre la détection d'objet en estimant le changement du mouvement de l'image du masque avec un flux optique.
Le masque R-CNN utilise la version matièreport de l'implémentation. Pour le code, j'ai fait référence à l'article de AI Coordinator. Pour cela, nous avons ajouté un traitement d'interpolation. Par exemple, lorsque la détection d'objet est effectuée à des intervalles de 10 images pour une vidéo d'entrée à 30 ips, les 9 images entre la détection d'objet et la détection d'objet sont les vecteurs de mouvement pour chaque pixel par le «flux optique dense» implémenté dans Opencv. Demandez et mettez à jour l'image du masque.
C'est presque comme ça.
Anaconda3 2019.10 Python 3.7.6 opencv 3.4.9 tensorflow-gpu 2.1.0
Vous pouvez vérifier l'opération en modifiant les valeurs suivantes dans le code.
file = "input.mp4"
Spécifiez le fichier vidéo pour détecter l'objet.
```width=640, height=320```
Redimensionne l'image à la taille spécifiée ici lors de la détection d'un objet.
Plus la taille est petite, plus le temps de traitement est court.
```detect_fps = 1```
Spécifie l'intervalle (fps) pour la détection d'objet.
```debug_restrict_class = 1```
Vous pouvez limiter l'identification de classe dans la détection d'objets.
Si cette valeur est définie sur 1, les détections autres que celles spécifiées dans la liste class_filter seront ignorées.
De plus, si vous souhaitez le limiter, l'image du masque sera dessinée dans la couleur spécifiée pour chaque classe.
#### **`debug_score_threshould = 0.900`**
```900
Vous pouvez spécifier le seuil de la valeur du score d'identification dans la détection d'objet.
Les résultats de détection inférieurs au seuil sont ignorés.
```debug_max_instances = 100```
Vous pouvez spécifier le nombre maximal d'objets détectés pour la détection d'objets.
```debug_display_rect = 0```
Indique s'il faut dessiner un rectangle autour de l'objet détecté.
```debug_display_text = 0```
Indique s'il faut dessiner le nom de la classe et la valeur du score en haut du rectangle de l'objet de détection.
```debug_display_mask = 1```
S'il faut dessiner une image de masque pour chaque pixel de l'objet détecté.
```debug_update_masks = 1```
S'il faut mettre à jour l'image du masque par flux optique.
```debug_update_masks_adding = 0```
S'il faut dessiner l'image de masque de l'image suivante sur l'image de masque de l'image précédente lors de la mise à jour de l'image de masque par le flux optique.
# Vérification
――Le flux optique peut interpoler jusqu'à 2 à 3 images au maximum.
--Lorsque l'objet s'approche de vous, le nombre de pixels qui composent l'objet augmente, donc même si vous déplacez l'image de masque avec le flux optique, un espace sera créé. (C'est naturel ...)
- Si la forme change fréquemment avec le mouvement, comme une personne avec des membres, le flux optique ne peut pas rattraper.
# résultat
Par exemple, cela peut être un peu utile pour interpoler quelque chose avec une forme fixe comme une voiture avec un flux optique, mais ce n'était pas pratique. 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):
#Obtenir des images du flux vidéo
ret, frame = cap.read()
if ret == False:
break
#Redimensionner l'image de la caméra
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)
#Appuyez sur Echap pour terminer.
if cv2.waitKey(1) == 27:
break
#Fin
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
AttributeError: module 'tensorflow' has no attribute 'log'
c'est tout
Recommended Posts