opencv找到凹壳

use*_*417 6 interpolation opencv concave image-processing contour

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

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

我对如何做到这一点有了初步的想法.但是在第一步之后我不知道怎么做.我的想法是首先使用kmeans分离图像并找出不同的对象.我成功地完成了它.kmeans之后得到的图像是:对象1面具 对象2对象3面具.

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

我想的另一种方法是使用插值.但是我不确定它是否有可能存在如此稀疏的分数.有没有人对如何做到这一点有任何想法?我不确定我是否走在正确的道路上,我对任何解决方案持开放态度.

非常感谢!

Thr*_*986 6

看看形态的转变。我将从使用大内核的膨胀操作开始,例如大小为 (15,15) 的 MORPH_ELLIPSE。然后,使用相同大小的内核进行腐蚀操作,将斑点变薄。请查看此处的文档。请注意,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]));
      }
    }
Run Code Online (Sandbox Code Playgroud)