Python和OpenCV。如何检测图像中的所有(填充)圆形/圆形对象? [英] Python and OpenCV. How do I detect all (filled)circles/round objects in an image?
问题描述
我试图制作一个程序,它打开一张图片,扫描它的圆/圆形并返回坐标,以便我可以使用 cv.Circle
函数来在检测到的圆上绘制圆圈。
我的问题是:如何使用 cv.HoughCircles()$ c获取图像中检测到的圆的坐标/半径$ c>?
使用此页面,我发现了如何检测这些圆圈(这让我花了很多时间来发现,因为我不了解像阈值这样的术语,而Python的OpenCV文档非常差,几乎没有。不幸的是,在该页面上它没有显示如何提取从创建的 CvMat
中检测到的每个圈子的信息。如何提取这些信息/是否有其他方式(例如,使用 MemoryStorage()
)?
是我的代码到目前为止:
$ $ p $ 导入cv,opencv
def main():
im = cv.LoadImageM(Proba.jpg)
gray = cv.CreateImage(cv.GetSize(im),8,1)
边缘= cv.CreateImage(cv.GetSize(im),8,1)
cv.CvtColor(im,gray,cv.CV_BGR2GRAY)
cv.Canny(灰色,边缘,50 ,200,3)
cv.Smooth(灰色,灰色,cv.CV_GAUSSIAN,9,9)
storage = cv.CreateMat(im.rows,1,cv.CV_32FC3)
cv.HoughCircles(边缘,存储,cv.CV_HOUGH_GRADIENT,2,gray.height / 4,200,100)
#现在,假设它找到了圆圈,我该如何提取信息?
print storage.r
$ b $ if if __name__ =='__main__':
main()
另外, HoughCircles
的最后两个参数需要具备什么值才能让我检测真正的小圆圈(如屏幕上的3毫米)?
谢谢大家的时间和精力试图帮助我!
我正在处理的图像是这样的:
最后两个参数似乎被传递给 cv.Canny()
,这意味着从 cv.Canny()
。我对此不太确定。
至于尺寸,它好像接下来的两个参数(在 200,100之后) code>默认为
0
,这可能意味着检测到所有尺寸。
从C ++示例的源代码中,我也可以猜测你不需要做Canny边缘检测:
#include< cv.h>
#include< highgui.h>
#include< math.h>
使用namespace cv;
int main(int argc,char ** argv)
{
Mat img,grey;
if(argc!= 2&&!(img = imread(argv [1],1))。data)
return -1;
cvtColor(img,gray,CV_BGR2GRAY);
// //平滑它,否则可能检测到很多假圆圈
GaussianBlur(灰色,灰色,尺寸(9,9),2,2);
vector< Vec3f>界;
HoughCircles(灰色,圆圈,CV_HOUGH_GRADIENT,
2,灰色 - >行/ 4,200,100);
for(size_t i = 0; i< circles.size(); i ++)
{
点中心(cvRound(circles [i] [0]),cvRound(圈[i ] [1]));
int radius = cvRound(circles [i] [2]);
//绘制圆心
circle(img,center,3,Scalar(0,255,0),-1,8,0);
//绘制圆形轮廓
circle(img,center,radius,Scalar(0,0,255),3,8,0);
}
namedWindow(circles,1);
imshow(circles,img);
返回0;
}
您试图将此C ++代码转换为Python,我认为?
for(size_t i = 0; i {
点中心(cvRound(circles [i] [0]),cvRound(circles [i] [1]));
int radius = cvRound(circles [i] [2]);
//绘制圆心
circle(img,center,3,Scalar(0,255,0),-1,8,0);
//绘制圆形轮廓
circle(img,center,radius,Scalar(0,0,255),3,8,0);
}
据我所知, CvMat
对象可迭代,就像列表一样:
存储中的圆圈:
radius = circle [2]
center =(circle [0],circle [1])$ b
$ b cv.Circle(im,center,radius,(0,0,255),3,8, 0)
我没有任何测试图片,所以不要误解我的意思。您的完整代码可能是:
import cv
def main():
im = cv.LoadImage('Proba.jpg')
gray = cv.CreateImage(cv.GetSize(im),8,1)
edges = cv.CreateImage(cv.GetSize(im), 8,1)
cv.CvtColor(im,gray,cv.CV_BGR2GRAY)
#cv.Canny(灰色,边缘,20,55,3)
storage = cv.CreateMat(im.width,1,cv.CV_32FC3)
cv.HoughCircles(edges,storage,cv.CV_HOUGH_GRADIENT,5,25,200,10)
我在xrange(storage.width - 1)中:
radius = storage [i,2]
center =(storage [i,0],storage [i,1])$ b
$ b print(radius,center)
cv.Circle(im,center,radius,(0,0,255),3,8,0)
cv。 NamedWindow('Circles')
cv.ShowImage('Circles',im)
cv.WaitKey(0)
if __name__ =='__main__':
main()
I am trying to make a program which opens an image, scans it for circles/round shapes and returns the coordinates so that I can use the cv.Circle
function to draw circles over the circle detected.
My question is: How do I get the coordinates/radii of the circles detected in an image using cv.HoughCircles()
?
Using this page, I found out how to detect the circles (which took me a lot of time to find out since I don't understand terms like threshold and the OpenCV documentation for Python is really poor, almost none). Unfortunately, on that page it didn't show how to extract the information of each circle detected from the CvMat
created. How do I extract that information/is there some other way(eg. with MemoryStorage()
) ?
This is my code so far:
import cv, opencv
def main():
im = cv.LoadImageM("Proba.jpg")
gray = cv.CreateImage(cv.GetSize(im), 8, 1)
edges = cv.CreateImage(cv.GetSize(im), 8, 1)
cv.CvtColor(im, gray, cv.CV_BGR2GRAY)
cv.Canny(gray, edges, 50, 200, 3)
cv.Smooth(gray, gray, cv.CV_GAUSSIAN, 9, 9)
storage = cv.CreateMat(im.rows, 1, cv.CV_32FC3)
cv.HoughCircles(edges, storage, cv.CV_HOUGH_GRADIENT, 2, gray.height/4, 200, 100)
# Now, supposing it found circles, how do I extract the information?
print storage.r
if __name__ == '__main__':
main()
Also, what value do the last two parameters of HoughCircles
need to have in order for me to detect really small circles (like 3mm on the screen) ?
Thank you all for your time and effort trying to help me!
The image I'm working with is this:
The last two parameters are what seem to be passed to cv.Canny()
, which implies that cv.Canny()
is called from within cv.HoughCircles()
. I'm not too sure about that.
As for the sizes, it seems like the next two parameters (after 200, 100)
default to 0
, which might mean that all sizes are detected.
From the C++ example's source, I can also guess that you don't need to do a Canny edge detection:
#include <cv.h>
#include <highgui.h>
#include <math.h>
using namespace cv;
int main(int argc, char** argv)
{
Mat img, gray;
if( argc != 2 && !(img=imread(argv[1], 1)).data)
return -1;
cvtColor(img, gray, CV_BGR2GRAY);
// smooth it, otherwise a lot of false circles may be detected
GaussianBlur( gray, gray, Size(9, 9), 2, 2 );
vector<Vec3f> circles;
HoughCircles(gray, circles, CV_HOUGH_GRADIENT,
2, gray->rows/4, 200, 100 );
for( size_t i = 0; i < circles.size(); i++ )
{
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
// draw the circle center
circle( img, center, 3, Scalar(0,255,0), -1, 8, 0 );
// draw the circle outline
circle( img, center, radius, Scalar(0,0,255), 3, 8, 0 );
}
namedWindow( "circles", 1 );
imshow( "circles", img );
return 0;
}
You're trying to convert this C++ code into Python, I assume?
for( size_t i = 0; i < circles.size(); i++ )
{
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
// draw the circle center
circle( img, center, 3, Scalar(0,255,0), -1, 8, 0 );
// draw the circle outline
circle( img, center, radius, Scalar(0,0,255), 3, 8, 0 );
}
As far as I can tell, CvMat
objects are iterable, just like a list:
for circle in storage:
radius = circle[2]
center = (circle[0], circle[1])
cv.Circle(im, center, radius, (0, 0, 255), 3, 8, 0)
I don't have any test images, so don't take my word that this works. Your complete code would might be:
import cv
def main():
im = cv.LoadImage('Proba.jpg')
gray = cv.CreateImage(cv.GetSize(im), 8, 1)
edges = cv.CreateImage(cv.GetSize(im), 8, 1)
cv.CvtColor(im, gray, cv.CV_BGR2GRAY)
#cv.Canny(gray, edges, 20, 55, 3)
storage = cv.CreateMat(im.width, 1, cv.CV_32FC3)
cv.HoughCircles(edges, storage, cv.CV_HOUGH_GRADIENT, 5, 25, 200, 10)
for i in xrange(storage.width - 1):
radius = storage[i, 2]
center = (storage[i, 0], storage[i, 1])
print (radius, center)
cv.Circle(im, center, radius, (0, 0, 255), 3, 8, 0)
cv.NamedWindow('Circles')
cv.ShowImage('Circles', im)
cv.WaitKey(0)
if __name__ == '__main__':
main()
这篇关于Python和OpenCV。如何检测图像中的所有(填充)圆形/圆形对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!