OpenCV点目标检测未找到所有目标,并发现圆圈是偏移的

我正试图检测黑/白点目标的中心,就像在这张照片中一样。 我试过使用cv2.HoughCircles方法,但是1,我只能检测2到3个目标,2,当我将找到的圆绘制回图像时,它们总是略微偏移。

我使用了错误的方法吗? 我应该使用findContours还是完全不同的东西?

这是我的代码:

import cv2 from cv2 import cv import os import numpy as np def showme(pic): cv2.imshow('window',pic) cv2.waitKey() cv2.destroyAllWindows() im=cv2.imread('small_test.jpg') gray=cv2.cvtColor(im,cv2.COLOR_BGR2GRAY) #I've tried blur,bw,tr... all give me poor results. blur = cv2.GaussianBlur(gray,(3,3),0) n,bw = cv2.threshold(blur,120,255,cv2.THRESH_BINARY) tr=cv2.adaptiveThreshold(blur,255,0,1,11,2) circles = cv2.HoughCircles(gray, cv.CV_HOUGH_GRADIENT, 3, 100, None, 200, 100, 5, 16) try: n = np.shape(circles) circles=np.reshape(circles,(n[1],n[2])) print circles for circle in circles: cv2.circle(im,(circle[0],circle[1]),circle[2],(0,0,255)) showme(im) except: print "no cicles found" 

这是我目前的输出:

播放我在另一篇文章中写的代码,我能够获得更好的结果:

这都是关于参数的。 它总是如此。

您应该在此程序中调用3个重要函数: cvSmooth()cvCanny()cvHoughCircles() 。 他们每个人都有可能彻底改变结果。

这是C代码:

 IplImage* img = NULL; if ((img = cvLoadImage(argv[1]))== 0) { printf("cvLoadImage failed\n"); } IplImage* gray = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1); CvMemStorage* storage = cvCreateMemStorage(0); cvCvtColor(img, gray, CV_BGR2GRAY); // This is done so as to prevent a lot of false circles from being detected cvSmooth(gray, gray, CV_GAUSSIAN, 7, 9); IplImage* canny = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1); IplImage* rgbcanny = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,3); cvCanny(gray, canny, 40, 240, 3); CvSeq* circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT, 2, gray->height/8, 120, 10, 2, 25); cvCvtColor(canny, rgbcanny, CV_GRAY2BGR); for (size_t i = 0; i < circles->total; i++) { // round the floats to an int float* p = (float*)cvGetSeqElem(circles, i); cv::Point center(cvRound(p[0]), cvRound(p[1])); int radius = cvRound(p[2]); // draw the circle center cvCircle(rgbcanny, center, 3, CV_RGB(0,255,0), -1, 8, 0 ); // draw the circle outline cvCircle(rgbcanny, center, radius+1, CV_RGB(0,0,255), 2, 8, 0 ); printf("x: %dy: %dr: %d\n",center.x,center.y, radius); } cvNamedWindow("circles", 1); cvShowImage("circles", rgbcanny); cvSaveImage("out.png", rgbcanny); cvWaitKey(0); 

我相信你有把这个移植到Python的技能。

由于该圆形图案是固定的并且与对象区分开来,因此简单的模板匹配应该可以很好地工作,请查看cvMatchTemplate 。 对于更复杂的条件(由于对象形状或视图几何形状而变形),您可以尝试更强大的function,如SIFT或SURF( cvExtractSURF )。

大多数使用Python代码检测圈子

 import cv2 import numpy as np img = cv2.imread('coin.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(gray,(7,9),6) cimg = cv2.cvtColor(blur,cv2.COLOR_GRAY2BGR) circles = cv2.HoughCircles(blur,cv2.HOUGH_GRADIENT,1,50, param1=120,param2=10,minRadius=2,maxRadius=30) circles = np.uint16(np.around(circles)) for i in circles[0,:]: # draw the outer circle cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2) # draw the center of the circle cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3) cv2.imshow('detected circles',cimg) cv2.waitKey(0) cv2.destroyAllWindows()