我有一个问题,在黑色硬币内填充白洞,以便我只能有0-255二进制图像与填充黑色硬币..我使用中位数过滤器来完成它但在那种情况下硬币之间的连接桥增长,这是不可能的经过几次侵蚀后识别它们......所以我需要在opencv中使用简单的floodFill方法
这是我带孔的图片:

编辑:类似函数的floodfill必须填充大组件中的空洞而不提示X,Y坐标作为种子......
编辑:我试图使用cvDrawContours函数,但我没有在更大的内部填充轮廓.
这是我的代码:
CvMemStorage mem = cvCreateMemStorage(0);
CvSeq contours = new CvSeq();
CvSeq ptr = new CvSeq();
int sizeofCvContour = Loader.sizeof(CvContour.class);
cvThreshold(gray, gray, 150, 255, CV_THRESH_BINARY_INV);
int numOfContours = cvFindContours(gray, mem, contours, sizeofCvContour, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
System.out.println("The num of contours: "+numOfContours); //prints 87, ok
Random rand = new Random();
for (ptr = contours; ptr != null; ptr = ptr.h_next()) {
Color randomColor = new Color(rand.nextFloat(), rand.nextFloat(), rand.nextFloat());
CvScalar color = CV_RGB( randomColor.getRed(), randomColor.getGreen(), randomColor.getBlue());
cvDrawContours(gray, ptr, color, color, …Run Code Online (Sandbox Code Playgroud) 我有图像特征提取问题.输入图像是二进制(黑色和白色),并且可以包含近似已知区域和纵横比的斑点.这些需要使用一些最佳拟合算法与椭圆拟合.
输入示例:

期望的输出:

可能存在多个blob(零个或多个),该数量事先未知.所有斑点的近似面积和纵横比是已知的(并且是相同的).图像中有多少,它们的位置,方向和实际尺寸都是我想要找到的.根据实际找到的大小和纵横比,输出应该是每个blob的最佳拟合椭圆.
造成这种困难的是噪音和可能的重叠.
噪音示例:

重叠和噪音的示例:

嘈杂的图像可能在斑点中有洞,而且周围散布着小的其他斑点.小的其他斑点不计算在内,因为它们太小而且不能覆盖任何密集的区域以至于被认为是真正的匹配.
具有重叠的图像应该被计为两个斑点,因为该区域太大而单个斑点无法很好地覆盖它.
评估潜在拟合的可能指标是:
(K1*与预期尺寸的偏差百分比+ K2*与预期纵横比的偏差百分比+ K3*椭圆的百分比,非黑色+ K4*百分比与任何其他椭圆重叠)+ + K5*百分比的图像其余部分的总和这是黑色的
对于一些适当选择的参数K1..K5.完美的比赛得分为0.
我可以看到如何使用强力解决这个问题,例如尝试足够的不同可能的拟合来很好地对搜索空间进行采样.我无法想象一种比蛮力更快的方法.
我更喜欢python和/或opencv中的示例.我将尝试在python中实现并发布任何建议的解决方案.谢谢!
PS不能假设blob已连接.可能有足够的噪音将其分解成不连续的部分.
PPS二进制腐蚀无法消除少量噪声.在我的一些图像中,有足够的内部孔,如果图像被腐蚀到足以使噪声比特消失,则侵蚀使整个(真实)斑点消失.
PPPS我认为使用任何基于轮廓的方法来解决这个问题是非常困难的.我在实践中看到的数据有太多的边缘噪声,可能(通常是)一些噪声连接单独的blob,或者将单个blob分成几个(明显的)连接组件.我想基于区域的方法,因为区域覆盖似乎比边缘形状小得多.
PPPPS根据要求,这是一个由于噪音导致切入的示例:

和一个有很多很多噪音但仍然是一个明显斑点的样本:

编辑没有一个答案实际上解决了这个问题,尽管巴拉特提出了一个部分解决方案,它可以很好地解决非重叠的blob问题.请更多:)我将奖励任何实际解决方案的额外奖励.
我试图分离图像的轮廓(为了找到统一的区域),所以我应用了cvCanny然后cvFindContours,然后我每次按下一个键时使用以下代码绘制1个轮廓:
for( ; contours2 != 0; contours2 = contours2->h_next ){
cvSet(img6, cvScalar(0,0,0));
CvScalar color = CV_RGB( rand()&255, rand()&255, rand()&255 );
cvDrawContours(img6, contours2, color, cvScalarAll(255), 100);
//cvFillConvexPoly(img6,(CvPoint *)contours2,sizeof (contours2),color);
area=cvContourArea(contours2);
cvShowImage("3",img6);
printf(" %d", area);
cvWaitKey();
}
Run Code Online (Sandbox Code Playgroud)
但是在第一次迭代中它绘制了所有轮廓,在第二次迭代中它绘制了除了一个之外的所有轮廓,第三次绘制除了两个之外的所有轮廓,依此类推.
如果我用它填充大部分屏幕cvFillConvexPoly功能(尽管我写这个,我意识到一个凸多边形不会为我工作,我需要填写刚刚insideof轮廓)
那么,我怎样才能在for的每次迭代中只取一个轮廓,而不是所有剩余的轮廓?
谢谢.
我的工作基于带有点阵的图像(图1),最终结果如图4所示.我将逐步解释我的工作.
图1原始图像

步骤1:检测每个对象的边缘,包括点和我想要删除的"环"以获得更好的性能.边缘检测的结果如图2所示.我使用Canny边缘探测器,但它对一些浅灰色点不起作用.我的第一个问题是如何关闭点的轮廓并尽可能减少其他噪音?
图2边缘检测

第2步:扩张每个对象.我找不到填补洞的好方法,所以我直接扩张它们.如图3所示,孔似乎扩大得太多,其他噪音也是如此.我的第二个问题是如何填充或扩大孔,以使它们以相同/相似的尺寸填充圆圈?
图3扩张

第3步:找到并绘制每个点的质心.如图4所示,由于粗略图像处理,存在"环"的标记,并且一些点以两个白色像素示出.想要的结果应该只显示一个点的点和一个白色像素.
图4:质心

这是我的这3个步骤的代码.任何人都可以帮助我的工作做得更好吗?
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
using namespace std;
using namespace cv;
// Global variables
Mat src, edge, dilation;
int dilation_size = 2;
// Function header
void thresh_callback(int, void*);
int main(int argc, char* argv)
{
IplImage* img = cvLoadImage("c:\\dot1.bmp", 0); // dot1.bmp = Fig. 1
// Perform canny edge detection
cvCanny(img, img, 33, 100, 3);
// IplImage to Mat …Run Code Online (Sandbox Code Playgroud) 我正试图在我的图像中间检测到一个圆形物体.这是一个示例图像:

左半部分是灰度和高斯模糊输入图像; 在Otsu阈值处理后,右半部分是相同的图像.左下角的微小银色阴影导致Otsu门槛误入歧途.有没有办法设置一个感兴趣的圆形区域,以避免角落噪音?