非连接形态滤波器 [英] Non connecting morphological filter

查看:210
本文介绍了非连接形态滤波器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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





我要增强蒙版的边框并使它们更加平滑。为此,我使用OPEN形态滤波器具有相当大的圆内核,它工作得很好,直到分段对象之间的距离是足够的。但在很多样品对象粘在一起。是否存在一些或多或少的简单方法来平滑这种图像而不改变其形态?



解决方案

不首先应用形态滤波器,可以尝试检测图像的外部轮廓。现在,您可以将这些外部轮廓绘制为填充轮廓,然后应用您的形态过滤器。这工作,因为现在你没有任何洞要填。



另一种方法:




  • 找到外部轮廓

  • 取轮廓点的坐标的x,y。您可以将这些视为1-D信号,并对这些信号应用平滑滤波器。



在下面的代码中,



p>

没有任何平滑的外部轮廓





在对x和y 1-D信号应用高斯滤波器之后





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);

//高斯滤波器的轮廓平滑参数
int filterRadius = 5;
int filterSize = 2 * filterRadius + 1;
double sigma = 10;

vector< vector< Point> >轮廓;
vector< Vec4i>层次;
//找到外部轮廓并存储所有轮廓点
findContours(cont,contour,hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE,Point(0,0));
for(size_t j = 0; j {
//绘制初始轮廓形状
drawContours(original,contour, Scalar(0,255,0),1);
//提取点的x和y坐标。我们将这些视为1-D信号
//向1-D信号添加循环填充
size_t len = contoururs [j] .size()+ 2 * filterRadius;
size_t idx =(contoururs [j] .size() - filterRadius);
vector< float> x,y;
for(size_t i = 0; i {
x.push_back(contoururs [j] [(idx + i)%contoururs [j] .size ]。X);
y.push_back(contoururs [j] [(idx + i)%contoururs [j] .size()]。
}
//过滤器1-D信号
矢量< float> xFilt,yFilt;
GaussianBlur(x,xFilt,Size(filterSize,filterSize),sigma,sigma);
GaussianBlur(y,yFilt,Size(filterSize,filterSize),sigma,sigma);
//构建平滑轮廓
矢量<矢量<点> > smoothContours;
vector< Point>光滑;
for(size_t i = filterRadius; i< contoururs [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<< 调试轮廓< j<< :<< contours [j] .size()<< ,< smooth.size()<< endl;
}


After some simple preprocessing I am receiving boolean mask of segmented images.

I want to "enhance" borders of the mask and make them more smooth. For that I am using OPEN morphology filter with a rather big circle kernel , it works very well until the distance between segmented objects is enough. But In alot of samples objects stick together. Is there exists some more or less simple method to smooth such kind of images without changing its morphology ?

解决方案

Without applying a morphological filter first, you can try to detect the external contours of the image. Now you can draw these external contours as filled contours and then apply your morphological filter. This works because now you don't have any holes to fill. This is fairly simple.

Another approach:

  • find external contours
  • take the x, y of coordinates of the contour points. you can consider these as 1-D signals and apply a smoothing filter to these signals

In the code below, I've applied the second approach to a sample image.

Input image

External contours without any smoothing

After applying a Gaussian filter to x and y 1-D signals

C++ code

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;
}

这篇关于非连接形态滤波器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