[PYTHON] J'ai essayé d'interpoler le masque R-CNN avec un flux optique

Aperçu

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.

Méthode

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.

environnement

C'est presque comme ça.

Anaconda3 2019.10 Python 3.7.6 opencv 3.4.9 tensorflow-gpu 2.1.0

Paramètres de validation

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()

Information supplémentaire

AttributeError: module 'tensorflow' has no attribute 'log'

c'est tout

Recommended Posts

J'ai essayé d'interpoler le masque R-CNN avec un flux optique
J'ai essayé de déplacer Faster R-CNN rapidement avec pytorch
J'ai essayé d'implémenter Autoencoder avec TensorFlow
J'ai essayé de visualiser AutoEncoder avec TensorFlow
J'ai essayé d'implémenter CVAE avec PyTorch
J'ai essayé de résoudre TSP avec QAOA
J'ai essayé de prédire l'année prochaine avec l'IA
J'ai essayé d'implémenter la lecture de Dataset avec PyTorch
J'ai essayé d'utiliser lightGBM, xg boost avec Boruta
J'ai essayé d'apprendre le fonctionnement logique avec TF Learn
J'ai essayé de déplacer GAN (mnist) avec keras
J'ai essayé de détecter rapidement un mouvement avec OpenCV
J'ai essayé d'obtenir des données CloudWatch avec Python
J'ai essayé de sortir LLVM IR avec Python
J'ai essayé d'automatiser la fabrication des sushis avec python
J'ai essayé de prédire la survie du Titanic avec PyCaret
J'ai essayé d'utiliser Linux avec Discord Bot
J'ai essayé d'étudier DP avec séquence de Fibonacci
J'ai essayé de juger Tundele avec Naive Bays
J'ai essayé de déboguer.
J'ai essayé d'entraîner la fonction péché avec chainer
J'ai essayé de déplacer l'apprentissage automatique (détection d'objet) avec TouchDesigner
J'ai essayé d'extraire des fonctionnalités avec SIFT d'OpenCV
J'ai essayé de lire et d'enregistrer automatiquement avec VOICEROID2 2
J'ai essayé d'implémenter et d'apprendre DCGAN avec PyTorch
J'ai essayé d'implémenter Mine Sweeper sur un terminal avec python
J'ai essayé de démarrer avec le script python de blender_Part 01
J'ai essayé de résoudre Soma Cube avec python
J'ai essayé de lire et d'enregistrer automatiquement avec VOICEROID2
J'ai essayé de démarrer avec le script python de blender_Partie 02
J'ai essayé de générer ObjectId (clé primaire) avec pymongo
J'ai essayé d'implémenter le perceptron artificiel avec python
J'ai essayé de créer un pipeline ML avec Cloud Composer
J'ai essayé de découvrir notre obscurité avec l'API Chatwork
[Introduction à Pytorch] J'ai essayé de catégoriser Cifar10 avec VGG16 ♬
J'ai essayé de résoudre le problème avec Python Vol.1
J'ai essayé de créer une application OCR avec PySimpleGUI
J'ai essayé d'implémenter SSD avec PyTorch maintenant (Dataset)
J'ai essayé de passer par l'optimisation bayésienne. (Avec des exemples)
J'ai essayé de trouver la classe alternative avec tensorflow
[Introduction à AWS] J'ai essayé de jouer avec la conversion voix-texte ♪
J'ai essayé de résoudre la théorie des nombres entiers d'AOJ avec Python
J'ai étudié comment rationaliser le flux de travail avec Excel x Python ②
J'ai étudié comment rationaliser le flux de travail avec Excel x Python ④
J'ai essayé de savoir comment rationaliser le flux de travail avec Excel x Python ⑤
J'ai étudié comment rationaliser le flux de travail avec Excel x Python ①
J'ai étudié comment rationaliser le flux de travail avec Excel x Python ③
J'ai essayé fp-growth avec python
J'ai essayé de gratter avec Python
J'ai essayé d'apprendre PredNet
J'ai essayé Learning-to-Rank avec Elasticsearch!
J'ai essayé d'organiser SVM.
J'ai essayé le clustering avec PyCaret
J'ai essayé d'implémenter PCANet