从这张图片中识别绿色圆圈
Identifying green circles from this image
我目前制作了一张由黑点和绿点组成的图像.....我打印了它然后用我的相机点击它.....之后我制作了一个程序来扫描这个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);
vector<vec3f> circles1;
HoughCircles(image_gray, circles1, CV_HOUGH_GRADIENT, 2, 10, 100, 22, 10, 17);
我可以用这段代码扫描圆圈,运行 循环遍历每个圆圈……但现在我想知道圆圈是绿色还是黑色……我不知道我不知道该怎么做....我尝试将它转换为 hsv 但它在有光的一侧显示不同的颜色......请帮我解决这个问题....
OpenCV 有一个名为 InRange
的函数(在 C++ 中为 cv2.InRange
、Java- Core.InRange
)。在该函数中,您提供了两个 Scalar
对象:一个是颜色范围的起始 BGR 颜色,另一个是结束。它会 return 你一个白色像素的掩码:白色在范围内,黑色不在。更多信息 HERE。我建议你在HoughCircles
之前调用InRange
,这样会更容易判断绿色对象中哪些对象是圆,而不是哪些圆是绿色。
我试过用这个方法来解决你的问题:
- 首先,我使用起始 HSV 值
Scalar(37, 38, 70)
和结束 Scalar(85, 255, 200)
执行 InRange 函数。请注意,您在标量中放置的不是 RGB 或 BGR 值,它是 HSV 颜色(范围从 H (0-180)、S(0-255)、V(0-255),如 THIS 答案中所写):
- 其次,我像您在代码中那样执行 HoughCircles 算法:
如您所见,有一个圆圈不应该出现,而且两张图片上的圆圈大小可能不同。我强烈建议您使用 InRange 函数的值来改善颜色选择,使圆圈更圆更完美,并使用 HoughCircles 来避免随机和不必要的圆圈,因为我在最后一张图片的中间得到了一个。此外,我会建议您尝试使用 Canny 算法(Canny 边缘检测器)来清除这些对象的中心,也许您的结果会有所改善。
代码在Java中,但你应该很容易理解它,因为你主要关心的是InRange函数:
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;
最后,这个算法即使有正确的值也可能并不完美。我认为使用适当的值可以产生非常好的或完美的结果(遗憾的是我没有太多时间找出它们,所以我把它留给你),但如果你需要完美的结果我建议你尝试一下在更广泛的范围内。例如,在彩色图像上调用 Canny 函数(如您提供的那样)可能会为您提供非常准确的圆圈和其他物体的轮廓。然后,例如,您可以在这些轮廓上执行 HoughCircles 函数并获取它们的数据,清除圆圈外的所有像素。然后使用 InRange,您可以检查圆圈的颜色并对其进行分类……但这只是理论上的。尝试您想到的一切。此实验可能会为您提供比更新的当前结果更正确的结果。祝你好运!
好吧,我刚刚尝试了 HSV 方法,经过一些反复试验,我找到了只有绿色区域会出现的范围。一旦获得显示绿色圆圈位置的白色像素图像,就可以调用 HoughCircles。
HSV 的范围是 (32,22,0) 到 (103,142,160)
我希望这能解决问题。 :)
我目前制作了一张由黑点和绿点组成的图像.....我打印了它然后用我的相机点击它.....之后我制作了一个程序来扫描这个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);
vector<vec3f> circles1;
HoughCircles(image_gray, circles1, CV_HOUGH_GRADIENT, 2, 10, 100, 22, 10, 17);
我可以用这段代码扫描圆圈,运行 循环遍历每个圆圈……但现在我想知道圆圈是绿色还是黑色……我不知道我不知道该怎么做....我尝试将它转换为 hsv 但它在有光的一侧显示不同的颜色......请帮我解决这个问题....
OpenCV 有一个名为 InRange
的函数(在 C++ 中为 cv2.InRange
、Java- Core.InRange
)。在该函数中,您提供了两个 Scalar
对象:一个是颜色范围的起始 BGR 颜色,另一个是结束。它会 return 你一个白色像素的掩码:白色在范围内,黑色不在。更多信息 HERE。我建议你在HoughCircles
之前调用InRange
,这样会更容易判断绿色对象中哪些对象是圆,而不是哪些圆是绿色。
我试过用这个方法来解决你的问题:
- 首先,我使用起始 HSV 值
Scalar(37, 38, 70)
和结束Scalar(85, 255, 200)
执行 InRange 函数。请注意,您在标量中放置的不是 RGB 或 BGR 值,它是 HSV 颜色(范围从 H (0-180)、S(0-255)、V(0-255),如 THIS 答案中所写):
- 其次,我像您在代码中那样执行 HoughCircles 算法:
如您所见,有一个圆圈不应该出现,而且两张图片上的圆圈大小可能不同。我强烈建议您使用 InRange 函数的值来改善颜色选择,使圆圈更圆更完美,并使用 HoughCircles 来避免随机和不必要的圆圈,因为我在最后一张图片的中间得到了一个。此外,我会建议您尝试使用 Canny 算法(Canny 边缘检测器)来清除这些对象的中心,也许您的结果会有所改善。
代码在Java中,但你应该很容易理解它,因为你主要关心的是InRange函数:
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;
最后,这个算法即使有正确的值也可能并不完美。我认为使用适当的值可以产生非常好的或完美的结果(遗憾的是我没有太多时间找出它们,所以我把它留给你),但如果你需要完美的结果我建议你尝试一下在更广泛的范围内。例如,在彩色图像上调用 Canny 函数(如您提供的那样)可能会为您提供非常准确的圆圈和其他物体的轮廓。然后,例如,您可以在这些轮廓上执行 HoughCircles 函数并获取它们的数据,清除圆圈外的所有像素。然后使用 InRange,您可以检查圆圈的颜色并对其进行分类……但这只是理论上的。尝试您想到的一切。此实验可能会为您提供比更新的当前结果更正确的结果。祝你好运!
好吧,我刚刚尝试了 HSV 方法,经过一些反复试验,我找到了只有绿色区域会出现的范围。一旦获得显示绿色圆圈位置的白色像素图像,就可以调用 HoughCircles。
HSV 的范围是 (32,22,0) 到 (103,142,160)
我希望这能解决问题。 :)