Jas*_*son 9 opencv computer-vision
我试图找到二进制图像的方向(其中方向被定义为最小惯性矩的轴,即最小的第二矩区域).我正在使用霍恩博士的书籍(MIT)进行机器人视觉,这可以在这里找到参考.
使用OpenCV,这是我的函数,其中a,b和c是上面pdf第15页上找到的区域的第二个矩(文本的第60页):
Point3d findCenterAndOrientation(const Mat& src)
{
Moments m = cv::moments(src, true);
double cen_x = m.m10/m.m00; //Centers are right
double cen_y = m.m01/m.m00;
double a = m.m20-m.m00*cen_x*cen_x;
double b = 2*m.m11-m.m00*(cen_x*cen_x+cen_y*cen_y);
double c = m.m02-m.m00*cen_y*cen_y;
double theta = a==c?0:atan2(b, a-c)/2.0;
return Point3d(cen_x, cen_y, theta);
}
Run Code Online (Sandbox Code Playgroud)
OpenCV计算原点周围的第二个矩(0,0),因此我必须使用平行轴定理将轴移动到形状的中心,mr ^ 2.
我打电话时,中心看起来正确
Point3d p = findCenterAndOrientation(src);
rectangle(src, Point(p.x-1,p.y-1), Point(p.x+1, p.y+1), Scalar(0.25), 1);
Run Code Online (Sandbox Code Playgroud)
但是当我尝试用最小转动惯量绘制轴时,使用此功能,它看起来完全错误:
line(src, (Point(p.x,p.y)-Point(100*cos(p.z), 100*sin(p.z))), (Point(p.x, p.y)+Point(100*cos(p.z), 100*sin(p.z))), Scalar(0.5), 1);
Run Code Online (Sandbox Code Playgroud)
以下是输入和输出的一些示例:

(我希望它是垂直的)

(我希望它是水平的)
我曾经有过这种方向的工作,并编写了以下内容.它返回了对象的确切方向.largest_contour是检测到的形状.
CvMoments moments1,cenmoments1;
double M00, M01, M10;
cvMoments(largest_contour,&moments1);
M00 = cvGetSpatialMoment(&moments1,0,0);
M10 = cvGetSpatialMoment(&moments1,1,0);
M01 = cvGetSpatialMoment(&moments1,0,1);
posX_Yellow = (int)(M10/M00);
posY_Yellow = (int)(M01/M00);
double theta = 0.5 * atan(
(2 * cvGetCentralMoment(&moments1, 1, 1)) /
(cvGetCentralMoment(&moments1, 2, 0) - cvGetCentralMoment(&moments1, 0, 2)));
theta = (theta / PI) * 180;
// fit an ellipse (and draw it)
if (largest_contour->total >= 6) // can only do an ellipse fit
// if we have > 6 points
{
CvBox2D box = cvFitEllipse2(largest_contour);
if ((box.size.width < imgYellowThresh->width) && (box.size.height < imgYellowThresh->height))
{
cvEllipseBox(imgYellowThresh, box, CV_RGB(255, 255 ,255), 3, 8, 0 );
}
}
Run Code Online (Sandbox Code Playgroud)