首页 > 编程语言 >OpenCV RotatedRect类中angle参数解析 C++

OpenCV RotatedRect类中angle参数解析 C++

时间:2024-06-10 20:04:38浏览次数:11  
标签:angle Point back C++ vPoints OpenCV push 255

0.前言
本文主要探讨RotatedRect类angle的实际含义,为后续学者提供一定的参考。

1.官方手册
RotatedRect其一构造函数如下图(图1-1)所示。


在OpenCV图形坐标系中,水平方向向右为x轴正方向,垂直方向向下为y轴正方向,左上角为(0,0)点。
center表示矩形的中心坐标,size中包含了矩形的宽度和高度,angle是矩形顺时针方向的旋转角度。
图片来源地址:https://docs.opencv.org/4.6.0/db/dd6/classcv_1_1RotatedRect.html#aba20dfc8444fff72bd820b616f0297ee

2.angle含义探讨
笔者在学习该参数时参考了一些网络文献,在实际测试时发现实验结果与参考的文献结论有冲突,所以自行做了实验去探究angle的实际含义。

2.1实验设计
笔者从网络上文献中摘取了一幅图像,该图像如下(图2-1)所示。


图片来源连接:https://blog.csdn.net/mailzst1/article/details/83141632
对于图2-1,笔者做出了一些变动,将图2-1缩放到水平为400像素,保持原图像比例不变。得到四个矩阵角点坐标如下所示。

矩阵(1) 矩阵(2) 矩阵(3) 矩阵(4)
Point(43, 30) Point(233, 84) Point(100, 217) Point(264, 222)
Point(129, 30) Point(227, 39) Point(57, 205) Point(225, 145)
Point(129, 77) Point(312, 25) Point(81, 122) Point(265, 125)
Point(43, 77) Point(319, 70) Point(124, 135) Point(305, 201)

使用如下代码运行测试,从中发现规律。

点击查看代码
Mat mSrcImage(400, 400, CV_8UC3, Scalar(0, 0, 0));
int iTypeVal = 0;
vector<Point> vPoints;
void onTypeChange(int, void*)
{
	Mat mResult;
	mSrcImage.copyTo(mResult);
	if (iTypeVal == 0)//boundingRectO函数
	{
		Rect rRes=boundingRect(vPoints);
		rectangle(mResult, rRes, Scalar(0, 0, 255), 1);
	}
	else if (iTypeVal==1)//minAreaRectO函数
	{
		RotatedRect rrRes = minAreaRect(vPoints);
		Point2f pPoint[4];
		rrRes.points(pPoint);
		for (short a = 0; a < 4; ++a)
		{
			line(mResult, pPoint[a], pPoint[(a + 1) % 4], Scalar(0, 0, 255), 1);
		}
		cout << rrRes.center << "," << rrRes.angle << endl;
	}
	else if (iTypeVal == 2)//minEnclosingCircJeO函数
	{
		Point2f pCenter;
		float fR;
		minEnclosingCircle(vPoints, pCenter, fR);
		circle(mResult, pCenter, fR, Scalar(0, 0, 255), 1);
	}
	else if (iTypeVal == 3)//fitEllipseO函数
	{
		RotatedRect rrEllipse = fitEllipse(vPoints);
		ellipse(mResult, rrEllipse, Scalar(0, 0, 255), 1);
	}
	else if(iTypeVal==4)//minEnclosingTriangle函数
	{
		vector<Point2f> vTriangle(3);
		minEnclosingTriangle(vPoints, vTriangle);
		for (short a = 0; a < 3; ++a)
		{
			line(mResult, vTriangle[a], vTriangle[(a + 1) % 3], Scalar(0, 0, 255), 1);
		}
	}
	else//凸包
	{
		vector<Point> vHull;
		convexHull(vPoints, vHull, false, true);
		vector<vector<Point>> vvContours = { vHull };
		drawContours(mResult, vvContours, -1, Scalar(0, 0, 255), 1);
	}
	imshow("轮廓包围", mResult);
}
void openCVdemo::test_61()
{
	//四个矩阵
	vPoints.push_back(Point(43, 30));
	vPoints.push_back(Point(129, 30));
	vPoints.push_back(Point(129, 77));
	vPoints.push_back(Point(43, 77));

	//vPoints.push_back(Point(233, 84));
	//vPoints.push_back(Point(227, 39));
	//vPoints.push_back(Point(312, 25));
	//vPoints.push_back(Point(319, 70));

	//vPoints.push_back(Point(100, 217));
	//vPoints.push_back(Point(57, 205));
	//vPoints.push_back(Point(81, 122));
	//vPoints.push_back(Point(124, 135));

	//vPoints.push_back(Point(264, 222));
	//vPoints.push_back(Point(225, 145));
	//vPoints.push_back(Point(265, 125));
	//vPoints.push_back(Point(305, 201));

	for (Point& p : vPoints)
	{
		circle(mSrcImage, p, 2, Scalar(255, 255, 255), -1, LineTypes::FILLED);
	}
	imshow("原图", mSrcImage);
	namedWindow("轮廓包围", WindowFlags::WINDOW_AUTOSIZE);
	createTrackbar("轮廓类型", "轮廓包围", &iTypeVal, 5, onTypeChange, nullptr);
	onTypeChange(0, nullptr);
}

