基本上,我有一个包含对象的二进制图像,我应用了轮廓和矩函数来查找质心,并检测此图像中的对象。 (不规则物体)
我现在要做的是生成穿过质心,到轮廓边缘的线(以不同的角度),找出最长的线。
有关此事的任何帮助将不胜感激。
答案 0 :(得分:1)
假设线条从质心绘制到质量的周边,而不是使用测试角度,只需使用轮廓点本身并对每组点进行距离计算。见下面的例子。 (示例代码是用C ++编写的,问题标签是java,有一天我会被烧掉。)
Mat GrayImage; // input grayscale image, set to something
Mat ContourImage;
Mat DrawImage = Mat::zeros(GrayImage.size(), CV_8UC3);
int thresh = 90;
// get a threshold image using Canny edge detector
Canny(GrayImage, ContourImage, thresh, thresh * 2, 3);
vector< vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(ContourImage, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);// retrieves external contours, CHANGES THRESHOLD IMAGE
vector<Point2f> centerofMass(contours.size());
vector<Moments> mu(contours.size());
// for every contour in the image
for (int i = 0; i < contours.size(); i++)
{
// draw the contour
drawContours(DrawImage, contours, i, Scalar(200, 54, 120), 2, 8, hierarchy, 0, Point());
//calculate center of mass
mu[i] = moments(contours[i],false);
centerofMass[i] = Point2f(mu[i].m10 / mu[i].m00, mu[i].m01 / mu[i].m00);
double biggestDistance = 0;
Point2f farthest_Perimeter_Point;
// for each point in the current contour
for (int j = 0; j < contours[i].size(); j++)
{
// get a point that makes up the contour
Point2f perimeterofMass(contours[i][j].x, contours[i][j].y);
//calculate the distance
double dist = cv::norm(centerofMass[i] - perimeterofMass);
// determine farthest point
if (dist > biggestDistance)
{
biggestDistance = dist;
farthest_Perimeter_Point = perimeterofMass;
}
}
// now we have farthest point as farthest_Perimeter_Point for the current contour at [i]
//draw the line because why not;
line(DrawImage, centerofMass[i], farthest_Perimeter_Point, Scalar(145, 123, 201));
}
imshow("grayimage", GrayImage);
imshow("thresholdimage", ContourImage);
imshow("drawimage", DrawImage);
另一个假设是线条从质量周边的一个起点到质量的另一侧绘制,同时与中心相交。首先从周长的一个点开始,使用起点和中心点在point-intercept form中形成线方程。第二个找到此线与另一侧相交的位置,现在您可以计算距离。第三,确定这些线之间的最大距离。
参考文献: