Opencv 非连接形态滤波器

Opencv 非连接形态滤波器,opencv,image-processing,computer-vision,image-morphology,Opencv,Image Processing,Computer Vision,Image Morphology,经过一些简单的预处理,我收到分割图像的布尔掩码 我想“增强”面具的边缘,使其更加平滑。因为我使用的是一个很大的圆形内核的开放形态过滤器,它工作得非常好,直到分割对象之间的距离足够。但在很多样本中,物体粘在一起。是否存在某种或多或少简单的方法来平滑此类图像而不改变其形态 不能100%确定你想要实现什么,但这可能是一条探索的途径。。。工具potrace拍摄图像并将其转换为涉及平滑的矢量化图像。它更喜欢PGM格式化输入文件,所以我使用ImageMagick来准备它们。无论如何,下面是一个命令和结果的

经过一些简单的预处理,我收到分割图像的布尔掩码

我想“增强”面具的边缘,使其更加平滑。因为我使用的是一个很大的圆形内核的开放形态过滤器,它工作得非常好,直到分割对象之间的距离足够。但在很多样本中,物体粘在一起。是否存在某种或多或少简单的方法来平滑此类图像而不改变其形态


不能100%确定你想要实现什么,但这可能是一条探索的途径。。。工具
potrace
拍摄图像并将其转换为涉及平滑的矢量化图像。它更喜欢
PGM
格式化输入文件,所以我使用ImageMagick来准备它们。无论如何,下面是一个命令和结果的示例,看看您的想法:

convert disks.png pgm:- | potrace - -s -o out.svg


我已将生成的
SVG
文件转换为
PNG
,因此我可以将其上载到so。

无需首先应用形态学过滤器,您可以尝试检测图像的外部轮廓。现在,您可以将这些外部轮廓绘制为填充轮廓,然后应用形态学过滤器。这是有效的,因为现在你没有任何洞要填补。这相当简单

另一种方法:

  • 寻找外部轮廓
  • 取轮廓点坐标的x,y。你可以把这些看成是一维信号,并对这些信号应用平滑滤波器< /LI>
在下面的代码中,我将第二种方法应用于示例图像

输入图像

没有任何平滑的外部轮廓

对x和y一维信号应用高斯滤波器后

C++代码

Mat im = imread("4.png", 0);

Mat cont = im.clone();
Mat original = Mat::zeros(im.rows, im.cols, CV_8UC3);
Mat smoothed = Mat::zeros(im.rows, im.cols, CV_8UC3);

// contour smoothing parameters for gaussian filter
int filterRadius = 5;
int filterSize = 2 * filterRadius + 1;
double sigma = 10;      

vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
// find external contours and store all contour points
findContours(cont, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE, Point(0, 0));
for(size_t j = 0; j < contours.size(); j++)
{
    // draw the initial contour shape
    drawContours(original, contours, j, Scalar(0, 255, 0), 1);
    // extract x and y coordinates of points. we'll consider these as 1-D signals
    // add circular padding to 1-D signals
    size_t len = contours[j].size() + 2 * filterRadius;
    size_t idx = (contours[j].size() - filterRadius);
    vector<float> x, y;
    for (size_t i = 0; i < len; i++)
    {
        x.push_back(contours[j][(idx + i) % contours[j].size()].x);
        y.push_back(contours[j][(idx + i) % contours[j].size()].y);
    }
    // filter 1-D signals
    vector<float> xFilt, yFilt;
    GaussianBlur(x, xFilt, Size(filterSize, filterSize), sigma, sigma);
    GaussianBlur(y, yFilt, Size(filterSize, filterSize), sigma, sigma);
    // build smoothed contour
    vector<vector<Point> > smoothContours;
    vector<Point> smooth;
    for (size_t i = filterRadius; i < contours[j].size() + filterRadius; i++)
    {
        smooth.push_back(Point(xFilt[i], yFilt[i]));
    }
    smoothContours.push_back(smooth);

    drawContours(smoothed, smoothContours, 0, Scalar(255, 0, 0), 1);

    cout << "debug contour " << j << " : " << contours[j].size() << ", " << smooth.size() << endl;
}
matim=imread(“4.png”,0);
Mat cont=im.clone();
Mat original=Mat::零(im.rows、im.cols、CV_8UC3);
Mat平滑=Mat::零(im.rows、im.cols、CV_8UC3);
//高斯滤波器的轮廓平滑参数
int filteradius=5;
int filterSize=2*filterRadius+1;
双西格玛=10;
矢量等值线;
向量层次;
//查找外部轮廓并存储所有轮廓点
findContours(cont、等高线、层次、CV_RETR__外部、CV_CHAIN_近似、无、点(0,0));
对于(大小j=0;j