从此图片中识别绿色圆圈 [英] Identifying green circles from this image

查看:519
本文介绍了从此图片中识别绿色圆圈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前做了一个由黑色和绿色的点组成的图像.....我做了一个打印,然后点击它用我的相机.....之后,我做了一个程序来扫描这个图像opencv。图片如下:





这是代码

  image = imread(ImageTryse.jpg,1); // read the image 
cv :: resize(image,image,Size(800,800),0,0,cv :: INTER_CUBIC);
Mat image_gray = IncreaseContrast(image);
cvtColor(image_gray,image_gray,CV_BGR2GRAY);
矢量< vec3f> circle1;
HoughCircles(image_gray,circles1,CV_HOUGH_GRADIENT,2,10,100,22,10,17);

我可以使用此代码扫描圈子,并对每个圈子执行循环....但现在我想知道的天气圆圈是绿色或黑色....我不知道我怎么能这样....我试图转换为hsv,但它是显示不同的颜色在一侧有光.. ...请帮助我解决这个问题....

解决方案

OpenCV有一个函数 InRange (在C ++中为 cv2.InRange ,Java- Core.InRange ) 。在该函数中,您提供两个 Scalar 对象:一个是颜色范围的起始BGR颜色,另一个是结束。它会返回一个白色像素的掩码:白色在范围内,黑色不是。详情请参阅




  • 其次,我在您的代码中执行HoughCircles algorythm:





如您所见,它应该不是,也可以在两个图片上的圆圈的大小不同。我强烈建议你使用InRange函数的值来改善颜色选择,使圆圈更圆和更完美,和HoughCircles避免随机和不必要的圈子,因为我有一个在最后一张图片的中间。此外,我会提供你实验Canny algorythm(Canny边缘检测器)来清除这些对象的中心,也许你的结果会改善。



代码是Java的,但你应该很容易理解它,因为你的问题主要是InRange函数:

  Mat src = new Mat(); 
Mat circles = new Mat();
结果;

Utils.bitmaptoMat(Image,src);
Imgproc.cvtColor(src,src,Imgproc.COLOR_BGR2HSV);

Core.inRange(src,new Scalar(37,38,70),new Scalar(85,255,200),src);
Imgproc.HoughCircles(src,circles,Imgproc.CV_HOUGH_GRADIENT,2,30,100,22,10,17);

result = new Mat(src.rows(),src.cols(),CvType.CV_8UC1,new Scalar(0,0,0));
for(int i = 0; i< circles.cols(); i ++)
{
double [] circle = circles.get(0,i);
if(circle = null)break;
Point center = new Point(Math.round(circle [0]),Math.round(circle [1]));
int radius =(int)Math.round(circle [2]);
Imgproc.circle(result,center,radius,new Scalar(255,0,0));
}
return result;

最后,这个algorythm甚至有正确的值可能不是完美的。我认为有可能产生一个真正伟大的或完美的结果与正确的价值观(我很遗憾没有很多时间找出他们,所以我留给你),但如果你需要完美的结果,我建议你试验在更广泛的幽灵。例如,在彩色图像(如您提供的)上调用Canny函数可能会给您非常准确的圆和其他对象的轮廓。然后,例如,您可以对这些轮廓执行HoughCircles函数并拥有它们的数据,清除圆圈外的所有像素。然后用InRange你可以检查圆的颜色,整理出来...但这只是理论。尝试一切你想到的东西。这个实验可以为您提供更新的当前结果更正确的结果。祝你好运!


I have currently made an image that consists of black and green dots..... I made a print of it and then clicked it with my camera..... After that i made a program to scan this image in opencv. Here is the image:

This is the code

    image = imread("ImageTryse.jpg", 1); // Read the image
cv::resize(image, image, Size(800, 800), 0, 0, cv::INTER_CUBIC);
Mat image_gray = IncreaseContrast(image);
cvtColor(image_gray, image_gray, CV_BGR2GRAY);
vector<vec3f> circles1;
HoughCircles(image_gray, circles1, CV_HOUGH_GRADIENT, 2, 10, 100, 22, 10, 17);

I am able to scan circles with this code and run a loop through each of them.... But now i want to know weather the circle is green or black.... I don't know how i can do that.... I tried converting it to hsv but it was showing different colors on the side having light..... Please help me to solve this problem....

解决方案

OpenCV has a function called InRange (in C++ it would be cv2.InRange, Java- Core.InRange). In that function you provide two Scalar objects: one is starting BGR color of the range of colors, the other is the ending. It will return you a mask of white pixels: white color is in range, black is not. More information HERE. I'd recommend you to call InRange before HoughCircles, it would be easier to determine which objects of green ones are circles, rather than which circles are green.

I've tried out this method for solving your issue:

  • First, I perform InRange function with starting HSV values Scalar(37, 38, 70) and ending Scalar(85, 255, 200). Note that you are putting not RGB or BGR values in Scalar, it is HSV color (ranges from H (0-180), S(0-255), V(0-255), as written in THIS answer):

  • Secondly, I perform a HoughCircles algorythm as you do in your code:

As you see, there is one circle where it should not be, also the circles may be different in size on both pictures. I would highly suggest you to play with values of InRange function to improve color selection, making circles rounder and more perfect, and HoughCircles to avoid random and unnecessary circles as I got one in the middle of the last picture. Also, I would offer you to experiment with Canny algorythm (Canny edge detector) to clear centers of those objects, maybe your results will improve then.

The code is in Java, but you should easily understand it as your concern is mainly InRange function:

Mat src = new Mat();
Mat circles = new Mat();
Mat result;

Utils.bitmapToMat(Image, src);
Imgproc.cvtColor(src, src, Imgproc.COLOR_BGR2HSV);

Core.inRange(src, new Scalar(37, 38, 70), new Scalar(85, 255, 200), src);
Imgproc.HoughCircles(src, circles, Imgproc.CV_HOUGH_GRADIENT, 2, 30, 100, 22, 10, 17);

result = new Mat(src.rows(), src.cols(), CvType.CV_8UC1, new Scalar(0,0,0));
for (int i = 0; i < circles.cols(); i++)
{
    double[] circle = circles.get(0, i);
    if (circle == null) break;
    Point center = new Point(Math.round(circle[0]), Math.round(circle[1]));
    int radius = (int)Math.round(circle[2]);
    Imgproc.circle(result, center, radius, new Scalar(255, 0, 0));
}
return result;

At last, this algorythm even with the right values may not be perfect. I think it is possible to produce a really great or perfect results with the proper values (I sadly did not had much time to find out them, so I leave it to you), but if you need perfect result I would suggest you to experiment in a wider spectre. For example, calling Canny function on coloured image (like you provided) may give you very accurate contours of circles and other objects. Then, for example, you could perform a HoughCircles function on those contours and having data of them, clear all the pixels outside of circles. Then with InRange you could check the colours of circles and sort out them... But this is just theoretical. Try everything what comes to your mind. This experimenting may provide you with result more correct that the updated current one. Good luck!

这篇关于从此图片中识别绿色圆圈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