OpenCV绘制圆端矩形的示例代码


Posted in Python onAugust 30, 2021

本文主要介绍了OpenCV绘制圆端矩形的示例代码,分享给大家,具体如下:

功能函数

// 绘制圆端矩形(药丸状,pill)
void DrawPill(cv::Mat mask, const cv::RotatedRect &rotatedrect, const cv::Scalar &color, int thickness, int lineType)
{
	cv::Mat canvas = cv::Mat::zeros(mask.size(), CV_8UC1);
	// 确定短边,短边绘制圆形
	cv::RotatedRect rect = rotatedrect;
	float r = rect.size.height / 2.0f;
	if (rect.size.width > rect.size.height) {
		rect.size.width -= rect.size.height;
	}
	else {
		rect.size.height -= rect.size.width;
		r = rect.size.width / 2.0f;
	}
	cv::Point2f ps[4];
	rect.points(ps);
 
	// 绘制边缘
	std::vector<std::vector<cv::Point>> tmpContours;
	std::vector<cv::Point> contours;
	for (int i = 0; i != 4; ++i) {
		contours.emplace_back(cv::Point2i(ps[i]));
	}
	tmpContours.insert(tmpContours.end(), contours);
	drawContours(canvas, tmpContours, 0, cv::Scalar(255),5, lineType);  // 填充mask
 
	// 计算常长短轴
	float a = rotatedrect.size.width;
	float b = rotatedrect.size.height;
 
	int point01_x = (int)((ps[0].x + ps[1].x) / 2.0f);
	int point01_y = (int)((ps[0].y + ps[1].y) / 2.0f);
	int point03_x = (int)((ps[0].x + ps[3].x) / 2.0f);
	int point03_y = (int)((ps[0].y + ps[3].y) / 2.0f);
	int point12_x = (int)((ps[1].x + ps[2].x) / 2.0f);
	int point12_y = (int)((ps[1].y + ps[2].y) / 2.0f);
	int point23_x = (int)((ps[2].x + ps[3].x) / 2.0f);
	int point23_y = (int)((ps[2].y + ps[3].y) / 2.0f);
 
	cv::Point c0 = a < b ? cv::Point(point12_x, point12_y) : cv::Point(point23_x, point23_y);
	cv::Point c1 = a < b ? cv::Point(point03_x, point03_y) : cv::Point(point01_x, point01_y);
 
	// 长轴两端以填充的方式画圆,直径等于短轴
	cv::circle(canvas, c0, (int)r, cv::Scalar(255), 5, lineType);
	cv::circle(canvas, c1, (int)r, cv::Scalar(255), 5, lineType);
 
	// 绘制外围轮廓,如果不这样操作,会得到一个矩形加两个圆形,丑。。。
	std::vector<std::vector<cv::Point>> EXcontours;
	cv::findContours(canvas,EXcontours,cv::RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
	drawContours(mask, EXcontours, 0, color, thickness,lineType);  // 填充mask
}

测试代码

#include <iostream>
#include <opencv2/opencv.hpp>
 
using namespace std;
using namespace cv;
 
void DrawPill(cv::Mat mask, const cv::RotatedRect &rotatedrect, const cv::Scalar &color, int thickness, int lineType);
 
int main()
{
	cv::Mat src = imread("test.jpg");
	cv::Mat result = src.clone();
	cv::RotatedRect rorect(cv::Point(src.cols / 2, src.rows / 2), cv::Size(1000, 800), 50);
	DrawPill(result, rorect, cv::Scalar(0, 255, 255),8,16);
	imshow("original", src);
	imshow("result", result);
	waitKey(0);
	return 0;
}
 
// 绘制圆端矩形(药丸状,pill)
void DrawPill(cv::Mat mask, const cv::RotatedRect &rotatedrect, const cv::Scalar &color, int thickness, int lineType)
{
	cv::Mat canvas = cv::Mat::zeros(mask.size(), CV_8UC1);
	// 确定短边,短边绘制圆形
	cv::RotatedRect rect = rotatedrect;
	float r = rect.size.height / 2.0f;
	if (rect.size.width > rect.size.height) {
		rect.size.width -= rect.size.height;
	}
	else {
		rect.size.height -= rect.size.width;
		r = rect.size.width / 2.0f;
	}
	cv::Point2f ps[4];
	rect.points(ps);
 
	// 绘制边缘
	std::vector<std::vector<cv::Point>> tmpContours;
	std::vector<cv::Point> contours;
	for (int i = 0; i != 4; ++i) {
		contours.emplace_back(cv::Point2i(ps[i]));
	}
	tmpContours.insert(tmpContours.end(), contours);
	drawContours(canvas, tmpContours, 0, cv::Scalar(255),5, lineType);  // 填充mask
 
	// 计算常长短轴
	float a = rotatedrect.size.width;
	float b = rotatedrect.size.height;
 
	int point01_x = (int)((ps[0].x + ps[1].x) / 2.0f);
	int point01_y = (int)((ps[0].y + ps[1].y) / 2.0f);
	int point03_x = (int)((ps[0].x + ps[3].x) / 2.0f);
	int point03_y = (int)((ps[0].y + ps[3].y) / 2.0f);
	int point12_x = (int)((ps[1].x + ps[2].x) / 2.0f);
	int point12_y = (int)((ps[1].y + ps[2].y) / 2.0f);
	int point23_x = (int)((ps[2].x + ps[3].x) / 2.0f);
	int point23_y = (int)((ps[2].y + ps[3].y) / 2.0f);
 
	cv::Point c0 = a < b ? cv::Point(point12_x, point12_y) : cv::Point(point23_x, point23_y);
	cv::Point c1 = a < b ? cv::Point(point03_x, point03_y) : cv::Point(point01_x, point01_y);
 
	// 长轴两端以填充的方式画圆,直径等于短轴
	cv::circle(canvas, c0, (int)r, cv::Scalar(255), 5, lineType);
	cv::circle(canvas, c1, (int)r, cv::Scalar(255), 5, lineType);
 
	// 绘制外围轮廓,如果不这样操作,会得到一个矩形加两个圆形,丑。。。
	std::vector<std::vector<cv::Point>> EXcontours;
	cv::findContours(canvas,EXcontours,cv::RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
	drawContours(mask, EXcontours, 0, color, thickness,lineType);  // 填充mask
}

测试效果

OpenCV绘制圆端矩形的示例代码 

图1 原图

OpenCV绘制圆端矩形的示例代码 

图2 绘制圆端矩形

绘制圆端矩形其实就是绘制了一个旋转矩形,然后分析哪个轴更长,就在哪个轴上的两端画圆,再取外围轮廓,大功告成,通俗来讲就画了一个矩形两个圆,如图3所示。

OpenCV绘制圆端矩形的示例代码 

图3 绘制逻辑

不过注意,这个图形最好不要超过图像边界,因为超过后再分析外围轮廓,它认为的外围就到了内部,如图4所示。

OpenCV绘制圆端矩形的示例代码 

图4 外围线

然后,你就会得到一个奇葩图形,如图5所示。

OpenCV绘制圆端矩形的示例代码

图5 示意图

到此这篇关于OpenCV绘制圆端矩形的示例代码的文章就介绍到这了,更多相关OpenCV 圆端矩形内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python实现发送邮件功能
Jul 22 Python
python实现对指定输入的字符串逆序输出的6种方法
Apr 26 Python
Tensorflow 查看变量的值方法
Jun 14 Python
如何用python写一个简单的词法分析器
Dec 18 Python
Python的log日志功能及设置方法
Jul 11 Python
django多个APP的urls设置方法(views重复问题解决)
Jul 19 Python
将Pytorch模型从CPU转换成GPU的实现方法
Aug 19 Python
python获取引用对象的个数方式
Dec 20 Python
在 Python 中接管键盘中断信号的实现方法
Feb 04 Python
wxpython自定义下拉列表框过程图解
Feb 14 Python
Python基础之字典常见操作经典实例详解
Feb 26 Python
Python调用腾讯API实现人脸身份证比对功能
Apr 04 Python
python中super()函数的理解与基本使用
python自动化操作之动态验证码、滑动验证码的降噪和识别
Aug 30 #Python
Python图片验证码降噪和8邻域降噪
Aug 30 #Python
Python音乐爬虫完美绕过反爬
Aug 30 #Python
详解解Django 多对多表关系的三种创建方式
Aug 23 #Python
一些让Python代码简洁的实用技巧总结
Aug 23 #Python
一篇文章搞懂python混乱的切换操作与优雅的推导式
Aug 23 #Python
You might like
重量级动漫纷纷停播!唯独OVERLORD第四季正在英魂之刃继续更新
2020/05/06 日漫
Classes and Objects in PHP5-面向对象编程 [1]
2006/10/09 PHP
PHP语言中global和$GLOBALS[]的分析 之二
2012/02/02 PHP
php简单日历函数
2015/10/28 PHP
php爬取天猫和淘宝商品数据
2018/02/23 PHP
让iframe子窗体取父窗体地址栏参数(querystring)
2009/10/13 Javascript
关于javascript DOM事件模型的两件事
2010/07/22 Javascript
js图片延迟加载的实现方法及思路
2013/07/22 Javascript
判断文件是否正在被使用的JS代码
2013/12/21 Javascript
使用Sticky组件实现带sticky效果的tab导航和滚动导航的方法
2016/03/22 Javascript
vue实现模态框的通用写法推荐
2018/02/26 Javascript
vue 手机物理监听键+退出提示代码
2020/09/09 Javascript
js实现验证码干扰(动态)
2021/02/23 Javascript
Python的Django框架安装全攻略
2015/07/15 Python
Python 爬虫的工具列表大全
2016/01/31 Python
修改python plot折线图的坐标轴刻度方法
2018/12/13 Python
python实现浪漫的烟花秀
2019/01/30 Python
详解python tkinter教程-事件绑定
2019/03/28 Python
python内存动态分配过程详解
2019/07/15 Python
python requests使用socks5的例子
2019/07/25 Python
Python实现企业微信机器人每天定时发消息实例
2020/02/25 Python
Python获取android设备cpu和内存占用情况
2020/11/15 Python
Python 的 f-string 可以连接字符串与数字的原因解析
2021/02/20 Python
html5 拖拽及用 js 实现拖拽功能的示例代码
2020/10/23 HTML / CSS
美国药妆网站:EDCskincare.com(防晒、痤疮、抗衰老等)
2017/04/28 全球购物
欧铁通票官方在线销售网站:Eurail.com
2017/10/14 全球购物
护士辞职信模板
2014/01/20 职场文书
高中英语教学反思
2014/02/04 职场文书
《跨越海峡的生命桥》教学反思
2014/02/24 职场文书
教师党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
会议邀请函
2015/01/30 职场文书
大学生旷课检讨书1000字
2015/02/19 职场文书
2015年创先争优工作总结
2015/05/23 职场文书
小学生法制教育心得体会
2016/01/14 职场文书
基于nginx实现上游服务器动态自动上下线无需reload的实现方法
2021/03/31 Servers
nginx+lua单机上万并发的实现
2021/05/31 Servers