opencv - 二值图像方向

标签 opencv computer-vision

我试图找到二值图像的方向(其中方向定义为最小惯性矩轴,即最小面积二次矩)。我正在使用霍恩博士 (MIT) 关于机器人视觉的书 which can be found here作为引用。

使用 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);
}

OpenCV 计算围绕原点 (0,0) 的二阶矩,所以我必须使用 Parallel Axis Theorem将轴移动到形状的中心,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);

但是当我尝试使用这个函数绘制具有最低惯性矩的轴时,它看起来完全错误:

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); 

下面是一些输入和输出的例子:

enter image description here enter image description here

(我希望它是垂直的)

enter image description here enter image description here

(我希望它是水平的)

最佳答案

我有时会处理方向并编写以下代码。它返回对象的确切方向。 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 );
                    }
                }

关于opencv - 二值图像方向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14720722/

相关文章:

python - 对 opencv 直播流应用多重效果

deep-learning - 为拥抱脸 (HF) ViT 模型创建特征提取器的正确方法是什么?

opencv - 导入错误 : No module named 'cv2' using jupyter

python - Opencv 视频捕获的永久修复

android - 如何查找包含特定图像/ Logo 的图像

python - 如何从 Pytorch 中的单个图像中提取特征向量?

python - 为什么对于 Keras 中的 Theano 和 Tensorflow 后端,一对图像之间的 L2 距离会得到不同的结果?

c++ - 从特征匹配/单应性中过滤误报 – OpenCV

python - 如何使用 OpenCV 和 Python 提取最大连通分量?

c++ - BackgroundSubtractorMOG2,我可以从中保存图像吗?从 BackgroundSubtractorMOG2 保存图像时出现错误