Comment détecter des formes géométriques simples en utilisant OpenCV
j'ai ce projet où j'ai besoin (sur iOS) de détecter des formes géométriques simples à l'intérieur d'une image.
après avoir cherché sur internet, J'ai conclu que le meilleur outil pour cela est OpenCV. Le truc c'est que jusqu'à il y a deux heures, je n'avais aucune idée de ce qu'était OpenCV et je n'ai jamais rien fait impliquant le traitement d'image. Mon expérience principale est JS / HTML, C#, SQL, Objective-C...
Où dois-je commencer?
j'ai trouvé cette réponse que j'ai pu digérer et en lisant déjà d'autres choses, je comprends Qu'OpenCV devrait retourner un tableau de formes avec les points/coins, est-ce vrai? Aussi comment peut-elle représenter un cercle ou demi-cercle? Qu'en est-il de l'orientation de la forme?
connaissez-vous un projet de démonstration iOS qui puisse démontrer une fonctionnalité similaire?
3 réponses
si vous avez seulement ces formes régulières, il y a une procédure simple comme suit:
- trouver les Contours de L'image (l'image doit être binaire comme indiqué dans votre question)
- se rapproche de chaque contour en utilisant la fonction
approxPolyDP
. - tout d'abord, vérifiez le nombre d'éléments dans les contours approximatifs de toutes les formes. C'est de reconnaître la forme. Par exemple, square en aura 4, le Pentagone en aura 5. Les cercles auront plus, Je ne sais pas, donc on le trouve. (J'ai eu 16 pour le cercle et 9 pour le demi-cercle.)
- assignez maintenant la couleur, lancez le code pour votre image de test, vérifiez son numéro, le remplir avec les couleurs correspondantes.
ci-dessous est mon exemple en Python:
import numpy as np
import cv2
img = cv2.imread('shapes.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,127,255,1)
contours,h = cv2.findContours(thresh,1,2)
for cnt in contours:
approx = cv2.approxPolyDP(cnt,0.01*cv2.arcLength(cnt,True),True)
print len(approx)
if len(approx)==5:
print "pentagon"
cv2.drawContours(img,[cnt],0,255,-1)
elif len(approx)==3:
print "triangle"
cv2.drawContours(img,[cnt],0,(0,255,0),-1)
elif len(approx)==4:
print "square"
cv2.drawContours(img,[cnt],0,(0,0,255),-1)
elif len(approx) == 9:
print "half-circle"
cv2.drawContours(img,[cnt],0,(255,255,0),-1)
elif len(approx) > 15:
print "circle"
cv2.drawContours(img,[cnt],0,(0,255,255),-1)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
ci-dessous est la sortie:
rappelez-vous, il ne fonctionne que pour les formes régulières.
alternativement pour trouver des cercles, vous pouvez utiliser houghcircles
. Vous pouvez trouver un tutorial ici .
en ce qui concerne iOS , OpenCV devs sont en train de développer quelques échantillons iOS cet été, alors visitez leur site : www.code.opencv.org et les contacter.
vous pouvez trouver des diapositives de leur tutoriel ici: http://code.opencv.org/svn/gsoc2012/ios/trunk/doc/CVPR2012_OpenCV4IOS_Tutorial.pdf
la réponse dépend de la présence d'autres formes, du niveau de bruit s'il y en a et de l'invariance que vous voulez prévoir (par exemple, rotation, échelle, etc.). Ces exigences définiront non seulement l'algorithme, mais aussi les étapes préalables à l'extraction des caractéristiques.
template matching qui a été suggéré ci-dessus fonctionne bien lorsque les formes ne sont pas tournés ou à l'échelle et quand il n'y a pas de formes similaires autour; en d'autres termes, il trouve un meilleur traduction dans l'image où le modèle est situé:
double minVal, maxVal;
Point minLoc, maxLoc;
Mat image, template, result; // template is your shape
matchTemplate(image, template, result, CV_TM_CCOEFF_NORMED);
minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc); // maxLoc is answer
Géométrique hachage est une bonne méthode pour obtenir l'invariance en termes de rotation et d'échelle; cette méthode nécessite l'extraction de certains points des contours.
de Hough Généralisée transformation peut prendre soin d'invariance, de bruit et aurait minimal de pré-traitement, mais il est un peu plus difficile à mettre en œuvre que d'autres méthodes. OpenCV a une telle transforme pour les lignes et les cercles.
dans le cas où le nombre de formes est limité calculant des moments ou en comptant les sommets convexes de la coque peut être la solution la plus facile: openCV analyse structurale
vous pouvez également utiliser template matching pour détecter les formes à l'intérieur d'une image.