2.2代码测试
分别测试每个矩阵的四个点,得到如下测试结果(图2-2)。

2.3规律探究
根据控制台输出的结果笔者绘制了下图(图2-3)。


上图标注了每个矩阵的angle值。不难看出,将图像x轴按顺时针方向旋转(旋转角度>0),旋转过程中遇到的第一个与旋转轴平行的边为L,angle的值是L与水平方向的夹角。具体示例如下图(图2-4)所示。

3.结语
本文是笔者探究的规律,若有误,请指正。

标签:angle,Point,back,C++,vPoints,OpenCV,push,255
From: https://www.cnblogs.com/hello-nullptr/p/18240905

相关文章

  • DAQmx数据采集---C++版本
    (一)效果展示:(二)采集流程:检索采集设备检索采集通道创建DAQ任务创建采集通道配置采集频率开始采集任务读取采集数据停止采集任务清空采集任务(三)相关接口:该接口可以检测系统已连接的相关采集卡的设备名称paramdata:分配的空间用来存储系统识别到的设备名称......
  • vscode运行C++20,支持模块的实现。
    C++是一个古老的语言,为了跟上时代,一直进行缓慢的演化。在2011年,C++11的发布让这个语言进入21世纪,可以现代化的使用。它有着lambda表达式,auto类型推断。此外使用容器替代低级语言结构,智能指针或其他RAII技术加强了安全编程。我们在编写C++代码应多使用现代化的函数。C++20让编程更......
  • 牛客周赛 Round 46 题解 C++
    目录 A 乐奈吃冰B 素世喝茶C 爱音开灯D 小灯做题E 立希喂猫F 祥子拆团 A 乐奈吃冰#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<queue>#include<set>#include<vector>#include<unordered_map>......
  • C++缺省参数、缺省参数的概念、缺省参数的分类、函数重载、函数重载的概念、C++支持函
    文章目录前言一、缺省参数1.缺省参数的概念2.缺省参数的分类二、函数重载1.函数重载的概念2.C++支持函数重载的原理三、引用1.引用的概念2.引用的特性3.常引用4.引用的使用场景5.传值和传引用效率比较6.引用和指针的区别总结前言C++缺省参数、缺省参数......
  • C语言 & 图形化界面方式连接MySQL【C/C++】【图形化界面组件分享】
      博客主页:花果山~程序猿-CSDN博客文章分栏:MySQL之旅_花果山~程序猿的博客-CSDN博客关注我一起学习,一起进步,一起探索编程的无限可能吧!让我们一起努力,一起成长!目录一.配置开发环境 二,接口介绍1.mysql_init2.mysql_real_connect3.mysql_query4.对select结果分析......
  • 【四种语言一网打尽(C\C++\Python\Golang)】L1-006 连续因子
    L1-006连续因子一个正整数N的因子中可能存在若干连续的数字。例如630可以分解为3×5×6×7,其中5、6、7就是3个连续的数字。给定任一正整数N,要求编写程序求出最长连续因子的个数,并输出最小的连续因子序列。输入格式:输入在一行中给出一个正整数N(1<N<2^31)。输......
  • C++~~期末复习题目讲解---lijiajia版本
    目录1.类和对象(3)创建对象的个数(3)全局变量,局部变量(4)构造函数的执行次数(5)静态动态析构和构造顺序(6)初始化顺序和声明顺序(7)构造和复制构造(8)拷贝构造的三种情况和例题讲解2.继承和派生(1)派生的构造和析构(2)赋值的兼容性规则3.虚函数1.类和对象(1)类和对象的三个特征:封......
  • 2024年华为OD机试真题-快递员的烦恼-C++-OD统一考试(C卷D卷)
     2024年OD统一考试(D卷)完整题库:华为OD机试2024年最新题库(Python、JAVA、C++合集) 题目描述:快递公司每日早晨,给每位快递员推送需要送到客户手中的快递以及路线信息,快递员自己又查找了一些客户与客户之间的路线距离信息,请你依据这些信息,给快递员设计一条最短路径,告诉他最短路......
  • C&C++内存管理【new和delete操作符的详细分析】【常见面试题】
    C/C++内存管理1.C/C++内存分布我们先来看一段代码,来了解一下C/C++中的数据内存分布。#include<stdlib.h>intglobalVar=1;staticintstaticGlobalVar=1;//比globalVar还要先销毁,同一个文件下后定义的先析构//全局变量存在数据段(静态区)但是链接方式和静......
  • C++Primer Plus 第12章 类和动态内存分配 12.10编程练习第2题new,delete的指向深度拷
    系列文章目录提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加例如:本章练习第2题涉及标准函数及关键词toupper,tolower(),strcpy_s(),strcat_s(),strcmp,strlen(),new[],delete[].实现如下效果输出应与下面相似:Pleaseenteryourname:FrettaFarboMynameis......