opencv找到凹壳 [英] opencv find concave hull

查看:1203
本文介绍了opencv找到凹壳的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在图像中显示了一组离散点,如下面的

I have a set of discrete points shown in an image, like the following

我想重建或提升采样(我不确定描述它的正确方法)图像,以便结果图像如下所示< img src =https://i.stack.imgur.com/BMCfc.jpgalt =后加工面具>。它不需要与示例图像完全相同,但主要思想是填充原始图像。

I want to reconstruct or up sampling (I'm not sure what's the correct way to describe it) the image, so that the result image would be like the following. It doesn't need to be exactly the same as the example image, but the main idea is to fill up the original one.

我对如何进行初步了解做到这一点。但是在第一步之后我不知道怎么做。我的想法是首先使用kmeans分离图像并找出不同的对象。我成功地完成了它。 kmeans之后生成的图像是: 。

I have an initial idea about how to do it. But I don't know how to do it after the first step. My idea is to first separate image using kmeans and find out the different objects. And I have successfully done it. The resulting images after kmeans are: .

在kmeans之后,我想使用find contour或类似凹形的东西来获得这些形状的轮廓并使用填充孔等功能填充形状。但是,我发现查找轮廓不起作用,它会将每个单个像素视为轮廓。

After kmeans, I want to use find contour or something like concave to get the outline of these shapes and fill the shape using functions like fill holes. However, I found "find contour" does not work, it will consider each single pixel as a contour.

我想的另一种方法是使用插值。但是我不确定它是否有可能存在如此稀疏的分数。有没有人对如何做到这一点有任何想法?我不确定我是否采用正确的方式而且我愿意接受任何解决方案。

The other way I'm thinking is to use interpolation. But I'm not sure whether it is possible with so sparse points. Does anyone have any ideas about how to do this? I'm not sure whether I'm on the right way and I'm open to any solutions.

非常感谢!

推荐答案

看一下形态变换。我将从使用大内核的扩张操作开始,比如尺寸为(15,15)的MORPH_ELLIPSE。然后,使用相同大小的内核使用侵蚀操作将blob减薄。请查看此处的文档。请注意,OpenCV也提供链式或顺序形态操作。请参见此处。然后你会看到我的建议是关闭操作。

Take a look at the morphological transformations. I would start with a dilation operation using a large kernel, say the MORPH_ELLIPSE with a size(15,15). Afterwards, thin the blobs back down using the erosion operation with the same size kernel. Take a look at the docs here. Note that OpenCV offers chained, or sequenced, morphological operations, too. See here. You'll then see that my suggestion is a "closing" operation.

更新:
我尝试使用简单的扩张和轮廓来产生图像中显示的结果。结果似乎满足了问题的一般要求。

Update: I experimented with simple dilation and contouring to yield the results shown in the image. The results appear to satisfy the general requirements of the problem.

同样,没有指定应用程序的实时含义,但这组操作可能很快已执行并可轻松应用于30fps应用程序。

Likewise, what "realtime" means for the application isn't specified, but this set of operations may be quickly executed and could easily be applied to a 30fps application.

以下代码段落:

// Convert image to grayscale
cvtColor(src, gray, CV_BGR2GRAY);
threshold(gray, gray, 128.0, 128.0, THRESH_BINARY);

// Dilate to fill holes
dilate(gray, dest, getStructuringElement(MORPH_ELLIPSE, Size(13,13)));

// Find contours
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(dest, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0,0)); 

  // Prune contours
  float maxArea = 0.0f;
  for (size_t i = 0; i< contours.size(); i++)
     {
       if (contourArea(contours[i]) >= maxArea)
         {
            maxArea = contourArea(contours[i]);
         }
     } 

  float minArea = 0.20f * maxArea;
  vector<vector<Point> > prunedContours;
  for (size_t i = 0; i< contours.size(); i++)
     {
       if (contourArea(contours[i]) >= minArea)
         {
           prunedContours.push_back(contours[i]);
         }
     }

// Smooth the contours
vector<vector<Point> > smoothedContours;
  smoothedContours.resize(prunedContours.size());
  for (size_t i=0;i<prunedContours.size();i++)
    {
    vector<float> x;
    vector<float> y;

    const size_t n = prunedContours[i].size();

    for (size_t j=0;j<n;j++)
      {
        x.push_back(prunedContours[i][j].x);
        y.push_back(prunedContours[i][j].y);
      }

    Mat G;
    transpose(getGaussianKernel(11,4.0,CV_32FC1),G);

    vector<float> xSmooth;
    vector<float> ySmooth;

    filter2D(x,xSmooth, CV_32FC1, G);
    filter2D(y,ySmooth, CV_32FC1, G);

    for (size_t j=0;j<n;j++)
      {
        smoothedContours[i].push_back(Point2f(xSmooth[j],ySmooth[j]));
      }
    }

这篇关于opencv找到凹壳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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