gpt4 book ai didi

c++ - 在 OpenCV 中查找轮廓的 "fitLine "

转载 作者:可可西里 更新时间:2023-11-01 16:37:35 26 4
gpt4 key购买 nike

我是一个在流中查找轮廓的程序,例如:

contours

我想找到可以描述这个轮廓的“点集”,就像红线一样:

enter image description here

黄色部分是轮廓的时刻,

我尝试使用 opencv 的 fitLine 函数,但结果是胡说八道,任何想法我怎样才能得到轮廓的中间线,这应该代表我的 Contours 的关键方面。顺便说一下 **我不是要密码! ** 只是提示我该怎么做?

在此先感谢您的帮助

最佳答案

也许可以通过距离变换和脊检测来尝试这种方法:

cv::Mat input = cv::imread("fitLine.jpg");
cv::Mat gray;
cv::cvtColor(input,gray,CV_BGR2GRAY);

cv::Mat mask = gray>100;
cv::imshow("mask",mask);

cv::Mat dt;
cv::distanceTransform(mask,dt,CV_DIST_L1,CV_DIST_MASK_PRECISE);

cv::imshow("dt", dt/15.0f);
cv::imwrite("fitLineOut.png",255*dt/15.0f);


//care: this part doesn't work for diagonal lines, a ridge detection would be better!!
cv::Mat lines = cv::Mat::zeros(input.rows, input.cols, CV_8UC1);
//only take the maxDist of each row
for(unsigned int y=0; y<dt.rows; ++y)
{
float biggestDist = 0;
cv::Point2i biggestDistLoc(0,0);
for(unsigned int x=0; x<dt.cols; ++x)
{
cv::Point2i current(x,y);
if(dt.at<float>(current) > biggestDist)
{
biggestDist = dt.at<float>(current) ;
biggestDistLoc = current;

}
}
lines.at<unsigned char>(biggestDistLoc) = 255;
}

//and the maxDist of each row
for(unsigned int x=0; x<dt.cols; ++x)
{
float biggestDist = 0;
cv::Point2i biggestDistLoc(0,0);
for(unsigned int y=0; y<dt.rows; ++y)
{
cv::Point2i current(x,y);
if(dt.at<float>(current) > biggestDist)
{
biggestDist = dt.at<float>(current) ;
biggestDistLoc = current;

}
}
lines.at<unsigned char>(biggestDistLoc) = 255;
}

cv::imshow("max", lines);


cv::waitKey(-1);

想法是计算距离变换并找到轮廓内的脊线。

这是距离变换图像的样子: enter image description here您可以看到线条中间有一个局部脊最大值。

然后我使用一个非常简单的方法:只需要找到每行/列中的最大距离即可。这是非常草率的,应该更改为真正的脊检测或细化方法!!!!

enter image description here

编辑:补充说明:

想法是找到轮廓“中间”的所有点。在数学/图形中,物体某种“中间”的中轴及其定义是同时与至少两个轮廓点具有相同最小距离的所有点。

近似中轴的一种方法是计算距离变换。距离变换是一个矩阵,它为每个像素保存到下一个对象点(例如对象的轮廓)的距离(也参见http://en.wikipedia.org/wiki/Distance_transform)。那是第一张图片。在那里你可以看到线中间的点比靠近边界的点亮一点,这意味着沿着线的最亮点可以解释为中轴(近似值),因为如果你移动远离它(与线方向正交)距离变小,所以峰值是到两个边界的距离接近相等的点。

这样,如果您可以在距离变换中找到那些“脊”,您就完成了。脊检测通常由 Harris 算子完成(参见 http://en.wikipedia.org/wiki/Ridge_detection)。

在我发布的快速而肮脏的版本中,我尝试通过仅接受每行中的最大值来检测脊线。这对大多数水平和垂直的山脊来说是可以的,但对角线山脊会失败。所以也许您真的想用真正的 山脊检测交换for循环

关于c++ - 在 OpenCV 中查找轮廓的 "fitLine ",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21675509/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com