Reconnaissons les objets rouges avec python

en premier

En python, notamment avec le support d'OpenCV, j'ai essayé de reconnaître un objet rouge à partir de l'image de la caméra vidéo, j'ai donc fait un article.

En raison de l'utilisation d'OpenCV, il est possible d'utiliser C / C ++ au lieu de python, mais si vous le faites avec python, vous pouvez l'écrire avec une quantité de travail étonnamment faible, c'est incroyable.

J'ai donc essayé d'écrire un article w

Comment détecter les objets rouges?

Le terme algorithme est cool à utiliser, mais ce n'est pas si noble. Je voudrais aborder le mécanisme de détection des objets rouges.

Je pense qu'il existe une méthode standard pour exprimer les couleurs RVB. En exprimant la luminosité de chacun des R, V et B de 0 à 255, il devient une couleur 24 bits. Alors, ce RVB peut-il être utilisé pour déterminer le rouge? C'est en fait assez difficile. Par exemple, R = 255, G = 0, B = 0 sera rouge, peu importe qui dit quoi. Mais qu'en est-il de R = 10, G = 0, B = 0? N'est-ce pas noir plutôt que rouge? Je me sens comme ça. En d'autres termes, il est difficile de juger de la teinte avec RVB.

Par conséquent, nous utilisons une structure de données appelée espace colorimétrique HSV. \ (Pour plus de détails, accédez à [Wikipedia](https://ja.wikipedia.org/wiki/HSV color space) )

Maintenant, créons une fonction et convertissons-la en espace colorimétrique HSV. L'importation d'OpenCV et de numpy est une norme.

import cv2
import numpy as np

def find_rect_of_target_color(image):
  hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV_FULL)
  h = hsv[:, :, 0]
  s = hsv[:, :, 1]

Jusqu'à ce point, les composantes H et S de l'image ont été extraites. Le composant H est Hue (teinte). En fait, il tourne comme un cercle en 360 pas: rouge → vert → bleu → rouge. Comme je l'ai écrit au début, il est difficile de juger de la teinte avec RVB, mais une fois converti en HSV, il devient très facile de juger par teinte en regardant H.

Dans le cas d'OpenCV, H, S et V sont tous tenus en 256 étapes (lorsque COLOR_BGR2HSV_FULL est spécifié), donc le H d'origine devrait être de 360 pas, mais il est arrondi à 256 étapes. Prenez ce côté en compte et continuez. En parlant de rouge dans la teinte (teinte), il est d'environ 280 à 28 ° y compris la gamme violacée. Si vous recalculez cela en 256 étapes, je pense que ce sera environ 200 à 20. Par conséquent, la plage où la valeur de H est (H <20 | H> 200) est rouge.

Faites également attention à la profondeur des couleurs. Même si la teinte (teinte) est rouge, si la couleur est suffisamment claire, elle s'approchera du blanc ou du noir. Il est nécessaire de juger en même temps la composante S et la saturation. Il est généralement compris entre 0 et 255, et plus le nombre est grand, plus il est "vif". Ici, puisqu'il s'agit d'un jugement rouge, ajoutons-le à la condition que la valeur de S soit (S> 128).

Si vous les écrivez ensemble de manière numpy, cela ressemblera à ce qui suit.

  mask = np.zeros(h.shape, dtype=np.uint8)
  mask[((h < 20) | (h > 200)) & (s > 128)] = 255

Vous avez maintenant les données de masque qui montrent la partie rouge. (255 pour le rouge, 0 pour le non-rouge) Mais ce n'est pas la fin. Ces données de masque ne montrent que "où les points sont rougeâtres" dans l'image.

Analyser les données du masque

Après tout, tant qu'il détecte un objet rouge, je veux reconnaître un bloc de points d'une certaine taille. Dans l'état actuel des choses, ce n'est qu'un groupe de points, et il n'y a pas d'unité. Afin de reconnaître ces données, qui ne sont qu'un point, comme un bloc, considérons d'abord ce qu'on appelle un "contour". Une fois que vous avez un contour, vous connaissez la masse entourée par ce contour.

  contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

La combinaison d'OpenCV et de python est excellente. Vous pouvez l'écrire en une seule ligne. Regardons maintenant le contenu de contours. En fait, lors du processus de création du contour, il a déjà été disposé en morceaux.

  rects = []
  for contour in contours:
    approx = cv2.convexHull(contour)
    rect = cv2.boundingRect(approx)
    rects.append(rect)    

J'écrirai à nouveau la même chose, mais la combinaison d'OpenCV et de python est excellente. C'est vraiment concis. cv2.convexHull () est une fonction qui calcule une forme convexe contenant une masse inégale. Le contour contient des informations de point qui forment le contour, mais comme il ne s'agit que d'un contour, il a une forme très compliquée, comme une côte de rias. C'est cv2.convexHull () qui transforme cela en un polygone 2D qui ressemble à un sac qui s'enroule. La valeur de retour ʻapproxest un tableau de (X, Y). Ensuite,cv2.boundingRect ()` calcule le rectangle dans lequel s'inscrit le polygone en forme de sac. Il renvoie des informations rectangulaires de la forme (x, y, largeur, hauteur). Jusqu'à ce point, les informations sur le groupe de points ont été collectées dans une liste de rectangles pour chaque bloc.

Maintenant, connectons ce que j'ai écrit séparément dans l'ordre.

import cv2
import numpy as np

def find_rect_of_target_color(image):
  hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV_FULL)
  h = hsv[:, :, 0]
  s = hsv[:, :, 1]
  mask = np.zeros(h.shape, dtype=np.uint8)
  mask[((h < 20) | (h > 200)) & (s > 128)] = 255
  contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
  rects = []
  for contour in contours:
    approx = cv2.convexHull(contour)
    rect = cv2.boundingRect(approx)
    rects.append(np.array(rect))
  return rects

