如何增加轮廓precision? [英] How to increase contours precision?

查看:111
本文介绍了如何增加轮廓precision?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用OpenCV的项目。我需要precisely裁剪掉从高清组图一些对象。
我使用的是四棵树把我的照片片,然后我计算每个四边形的同质性,以确定是否一块的对象是四。
我申请了一些过滤器作为康力与取决于四的同质性不同的阈值。
我希望这说明是可以理解的。

I am working on a project using OpenCV. I need to precisely crop out some objects from HD photos. I'm using a quad tree to cut my photos in pieces and then I calculate the homogeneity of each quad to determine if a piece of the object is in the quad. I apply some filters as Canny with different thresholds depending on the homogeneity of the quad. I hope this description is understandable.

本算法适用于特定类型的对象,但我坚持了一些人。
在这里,我的问题的一些例子:我想办法打平我的轮廓。
第一张截图用精明的过滤器和一个后此时,floodFill是。第二是最终的结果,面具

This algorithm works for certain kinds of objects but I'm stuck with some others. Here some example of my problems: I would like a way to flatten my contours. The first screenshot is a after using the canny filter and a floodfill. The second is the final mask result.

http://pastebin.com/91Pgrd2D

要实现这一结果,我用 cvFindContours()所以我的轮廓,但我不能找到一种方法来处理它们像我想要的。

To achieve this result, I use cvFindContours() so I have the contours but I can't find a way to handle them like I want.

推荐答案

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

Maybe you could use some kind of an average filter to approximate the curve and then use AproxPoly with a small gradient to smooth it. Here is a similar method:

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

您给它的外形和你想做的平均点的缓冲区的大小。
如果你认为轮廓太厚因为一些平均点的捆绑在一起太近,那么这就是Aproxpoly进来,因为它减少的点的数量。
但选择适当的梯度,这样你就不能让它太毛躁。

You give it the contour and the size of the buffer of points that you want to do the average on. If you think the contour is too thick because some of the averaged points are bundled together too close, then that's where Aproxpoly comes in because it reduces the number of points. But choose an appropriate gradient so you don't make it too edgy.

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

玩弄'X'就看你怎么得到更好的结果。

Play around with 'x' to see how you get better results.

这篇关于如何增加轮廓precision?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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