也許你可以使用某種平均濾波器來近似曲線,然後使用帶有小梯度的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'看看你如何得到更好的結果。
你有什麼輪廓問題?你想更平滑他們? – Adrian
@AdrianPopovici:那種,我希望他們能夠從我的物體上結合曲線,而不必擁有所有的人工製品。這裏是原始圖片:http://imageshack.us/photo/my-images/15/ex5gl.jpg/ – Turgal
在找到輪廓之前,您可以在B&W圖像上運行一些濾鏡,例如高斯濾鏡,然後設置閾值,這可以使輪廓平滑一些,但可能並不適合所有點的確切對象。您可以使用輪廓線做的另一件事是使用AproxPoly,然後應用樣條線或其他東西。 – Adrian