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里隐藏的“禅”
Jun 16 Python
对python添加模块路径的三种方法总结
Oct 16 Python
使用python对文件中的数值进行累加的实例
Nov 28 Python
python+opencv打开摄像头,保存视频、拍照功能的实现方法
Jan 08 Python
python实现Virginia无密钥解密
Mar 20 Python
详解Python列表赋值复制深拷贝及5种浅拷贝
May 15 Python
python破解bilibili滑动验证码登录功能
Sep 11 Python
Tensorflow轻松实现XOR运算的方式
Feb 03 Python
Python descriptor(描述符)的实现
Nov 15 Python
如何使用Python提取Chrome浏览器保存的密码
Jun 09 Python
python geopandas读取、创建shapefile文件的方法
Jun 29 Python
Python爬虫 简单介绍一下Xpath及使用
Apr 26 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
php的POSIX 函数以及进程测试的深入分析
2013/06/03 PHP
有关PHP性能优化的介绍
2013/06/20 PHP
php使用sql server验证连接数据库的方法
2014/12/25 PHP
PHP7内核之Reference详解
2019/03/14 PHP
Yii框架模拟组件调用注入示例
2019/11/11 PHP
删除重复数据的算法
2006/11/23 Javascript
基本jquery的控制tabs打开的数量的代码
2010/10/17 Javascript
js实现图片轮换效果代码
2013/04/16 Javascript
javascript禁用Tab键脚本实例
2013/11/22 Javascript
js实现图片放大和拖拽特效代码分享
2015/09/05 Javascript
js与jquery正则验证电子邮箱、手机号、邮政编码的方法
2016/07/04 Javascript
react-native ListView下拉刷新上拉加载实现代码
2017/08/03 Javascript
Node.js  REPL (交互式解释器)实例详解
2017/08/06 Javascript
MVVM 双向绑定的实现代码
2018/06/21 Javascript
ionic grid(栅格)九宫格制作详解
2018/06/30 Javascript
jQuery利用cookie 实现本地收藏功能(不重复无需多次命名)
2019/11/07 jQuery
基于vue实现图片验证码倒计时60s功能
2019/12/10 Javascript
Javascript实现html转pdf高清版(提高分辨率)
2020/02/19 Javascript
Python正则表达式介绍
2012/08/06 Python
使用grappelli为django admin后台添加模板
2014/11/18 Python
详解Python3中的Sequence type的使用
2015/08/01 Python
Python中文件I/O高效操作处理的技巧分享
2017/02/04 Python
Python实现PyPDF2处理PDF文件的方法示例
2019/09/25 Python
wxPython实现分隔窗口
2019/11/19 Python
Python3如何对urllib和urllib2进行重构
2019/11/25 Python
Python3.7+tkinter实现查询界面功能
2019/12/24 Python
利用Vscode进行Python开发环境配置的步骤
2020/06/22 Python
10分钟理解CSS3 Grid布局
2018/12/20 HTML / CSS
HTML5表单验证特性(知识点小结)
2020/03/10 HTML / CSS
里程积分管理买卖交换平台:Points.com
2017/01/13 全球购物
Snapfish英国:在线照片打印和个性化照片礼品
2017/01/13 全球购物
家长给学校的建议书
2014/05/15 职场文书
会议欢迎词
2015/01/23 职场文书
黄埔军校观后感
2015/06/10 职场文书
导游词之山东八仙过海景区
2019/11/11 职场文书
在NumPy中深拷贝和浅拷贝相关操作的定义和背后的原理
2022/04/14 Python