Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opencv MINARECT角度-不确定返回的角度_Opencv_Angle - Fatal编程技术网

Opencv MINARECT角度-不确定返回的角度

Opencv MINARECT角度-不确定返回的角度,opencv,angle,Opencv,Angle,从Minareact的功能来看,其返回角度是否在0-360度范围内? 我不确定,因为我有一个面向90度左右的对象,但我一直得到-1或-15度。这可能是openCV错误吗 非常感谢您的指导 谢谢我假设你使用C++,但是如果你使用C或Python,答案应该是相同的。 函数minareact给出的角度范围为-90到0度,不包括零,因此间隔为[-90,0] 如果输出的矩形未旋转,则函数给出-90度,即矩形的两个边完全水平,两个边完全垂直。当矩形顺时针旋转时,角度增加(朝零方向)。当达到零时,函数给出的角

从Minareact的功能来看,其返回角度是否在0-360度范围内? 我不确定,因为我有一个面向90度左右的对象,但我一直得到-1或-15度。这可能是openCV错误吗

非常感谢您的指导


谢谢

我假设你使用C++,但是如果你使用C或Python,答案应该是相同的。 函数
minareact
给出的角度范围为-90到0度,不包括零,因此间隔为[-90,0]

如果输出的矩形未旋转,则函数给出-90度,即矩形的两个边完全水平,两个边完全垂直。当矩形顺时针旋转时,角度增加(朝零方向)。当达到零时,函数给出的角度再次变回-90度

因此,如果从
minarealect
得到一个长矩形,并且它是平放的,
minarealect
将调用角度-90度。如果旋转图像直到
minarealect
给出的矩形完全竖直,则角度将再次显示为-90度

事实上,我对此一无所知(我拖延了OpenCV项目来了解它是如何工作的:/)。无论如何,这里有一个OpenCV程序,它演示了
minareact
,如果我还没有解释清楚的话:

#include <stdio.h>

#include <opencv\cv.h>
#include <opencv\highgui.h>

using namespace cv;

int main() {
    float angle = 0;
    Mat image(200, 400, CV_8UC3, Scalar(0));
    RotatedRect originalRect;
    Point2f vertices[4];
    vector<Point2f> vertVect;
    RotatedRect calculatedRect;

    while (waitKey(5000) != 27) {
        // Create a rectangle, rotating it by 10 degrees more each time.
        originalRect = RotatedRect(Point2f(100,100), Size2f(100,50), angle);

        // Convert the rectangle to a vector of points for minAreaRect to use.
        // Also move the points to the right, so that the two rectangles aren't
        // in the same place.
        originalRect.points(vertices);
        for (int i = 0; i < 4; i++) {
            vertVect.push_back(vertices[i] + Point2f(200, 0));
        }

        // Get minAreaRect to find a rectangle that encloses the points. This
        // should have the exact same orientation as our original rectangle.
        calculatedRect = minAreaRect(vertVect);

        // Draw the original rectangle, and the one given by minAreaRect.
        for (int i = 0; i < 4; i++) {
            line(image, vertices[i], vertices[(i+1)%4], Scalar(0, 255, 0));
            line(image, vertVect[i], vertVect[(i+1)%4], Scalar(255, 0, 0));
        }
        imshow("rectangles", image);

        // Print the angle values.
        printf("---\n");
        printf("Original angle:             %7.2f\n", angle);
        printf("Angle given by minAreaRect: %7.2f\n", calculatedRect.angle);
        printf("---\n");

        // Reset everything for the next frame.
        image = Mat(200, 400, CV_8UC3, Scalar(0));
        vertVect.clear();
        angle+=10;
    }

    return 0;
}
#包括
#包括
#包括
使用名称空间cv;
int main(){
浮动角度=0;
Mat图像(200400,CV_8UC3,标量(0));
旋转直线原直线;
点2f顶点[4];
向量向量;
旋转体计算体;
while(waitKey(5000)!=27){
//创建一个矩形,每次再旋转10度。
原始直线=旋转直线(点2F(100100),尺寸2F(100,50),角度);
//将矩形转换为要使用的点向量。
//同时将点向右移动,使两个矩形不相互重叠
//在同一个地方。
原始直点(顶点);
对于(int i=0;i<4;i++){
顶点向后推(顶点[i]+Point2f(200,0));
}
//让minareact找到一个包围这些点的矩形
//应具有与原始矩形完全相同的方向。
calculatedRect=MinareRect(垂直向量);
//绘制原始矩形,以及Minareact给出的矩形。
对于(int i=0;i<4;i++){
线(图像,顶点[i],顶点[(i+1)%4],标量(0,255,0));
线(图像,垂直向量[i],垂直向量[(i+1)%4],标量(255,0,0));
}
imshow(“矩形”,图像);
//打印角度值。
printf(“--\n”);
printf(“原始角度:%7.2f\n”,角度);
printf(“minareact给出的角度:%7.2f\n”,calculatedRect.Angle);
printf(“--\n”);
//为下一帧重置所有内容。
image=Mat(200400,CV_8UC3,标量(0));
vertVect.clear();
角度+=10;
}
返回0;
}

