7

我在图像中显示了一组离散点,如下所示 离散掩模

我想重建或上采样(我不确定描述它的正确方法是什么)图像,以便结果图像如下所示后处理面膜。它不需要与示例图像完全相同,但主要思想是填充原始图像。

我对如何做有一个初步的想法。但是我不知道第一步之后该怎么做。我的想法是首先使用 kmeans 分离图像并找出不同的对象。我已经成功地做到了。kmeans 之后的结果图像是对象 1 蒙版 对象 2对象 3 掩码

在 kmeans 之后,我想使用 find contour 或类似 concave 的方法来获取这些形状的轮廓,并使用诸如填充孔之类的功能来填充形状。但是,我发现“查找轮廓”不起作用,它会将每个单个像素视为一个轮廓。

我在想的另一种方法是使用插值。但我不确定如此稀疏的点是否可行。有人对如何做到这一点有任何想法吗?我不确定我是否走在正确的道路上,我愿意接受任何解决方案。

非常感谢!

4

1 回答 1

4

看一下形态变换。我将从使用大内核的膨胀操作开始,例如大小为 (15,15) 的 MORPH_ELLIPSE。之后,使用具有相同大小内核的腐蚀操作将 blob 变薄。看看这里的文档。请注意,OpenCV 也提供链式或序列化的形态学操作。见这里。然后你会看到我的建议是“关闭”操作。

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

同样,没有指定应用程序的“实时”意味着什么,但是这组操作可以快速执行并且可以很容易地应用于 30fps 应用程序。 轮廓图像

下面的代码片段:

// 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]));
      }
    }
于 2015-04-06T18:38:54.357 回答