Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Image 在图像上检测硬币(和拟合椭圆)_Image_Image Processing_Opencv_Image Recognition - Fatal编程技术网

Image 在图像上检测硬币(和拟合椭圆)

Image 在图像上检测硬币(和拟合椭圆),image,image-processing,opencv,image-recognition,Image,Image Processing,Opencv,Image Recognition,我目前正在一个项目中工作,我试图发现一些硬币躺在一个平面上(例如桌子上)。硬币不会重叠,也不会被其他物体隐藏。但可能还有其他可见的物体,而且照明条件可能并不完美。。。基本上,考虑你自己在你的桌子上拍摄一些硬币。 所以每个点都应该是可见的椭圆。由于我不知道相机的位置,椭圆的形状可能会有所不同,从圆形(从顶部观看)到扁平椭圆,这取决于硬币拍摄的角度 我的问题是,我不知道如何提取硬币,并最终在其上拟合椭圆(我正在寻找做进一步的计算) 现在,我刚刚做了第一次尝试,在OpenCV中设置了一个阈值,使用fi

我目前正在一个项目中工作,我试图发现一些硬币躺在一个平面上(例如桌子上)。硬币不会重叠,也不会被其他物体隐藏。但可能还有其他可见的物体,而且照明条件可能并不完美。。。基本上,考虑你自己在你的桌子上拍摄一些硬币。

所以每个点都应该是可见的椭圆。由于我不知道相机的位置,椭圆的形状可能会有所不同,从圆形(从顶部观看)到扁平椭圆,这取决于硬币拍摄的角度

我的问题是,我不知道如何提取硬币,并最终在其上拟合椭圆(我正在寻找做进一步的计算)

现在,我刚刚做了第一次尝试,在OpenCV中设置了一个阈值,使用findContours()获得轮廓线并拟合椭圆。不幸的是,轮廓线很少给我硬币的形状(反射、光线不好等等),这种方式也不是首选,因为我不希望用户设置任何阈值

另一个想法是在该图像上使用椭圆的模板匹配方法,但由于我不知道相机的角度,也不知道椭圆的大小,我认为这不会很好地工作

所以我想问是否有人能告诉我一种适合我的方法

有没有快速的方法从图像中提取三枚硬币?应在移动设备上实时进行计算,并且该方法对于不同或变化的灯光或背景颜色不应太敏感。


如果有人能告诉我哪种方法对我有效,那就太好了。

我不知道解决你问题的最佳方法是什么。但是,关于阈值,您可以使用Otsu的方法,该方法根据图像直方图的分析自动找到最佳阈值。使用OpenCV的方法,参数
ThresholdType
等于
THRESH_OTSU

不过,请注意,大津的方法仅适用于具有双峰直方图的图像(例如,在黑暗背景下具有明亮物体的图像)

您可能已经看到了这一点,但也有一种方法用于处理一组二维点(例如,连接的组件)

编辑:应用于样本图像的大津方法:

灰度图像:

应用大津方法的结果:
以下是一些实现传统方法(基于OpenCV)的C99源代码:

这是输出图像:

您可以改进的方面:

  • 处理不同的椭圆方向(目前,我假设轴是垂直/水平的)。使用图像瞬间,这并不难做到
  • 检查对象凸度(查看
    cvconverxitydefects
区分硬币和其他物体的最佳方法可能是根据形状。我想不出任何其他低级的图像功能(颜色显然已过时)。因此,我可以想到两种方法:

传统的目标检测 您的第一个任务是从背景中分离对象(硬币和非硬币)。正如卡尼里所建议的那样,Ohtsu的方法在这里很有效。你似乎担心图像是两部分的,但我不认为这会是一个问题。只要有大量的桌子可见,你就可以保证在你的直方图中有一个峰值。只要桌子上有几个视觉上可分辨的物体,你就可以保证你的第二个高峰

你的二值图像经过多次处理,以消除阈值化留下的噪声。这些硬币相对较大,因此它们应该能经受住这种形态操作

使用区域增长将白色像素分组到对象中——只需迭代连接相邻的前景像素。在该操作结束时,您将有一个不相交对象的列表,并且您将知道每个对象占用哪些像素

根据此信息,您将知道对象的宽度和高度(从上一步开始)。所以,现在你可以估计物体周围椭圆的大小,然后看看这个特定物体与椭圆的匹配程度。仅仅使用宽高比可能更容易


或者,您可以使用以更精确的方式确定对象的形状。

如果将来有人像我一样出现此问题,但使用C++:

使用
findContours
查找轮廓后(如上面Misha的回答),您可以使用
fitEllipse
轻松拟合椭圆,例如

    vector<vector<Point> > contours;

    findContours(img, contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0,0));

    RotatedRect rotRecs[contours.size()];

    for (int i = 0; i < contours.size(); i++) {
        rotRecs[i] = fitEllipse(contours[i]);
    }
矢量轮廓;
查找轮廓(img、等高线、等高线树、等高线链近似、点(0,0));
RotatedRect rotRecs[轮廓.size()];
对于(int i=0;i
啊,对了,我听说过大津的方法。这看起来不错,但就像你说的,它只适用于二分直方图,在大多数情况下,我不会这样做,因为大部分其他对象都是可见的。我在这张照片上尝试了分水岭算法,效果很好,但对位法是跟踪硬币。我可以让用户在开始时选择硬币和桌子,但之后它会自动检测硬币。因此,用卡尔曼滤波器或粒子滤波器跟踪标记点可能不起作用,因为运动可能是不稳定的。你还有其他想法或建议吗?你以前没有提到过跟踪。你需要跟踪他们是因为他们在移动还是因为相机在移动?我猜是后者。请尝试OpenCV附带的blobtrack_sample.cpp。我在跟踪移动的车辆时得到了很好的效果,但在这种情况下,有很多很好的特征(拐角)需要跟踪,使用硬币可能会更困难。如果我使用
    vector<vector<Point> > contours;

    findContours(img, contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0,0));

    RotatedRect rotRecs[contours.size()];

    for (int i = 0; i < contours.size(); i++) {
        rotRecs[i] = fitEllipse(contours[i]);
    }