这可以让您轻松看到手动绘制的矩形的角度和形状与同一矩形的
minareact
解释相比如何。

改进@Adam Goodwin的答案我想添加我的小代码,稍微改变一下行为:

我想得到较长边和垂直边之间的角度(对我来说,这是考虑旋转矩形最自然的方式):

如果需要相同的代码,只需使用以下代码:

void printAngle(RotatedRect calculatedRect){
    if(calculatedRect.size.width < calculatedRect.size.height){
        printf("Angle along longer side: %7.2f\n", calculatedRect.angle+180);
    }else{
        printf("Angle along longer side: %7.2f\n", calculatedRect.angle+90);
    }
}

经过实验,我发现如果长边在底点的左侧,角度值在长边和Y+轴之间,但是如果长边在底点的右侧,角度值在长边和X+轴之间。 因此,我使用如下代码(java):

rect=Imgproc.minareact(mop2f);

if(rect.size.width经过大量实验,我发现矩形方向与
minareact()
的输出角度之间的关系可以总结在下图中

下面的描述假设我们有一个高度和宽度长度不等的矩形,即它不是正方形

如果矩形垂直放置(宽度<高度),则检测角度为-90度。如果矩形水平放置,则检测角度也为-90度

如果矩形的顶部位于第一象限,则随着矩形从水平位置旋转到垂直位置,检测角度减小,直到检测角度变为-90度。在第一象限,检测矩形的宽度大于其高度

如果检测到的矩形的顶部位于第二象限,则角度随着矩形从垂直位置旋转到水平位置而减小。但第二象限和第一象限之间存在差异。如果矩形接近垂直位置但未处于垂直位置,则其角度接近0。如果矩形接近水平位置但未处于水平位置,其角度接近-90度


这篇文章也很好地解释了这一点。

老兄,你真是一颗珍宝。谢谢:)没问题:)OpenCV的文档似乎遗漏了很多重要的细节。还有一个问题,如果rotatedrect只提供了-90,-1之间的角度,我怎么能从它得到0-360度的变换?是的,OpenCV在文档方面可能更好当你深入研究代码或它们的示例时。好吧,OpenCV不可能做到这一点ut本身。很难说不知道你在做什么,但我会采取的方法是在你的对象上获得一个朝向一侧的特征点。然后,当你从
minareact
获得矩形时,你可以看到该点在矩形中的位置,并用它来计算出你的ob的方向
printf("Angle given by minAreaRect: %7.2f\n", calculatedRect.angle);
printAngle(calculatedRect);
printf("---\n");
       rRect = Imgproc.minAreaRect(mop2f);
       if(rRect.size.width<rRect.size.height){
            angle = 90 -rRect.angle;
        }else{
            angle = -rRect.angle;
        }