如何提高轮廓精度

How to increase contours precision?

本文关键字:精度 轮廓 何提高      更新时间:2023-10-16

我正在做一个使用OpenCV的项目。我需要精确地从高清照片中裁剪出一些物体。我用四叉树把我的照片切成碎片然后我计算每个四叉树的均匀性来确定物体的一部分是否在四叉树中。我应用一些过滤器作为Canny与不同的阈值取决于四元的均匀性。我希望这个描述是可以理解的。

这个算法适用于某些类型的对象,但我对其他一些对象感到困惑。这里有一些我的问题的例子:我想要一种方法来平坦我的轮廓。第一张截图是使用精明的过滤器和洪水填充后的图片。第二个是最终的掩码结果。

http://pastebin.com/91Pgrd2D


为了达到这个结果,我使用cvFindContours(),所以我有轮廓,但我找不到一种方法来处理它们,就像我想要的。

也许你可以使用某种平均过滤器来近似曲线,然后使用具有小梯度的AproxPoly来平滑它。下面是一个类似的方法:

void AverageFilter(CvSeq * contour, int buff_length)
{
    int n = contour->total, i, j;
    if (n > buff_length)
    {
        CvPoint2D32f* pnt;
        float* sampleX = new float[buff_length];
        float* sampleY = new float[buff_length];
        pnt = (CvPoint2D32f*)cvGetSeqElem(contour, 0);
        for (i = 0; i < buff_length; i++)
        {
            if (i >= buff_length / 2)
            {
                pnt = (CvPoint2D32f*)cvGetSeqElem(contour, i + 1 - buff_length / 2 );
            }
            sampleX[i] = pnt->x;
            sampleY[i] = pnt->y;
        }
        float sumX = 0, sumY = 0;
        for (i = 1; i < n; i++)
        {
            pnt = (CvPoint2D32f*)cvGetSeqElem(contour, i);
            for (j = 0; j < buff_length; j++)
            {
                sumX += sampleX[j];
                sumY += sampleY[j];
            }
            pnt->x = sumX / buff_length;
            pnt->y = sumY / buff_length;
            for (j = 0; j < buff_length - 1; j++)
                {
                    sampleX[j] = sampleX[j+1];
                    sampleY[j] = sampleY[j+1];
                }
            if (i <= (n - buff_length / 2))
            {
                pnt = (CvPoint2D32f*)cvGetSeqElem(contour, i + buff_length / 2 + 1);
                sampleX[buff_length - 1] = pnt->x;
                sampleY[buff_length - 1] = pnt->y;
            }
            sumX = 0;
            sumY = 0;
        }
        delete[] sampleX;
        delete[] sampleY;
    }
} 

你给它轮廓和你想要做平均的点的缓冲区的大小。如果你认为轮廓太厚,因为一些平均点聚得太近,那么这就是近似聚法的用武之处,因为它减少了点的数量。但是要选择一个合适的渐变,这样你就不会让它太前卫了。

srcSeq = cvApproxPoly(srcSeq,sizeof(CvContour),storage, CV_POLY_APPROX_DP, x, 1);

使用'x'看看如何得到更好的结果。