[PYTHON] Vergleich der Farberkennungsmethoden in OpenCV inRange, numpy, cupy

Einführung

Wenn Sie mit OpenCV spielen, möchten Sie möglicherweise Objekte anhand der Farbe erkennen. Oft bei der Farberkennung mit OpenCV

--Konvertieren Sie mit cv2.cvtColor vom RGB-Farbraum in den HSV-Farbraum

Die Methode wird vorgestellt. Andererseits ist es auf die gleiche Weise möglich, Numpy zu verwenden, um die Bedingungen für jedes Pixel zu binarisieren. Hier haben wir die Geschwindigkeiten auf Xavier NX verglichen, einschließlich der Vor- und Nachteile dieser beiden Methoden und der Implementierung in Cupy.

Was ich getan habe

Nach der Umstellung auf HSV haben wir die folgenden 4 Bedingungen einschließlich der Binärisierungsmethode mit inRange verglichen.

  1. So erkennen Sie grüne Kugeln mit inRange
  2. Binärisierung durch Angabe von Bedingungen mit numpy
  3. So erkennen Sie unter Bedingungen, die mit inRange with numpy nicht möglich sind Beim Beschleunigen von 4 und 3 mit CUPY Ich habe die resultierenden Bilder mit 1 und 23 und die Geschwindigkeiten mit 1234 verglichen. Die Quellen, die ich mit Python3 ausprobiert habe, sind in der zweiten Hälfte auf vier Arten angehängt.

Quellbild

color.jpg

Probleme mit inRange

Normalerweise möchten wir bei der Farberkennung mit inRange eine Farberkennung basierend auf dem Farbton durchführen. Daher sollten wir meiner Meinung nach zuerst vom RGB-Farbraum in den HSV-Farbraum konvertieren. in diesem Fall

--InRange hat grundsätzlich einen geringen Freiheitsgrad, da nur ein Schwellenwert mit einer Konstanten parallel zu jeder Achse im Farbraum angenommen werden kann.

Infolgedessen bei Verwendung von inRange hsv_h.jpg Wie Sie sehen können, ist es sehr schwierig, das schwarze Kabel unten im Bild und die weiße Wand oben im Bild von der grünen Kugel zu unterscheiden.

Implementierung in Numpy

Filter ähnlich wie inRange in Numpy

numpy1.py


        hsv = cv2.cvtColor( frame , cv2.COLOR_BGR2HSV )

        h = frame[:,:,0]
        s = frame[:,:,1]
        v = frame[:,:,2]

        mask_g = np.zeros(h.shape, dtype=np.uint8)
        mask_g[ (h>20) & (h <100) & (s>200) & (s < 255) & (v>50) & (v<150 ) ] = 255

Ich denke, es kann als implementiert werden. in diesem Fall

        mask_g[ (h>20) & (h <100) & (s>200) & (s < 255) & (v>50) & (v<150 ) ] = 255

Teil ist

        mask_g[ ( g/r> 2.0) & (g/b>2.0) ] = 255

Nicht nur der Schwellenwert als Konstante parallel zur Achse des Farbraums, sondern auch der Schwellenwert kann basierend auf dem Verhältnis jedes Elements festgelegt werden, und es kann ein linearer oder komplizierterer Schwellenwert festgelegt werden. Im obigen Beispiel ist das Bild nach der Erkennung wie folgt, und ich denke, dass das erwartete Ergebnis leicht erhalten werden kann. Im obigen Beispiel wird erkannt, wenn das grüne Element doppelt so hell wie rot und blau ist und die schwarzen und weißen Teile wie unten gezeigt leicht ausgeschlossen werden können. rgb_g.jpg

Geschwindigkeitsvergleich

Auf der anderen Seite in Bezug auf die Geschwindigkeit

  1. inRange
  2. numpy (Filterbedingung ähnlich wie inRange)
  3. numpy( R/B > 2 & R/G>2 )
  4. cupy( R/B >2 & R/G > 2 ) Es wurde wie folgt unter den vier Bedingungen von.
1.inRange 2.numpy(Wie inRange) 3.numpy(RGB-Korrelation) 4.CUPY
0.009[s] 0.047[s] 0.055[s] 0.021[s]

Ich dachte nicht, dass inRange der schnellste ist. .. .. ..

Quellcode habe ich versucht

1, in Reichweite erkennt grüne Kugel

inrange.py


import cv2
import numpy as np
import time

src = 'v4l2src device= /dev/video0 ! image/jpeg,width=1920,height=1080 !jpegdec !videoconvert ! appsink'

cap=cv2.VideoCapture(src)


W = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
H = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = cap.get(cv2.CAP_PROP_FPS)
while(cap.isOpened()):
    sum=0
    for i in range( 0,100 ):
        ret, frame = cap.read()
        start=time.time()
        r = frame[:,:,0]
        g = frame[:,:,1]
        b = frame[:,:,2]

        mask_g = np.zeros(r.shape, dtype=np.uint8)
        mask_g[ ( g/r> 2.0) & (g/b>2.0) ] = 255
        end = time.time()
        sum+= (end- start)
        cv2.imshow('ReadM',mask_g )
        cv2.waitKey(1)
        if i % 10 == 0 :
            print( i )
    print( sum/100)
cap.release()

2. Binärisierung durch Angabe von Bedingungen mit numpy

numpy1.py


import cv2
import numpy as np
import time

src = 'v4l2src device= /dev/video0 ! image/jpeg,width=1920,height=1080 !jpegdec !videoconvert ! appsink'

cap=cv2.VideoCapture(src)


W = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
H = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = cap.get(cv2.CAP_PROP_FPS)
while(cap.isOpened()):
    sum=0
    for i in range( 0,100 ):
        ret, frame = cap.read()
        start=time.time()
        hsv = cv2.cvtColor( frame , cv2.COLOR_BGR2HSV )

        h = frame[:,:,0]
        s = frame[:,:,1]
        v = frame[:,:,2]

        mask_g = np.zeros(h.shape, dtype=np.uint8)
        mask_g[ (h>20) & (h <100) & (s>200) & (s < 255) & (v>50) & (v<150 ) ] = 255
        end = time.time()
        sum+= (end- start)
        cv2.imshow('ReadM',mask_g )
        cv2.waitKey(1)
        if i % 10 == 0 :
            print( i )
    print( sum/100)
cap.release()

3. So erkennen Sie unter Bedingungen, die mit inRange with numpy nicht möglich sind

numpy2.py


import cv2
import numpy as np
import time

src = 'v4l2src device= /dev/video0 ! image/jpeg,width=1920,height=1080 !jpegdec !videoconvert ! appsink'

cap=cv2.VideoCapture(src)


W = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
H = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = cap.get(cv2.CAP_PROP_FPS)
while(cap.isOpened()):
    sum=0
    for i in range( 0,100 ):
        ret, frame = cap.read()
        start=time.time()
        r = frame[:,:,0]
        g = frame[:,:,1]
        b = frame[:,:,2]

        mask_g = np.zeros(r.shape, dtype=np.uint8)
        mask_g[ ( g/r> 2.0) & (g/b>2.0) ] = 255
        end = time.time()
        sum+= (end- start)
        cv2.imshow('ReadM',mask_g )
        cv2.waitKey(1)
        if i % 10 == 0 :
            print( i )
    print( sum/100)
cap.release()

Beim Beschleunigen von 4 und 3 mit CUPY

cupy.py


import cv2
import cupy as cp
import time

src = 'v4l2src device= /dev/video0 ! image/jpeg,width=1920,height=1080 !jpegdec !videoconvert ! appsink'

cap=cv2.VideoCapture(src)


W = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
H = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = cap.get(cv2.CAP_PROP_FPS)
while(cap.isOpened()):
    sum=0
    for i in range( 0,100 ):
        ret, frame = cap.read()
        start=time.time()
        frame_cupy = cp.asarray( frame )
        r = frame_cupy[:,:,0]
        g = frame_cupy[:,:,1]
        b = frame_cupy[:,:,2]

        mask_g = cp.zeros(r.shape, dtype=cp.uint8)
        mask_g[ ( g/r> 2.0) & (g/b>2.0) ] = 255
        mask_gn = cp.asnumpy( mask_g )
        end = time.time()
        sum+= (end- start)
        cv2.imshow('ReadM',mask_gn )
        cv2.waitKey(1)
        if i % 10 == 0 :
            print( i )
    print( sum/100)
cap.release()

Recommended Posts

Vergleich der Farberkennungsmethoden in OpenCV inRange, numpy, cupy
Behandlung des HSV-Farbraums unten und oben in OpenCV
Setzen Sie Python, Numpy, OpenCV3 in Ubuntu14
Schreiben Sie NumPy stückweise für CuPy um
Berechnung der mittleren IoU bei der Objekterkennung
Ausführungsbeispiel für die Blob-Erkennung mit OpenCV
Zusammenfassung der häufig verwendeten Methoden bei Pandas
Automatische Erkennung des Build-Verzeichnisses in waf
Vergleich von Lösungen bei Gewichtsanpassungsproblemen
Zusammenfassung der integrierten Methoden usw. der Python-Liste