Seulement ça. Avec juste cela, nous avons une fonction qui renvoie un tableau de rectangles qui identifient les points rouges dans l'image donnée.

Analyser la vidéo d'une caméra vidéo

Après l'avoir fait jusqu'à présent, je voudrais confirmer son fonctionnement. Traitons en temps réel avec l'image de la caméra vidéo.

if __name__ == "__main__":
  capture = cv2.VideoCapture()
  while cv2.waitKey(30) < 0:
    _, frame = capture.read()
    rects = find_rect_of_target_color(frame)
    for rect in rects:
      cv2.rectangle(frame, tuple(rect[0:2]), tuple(rect[0:2] + rect[2:4]), (0, 0, 255), thickness=2)
    cv2.imshow('red', frame)
  capture.release()
  cv2.destroyAllWindows()

comment c'est? Avez-vous obtenu les résultats escomptés? C'est mon attente, mais je pense que c'était un mauvais résultat. C'est parce que les grands et petits rectangles sont reconnus comme des «objets rouges». Il est absurde de penser à quelque chose comme le bruit comme un «objet». Éclaircissons-le parce que c'est une certaine taille.

Ici, une petite recommandation est de ne faire que du plus grand rectangle un "objet rouge". Pour détecter un objet rouge, avez-vous tenu l'objet rouge à portée de main devant la caméra? En d'autres termes, je voulais le détecter. Souvent, ce que vous voulez détecter est la plus grosse copie.

Modifiez ce qui suit afin que celui qui possède la plus grande surface soit recherché dans la liste rectangulaire obtenue.

if __name__ == "__main__":
  capture = cv2.VideoCapture()
  while cv2.waitKey(30) < 0:
    _, frame = capture.read()
    rects = find_rect_of_target_color(frame)
    if len(rects) > 0:
      rect = max(rects, key=(lambda x: x[2] * x[3]))
      cv2.rectangle(frame, tuple(rect[0:2]), tuple(rect[0:2] + rect[2:4]), (0, 0, 255), thickness=2)
    cv2.imshow('red', frame)
  capture.release()
  cv2.destroyAllWindows()

Alors c'est tout pour cette fois. Je suis impressionné par le fait que la combinaison de python + OpenCV est très pratique.

Recommended Posts

Reconnaissons les objets rouges avec python
Statistiques avec python
Python avec Go
Twilio avec Python
Intégrer avec Python
Jouez avec 2016-Python
AES256 avec python
Testé avec Python
python commence par ()
avec syntaxe (Python)
Bingo avec python
Zundokokiyoshi avec python
Excel avec Python
Micro-ordinateur avec Python
Cast avec python
Suivi des objets verts avec python + numpy (filtre à particules)
Zip, décompressez avec python
Django 1.11 a démarré avec Python3.6
Jugement des nombres premiers avec Python
Python avec eclipse + PyDev.
Grattage en Python (préparation)
Essayez de gratter avec Python.
Apprendre Python avec ChemTHEATER 03
Recherche séquentielle avec Python
"Orienté objet" appris avec python
Exécutez Python avec VBA
Manipuler yaml avec python
Communication série avec python
Apprendre Python avec ChemTHEATER 05-1
Apprenez Python avec ChemTHEATER
Exécutez prepDE.py avec python3
1.1 Premiers pas avec Python
Collecter des tweets avec Python
Binarisation avec OpenCV / Python
3. 3. Programmation IA avec Python
Méthode Kernel avec Python
Non bloquant avec Python + uWSGI
Grattage avec Python + PhantomJS
Publier des tweets avec python
Conduisez WebDriver avec python
Utiliser mecab avec Python 3
[Python] Redirection avec CGIHTTPServer
Analyse vocale par python
Pensez à yaml avec python
Utiliser Kinesis avec Python
Premiers pas avec Python
Utiliser DynamoDB avec Python
Getter Zundko avec python
Gérez Excel avec python
Loi d'Ohm avec Python
Jugement des nombres premiers avec python
vscode ne reconnaît pas python
Exécutez Blender avec python
Résoudre des maths avec Python
Python à partir de Windows 7
Carte thermique par Python + matplotlib
Multi-processus de manière asynchrone avec python
Apprendre Python avec ChemTHEATER 02
Utilisez Python 3.8 avec Anaconda
Programmation compétitive avec python
Manipuler rabbimq avec python