OpenCV旋转矩形并绘制

该篇博客是记录并分享使用C++ opencv绘制旋转矩形,该代码可以实时显示旋转的过程。
首先贴出效果图:
蓝色—原始矩形
绿色—旋转矩形
白色—旋转矩形的外接矩形
OpenCV旋转矩形并绘制_第1张图片
OpenCV旋转矩形并绘制_第2张图片
下面是代码:

// opencv_study.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include
using namespace cv;
using namespace std;
vector<Point>middle_point;	   //定义一个vector用于储存弧线的坐标

void draw_rectangle(Mat* draw_img, Point center_xy, Size wh, float angle)
{
	int write_angle = abs(angle);
	angle = angle * CV_PI / 180;	//转换成pi
																						//获取原始矩形左上、右上、右下、左下的坐标
	Point point_L_U = Point(center_xy.x - wh.width / 2, center_xy.y - wh.height / 2);	//左上
	Point point_R_U = Point(center_xy.x + wh.width / 2, center_xy.y - wh.height / 2);	//右上
	Point point_R_L = Point(center_xy.x + wh.width / 2, center_xy.y + wh.height / 2);	//右下
	Point point_L_L = Point(center_xy.x - wh.width / 2, center_xy.y + wh.height / 2);	//左下

	Point point[4] = { point_L_U,point_R_U,point_R_L,point_L_L };	//原始矩形数组
	Point after_point[4] = { Point(0,0) };		//旋转后的矩形数组

	for (int i = 0; i < 4; i++)		//求旋转后的对应坐标
	{
		int x = point[i].x - center_xy.x;
		int y = point[i].y - center_xy.y;
		after_point[i].x = cvRound( x * cos(angle) + y * sin(angle) + center_xy.x);
		after_point[i].y = cvRound(-x * sin(angle) + y * cos(angle) + center_xy.y);
	}
	for (int j = 0; j < 3; j++)		//绘制旋转后的矩形  红色
	{
		line(*draw_img, after_point[j], after_point[j + 1], Scalar(0, 255, 0));    
		if (j == 2)
		{
			line(*draw_img, after_point[j + 1], after_point[0], Scalar(0, 255, 0));
		}
	}
	line(*draw_img, center_xy, after_point[1], Scalar(0, 255, 0));		//绘制一条中点到左上角的线
	Point end_point = Point(cvRound((after_point[1].x + center_xy.x) / 2),
							cvRound((after_point[1].y + center_xy.y) / 2));		//弧线结束点坐标,中点到右上角的1/2
	middle_point.push_back(end_point);
	for (int i = 0; i < middle_point.size()-1; i++)		//绘制弧线
	{
		line(*draw_img, middle_point[i], middle_point[i+1], Scalar(0, 255, 0));
	}
	Point font_point = Point((middle_point[middle_point.size() / 2].x + 2 * center_xy.x) / 3,
							 (middle_point[middle_point.size() / 2].y + 2 * center_xy.y) / 3 );		//用于显示角度字符的位置
	string text = to_string(write_angle);
	putText(*draw_img, text, font_point, cv::FONT_HERSHEY_COMPLEX, 0.5, Scalar(0, 255, 0), 1);      //显示字符在图像上 
	
}
int main()
{
	Point center_xy = Point(200, 200);   //定义矩形的中心点坐标与长宽
	Size wh = Size(150, 100);
	float angle = 120.;                 //负为顺时针,正为逆时针
	Point start_point = Point(cvRound((center_xy.x + wh.width / 2 + center_xy.x) / 2),
							  cvRound((center_xy.y - wh.height / 2 + center_xy.y) / 2));   //绘制用于显示旋转角度的弧线的开始点坐标,中心点到右上角的1/2
	middle_point.push_back(start_point);
	for (int i = 0; abs(i) < abs(int(angle))+1;)    //循环动态显示矩形旋转过程
	{
		Mat img = Mat::zeros(Size(400, 400), CV_8UC3);         //生成一张图片
		RotatedRect *r_R = new RotatedRect(center_xy, wh, i);  //生成旋转矩形
		draw_rectangle(&img, center_xy, wh, i);                //绘制旋转矩形
		Rect r = r_R->boundingRect();                          //求旋转矩形的外接矩形
		rectangle(img, r, Scalar(255, 255, 255));              //绘制外接矩形  白色									  
		Rect org_r = Rect(center_xy.x - wh.width / 2, center_xy.y - wh.height / 2, wh.width, wh.height);     //求原始矩形参数
		rectangle(img, org_r, Scalar(255, 0, 0));              //绘制原始矩形  蓝色
		line(img, center_xy, Point(center_xy.x + wh.width / 2, center_xy.y - wh.height / 2),Scalar(255,0,0));    //绘制原始矩形中点到右上角的直线
		delete r_R;
		imshow("Rect", img);
		waitKey(20);
		if (angle < 0) { --i; }
		if (angle >= 0) { ++i; }
	}
	waitKey();
	return 0;
}


有个问题需要说明下,代码中求旋转矩形的公式是在网上找的,如下:

int x = point[i].x - center_xy.x;
int y = point[i].y - center_xy.y;
after_point[i].x = cvRound( x * cos(angle) + y * sin(angle) + center_xy.x);
after_point[i].y = cvRound(-x * sin(angle) + y * cos(angle) + center_xy.y);

这个公式和我自己推导出来的不一样,但是测试结果显示是正确的,所以还是有点疑惑,欢迎各位朋友指正。公式推导可以参考这个博客。

你可能感兴趣的:(opencv,c++)