我目前制作了一个由黑色和绿色点组成的图像.....我打印了它然后用我的相机点击它.....之后我做了一个程序来扫描这个图像OpenCV的。这是图像:
这是代码
spyOn(this.Service, "functionWithPromise");
我可以使用此代码扫描圆圈并在每个圆圈中运行循环....但现在我想知道天气圆圈是绿色还是黑色....我不知道我该怎么做那....我试过将它转换为hsv,但它在光线一侧显示出不同的颜色.....请帮我解决这个问题....
答案 0 :(得分:1)
OpenCV有一个名为InRange
的函数(在C ++中它将是cv2.InRange
,Java- Core.InRange
)。在该函数中,您提供了两个Scalar
个对象:一个是启动颜色范围的BGR颜色,另一个是结束。它将返回一个白色像素的掩码:白色在范围内,黑色不在。更多信息HERE。我建议您在InRange
之前致电HoughCircles
,更容易确定哪些绿色对象是圆圈,而不是哪些圆圈为绿色。
我已尝试过这种方法来解决您的问题:
Scalar(37, 38, 70)
和结束Scalar(85, 255, 200)
。请注意,您在标量中没有放置RGB或BGR值,它是HSV颜色(范围从H(0-180),S(0-255),V(0-255),如THIS中所述):如您所见,有一个圆圈不应该是,两个图片上的圆圈大小也可能不同。我强烈建议你玩InRange功能的值来改善颜色选择,使圆圈更圆,更完美,HoughCircles避免随机和不必要的圆圈,因为我在最后一张图片的中间有一个。另外,我会让你尝试用Canny algorythm(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,您可以检查圆圈的颜色并进行整理......但这只是理论上的。尝试一下你想到的一切。此实验可能会为您提供更正确的更新当前结果。祝你好运!
答案 1 :(得分:1)
好吧,我只是尝试了HSV方法,并且几乎没有试验和错误,我能够找到只有绿色区域出现的范围。获得带有显示绿色圆圈位置的白色像素的图像后,您可以调用HoughCircles。
HSV的范围是(32,22,0)到(103,142,160)
我希望这能解决问题。 :)