[PYTHON] Ich habe versucht, Mask R-CNN mit Optical Flow zu interpolieren

Überblick

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.

Methode

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.

Umgebung

Es ist fast so.

Anaconda3 2019.10 Python 3.7.6 opencv 3.4.9 tensorflow-gpu 2.1.0

Validierungsparameter

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

Zusatzinformationen

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

das ist alles

Recommended Posts

Ich habe versucht, Mask R-CNN mit Optical Flow zu interpolieren
Ich habe versucht, Faster R-CNN mit Pytorch auszuführen
Ich habe versucht, Autoencoder mit TensorFlow zu implementieren
Ich habe versucht, AutoEncoder mit TensorFlow zu visualisieren
Ich habe versucht, CVAE mit PyTorch zu implementieren
Ich habe versucht, TSP mit QAOA zu lösen
Ich habe versucht, nächstes Jahr mit AI vorherzusagen
Ich habe versucht, das Lesen von Dataset mit PyTorch zu implementieren
Ich habe versucht, lightGBM, xg Boost mit Boruta zu verwenden
Ich habe versucht, mit TF Learn die logische Operation zu lernen
Ich habe versucht, GAN (mnist) mit Keras zu bewegen
Ich habe versucht, mit OpenCV Bewegungen schnell zu erkennen
Ich habe versucht, CloudWatch-Daten mit Python abzurufen
Ich habe versucht, LLVM IR mit Python auszugeben
Ich habe versucht, die Herstellung von Sushi mit Python zu automatisieren
Ich habe versucht, das Überleben der Titanic mit PyCaret vorherzusagen
Ich habe versucht, Linux mit Discord Bot zu betreiben
Ich habe versucht, DP mit Fibonacci-Sequenz zu studieren
Ich habe versucht, Tundele mit Naive Bays zu beurteilen
Ich habe versucht zu debuggen.
Ich habe versucht, die Sündenfunktion mit Chainer zu trainieren
Ich habe versucht, maschinelles Lernen (Objekterkennung) mit TouchDesigner zu verschieben
Ich habe versucht, Funktionen mit SIFT von OpenCV zu extrahieren
Ich habe versucht, mit VOICEROID2 2 automatisch zu lesen und zu speichern
Ich habe versucht, DCGAN mit PyTorch zu implementieren und zu lernen
Ich habe versucht, Mine Sweeper auf dem Terminal mit Python zu implementieren
Ich habe versucht, mit Blenders Python script_Part 01 zu beginnen
Ich habe versucht, Soma Cube mit Python zu lösen
Ich habe versucht, mit VOICEROID2 automatisch zu lesen und zu speichern
Ich habe versucht, mit Blenders Python script_Part 02 zu beginnen
Ich habe versucht, ObjectId (Primärschlüssel) mit Pymongo zu generieren
Ich habe versucht, künstliches Perzeptron mit Python zu implementieren
Ich habe versucht, eine ML-Pipeline mit Cloud Composer zu erstellen
Ich habe versucht, unsere Dunkelheit mit der Chatwork-API aufzudecken
[Einführung in Pytorch] Ich habe versucht, Cifar10 mit VGG16 ♬ zu kategorisieren
Ich habe versucht, das Problem mit Python Vol.1 zu lösen
Ich habe versucht, eine OCR-App mit PySimpleGUI zu erstellen
Ich habe versucht, SSD jetzt mit PyTorch zu implementieren (Dataset)
Ich habe versucht, die Bayes'sche Optimierung zu durchlaufen. (Mit Beispielen)
Ich habe versucht, die alternative Klasse mit Tensorflow zu finden
[Einführung in AWS] Ich habe versucht, mit der Sprach-Text-Konvertierung zu spielen ♪
Ich habe versucht, AOJs Integer-Theorie mit Python zu lösen
Ich habe untersucht, wie der Arbeitsablauf mit Excel x Python optimiert werden kann
Ich habe untersucht, wie der Arbeitsablauf mit Excel x Python ④ optimiert werden kann
Ich habe versucht herauszufinden, wie der Arbeitsablauf mit Excel x Python optimiert werden kann
Ich habe untersucht, wie der Arbeitsablauf mit Excel x Python optimiert werden kann
Ich habe untersucht, wie der Arbeitsablauf mit Excel x Python optimiert werden kann
Ich habe fp-Wachstum mit Python versucht
Ich habe versucht, mit Python zu kratzen
Ich habe versucht, PredNet zu lernen
Ich habe versucht, mit Elasticsearch Ranking zu lernen!
Ich habe versucht, SVM zu organisieren.
Ich habe versucht, mit PyCaret zu clustern
Ich habe versucht, PCANet zu implementieren