Comparaison des méthodes de détection des couleurs dans OpenCV inRange, numpy, cupy

introduction

Lorsque vous jouez avec OpenCV, vous souhaiterez peut-être détecter des objets en fonction de la couleur. Souvent lors de la détection des couleurs avec OpenCV

--Convertir de l'espace colorimétrique RVB à l'espace colorimétrique HSV à l'aide de cv2.cvtColor --Spécifiez la plage d'espace colorimétrique HSV avec cv2.inRange et binarize

La méthode est introduite. D'autre part, de la même manière, il est possible d'utiliser Numpy pour binariser les conditions de chaque pixel. Ici, nous avons comparé les vitesses sur Xavier NX, y compris les avantages et les inconvénients de ces deux méthodes et la mise en œuvre dans cupy.

Ce que j'ai fait

Après la conversion en HSV, nous avons comparé les 4 conditions suivantes, y compris la méthode de binarisation avec inRange.

  1. Comment détecter les boules vertes avec inRange
  2. Comment binariser en spécifiant des conditions avec numpy
  3. Comment détecter dans des conditions impossibles à réaliser avec inRange avec numpy Lors de l'accélération de 4 et 3 avec CUPY J'ai comparé les images résultantes avec 1 et 23 et les vitesses avec 1234, respectivement. Les sources que j'ai essayées avec python3 sont attachées de 4 manières dans la seconde moitié.

Image source

color.jpg

Problèmes avec inRange

Normalement, lorsque la détection de couleur est effectuée à l'aide d'inRange, la détection de couleur est effectuée sur une base de teinte, donc je pense que l'espace colorimétrique RVB doit d'abord être converti en espace colorimétrique HSV. dans ce cas

--InRange a fondamentalement un faible degré de liberté car il ne peut prendre qu'un seuil avec une constante parallèle à chaque axe dans l'espace colorimétrique.

Par conséquent, lors de l'utilisation d'inRange hsv_h.jpg Comme vous pouvez le voir, il sera très difficile de distinguer le câble noir en bas de l'image et le mur blanc en haut de l'image de la boule verte.

Implémentation dans Numpy

Filtres similaires à inRange dans 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

Je pense qu'il peut être mis en œuvre comme. dans ce cas

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

La partie est

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

Non seulement le seuil en tant que constante parallèle à l'axe de l'espace colorimétrique, mais également le seuil peut être défini en fonction du rapport de chaque élément, et le seuil linéaire ou plus compliqué peut être défini. Dans l'exemple ci-dessus, l'image après détection sera la suivante, et je pense que le résultat attendu peut être facilement obtenu. Dans l'exemple ci-dessus, il est détecté lorsque l'élément vert est deux fois plus brillant que le rouge et le bleu, et les parties en noir et blanc peuvent être facilement exclues comme illustré ci-dessous. rgb_g.jpg

Comparaison de vitesse

Par contre, concernant la vitesse

  1. inRange
  2. numpy (condition de filtre similaire à inRange)
  3. numpy( R/B > 2 & R/G>2 )
  4. cupy( R/B >2 & R/G > 2 ) Il est devenu comme suit dans les quatre conditions de.
1.inRange 2.numpy(Comme inRange) 3.numpy(Corrélation RVB) 4.CUPY
0.009[s] 0.047[s] 0.055[s] 0.021[s]

Je ne pensais pas qu'inRange était le plus rapide. .. .. ..

Code source que j'ai essayé

1, dans la portée détecte la boule verte

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. Comment binariser en spécifiant des conditions avec 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. Comment détecter dans des conditions impossibles à réaliser avec inRange avec numpy

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

Lors de l'accélération de 4 et 3 avec 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

Comparaison des méthodes de détection des couleurs dans OpenCV inRange, numpy, cupy
Gestion de l'espace colorimétrique HSV inférieur et supérieur dans OpenCV
Mettez python, numpy, opencv3 dans ubuntu14
Réécrire NumPy par morceaux pour CuPy
Calcul de l'IoU moyen dans la détection d'objets
Exemple d'exécution de la détection d'objets blob avec OpenCV
Résumé des méthodes fréquemment utilisées chez les pandas
Détection automatisée du répertoire de construction dans waf
Comparaison des solutions aux problèmes d'appariement de poids
Résumé des méthodes intégrées, etc. de la liste Python