我正在使用OpenCV开发一个项目。我需要从高清照片中精确裁剪出一些物体。 我正在使用四叉树将我的照片切成碎片,然后我计算每个四边形的均匀性,以确定一块物体是否在四边形中。 我根据四元组的同质性应用一些具有不同阈值的Canny过滤器。 我希望这种描述是可以理解的。
此算法适用于某些类型的对象,但我遇到了其他一些对象。 这里有一些我的问题的例子:我想要一种平整我的轮廓的方法。 第一个屏幕截图是在使用canny过滤器和floodfill之后。第二个是最终的掩码结果。
为了实现这个结果,我使用cvFindContours()
所以我有轮廓但我找不到像我想要的那样处理它们的方法。
答案 0 :(得分:5)
也许您可以使用某种平均滤波器来近似曲线,然后使用带有小渐变的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;
}
}
您可以为其提供要进行平均值的轮廓和点缓冲区的大小。 如果您认为轮廓太厚,因为某些平均点被捆绑在一起太近,那么这就是Aproxpoly进来的地方,因为它减少了点数。 但是选择一个合适的渐变,这样就不会让它过于前卫。
srcSeq = cvApproxPoly(srcSeq,sizeof(CvContour),storage, CV_POLY_APPROX_DP, x, 1);
使用'x'来看看你如何获得更好的结果。