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 相关文章推荐
以一段代码为实例快速入门Python2.7
Mar 31 Python
简单介绍Python中的RSS处理
Apr 13 Python
用Python将一个列表分割成小列表的实例讲解
Jul 02 Python
Python开发的十个小贴士和技巧及长常犯错误
Sep 27 Python
解析Python的缩进规则的使用
Jan 16 Python
让Python脚本暂停执行的几种方法(小结)
Jul 11 Python
python使用tomorrow实现多线程的例子
Jul 20 Python
基于python实现学生信息管理系统
Nov 22 Python
关于Python 中的时间处理包datetime和arrow的方法详解
Mar 19 Python
python实现视频压缩功能
Dec 18 Python
用Python可视化新冠疫情数据
Jan 18 Python
全网非常详细的pytest配置文件
Jul 15 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共享内存用法实例分析
2016/02/12 PHP
jQuery UI AutoComplete 使用说明
2011/06/20 Javascript
jQuery实现点击标题输入详细信息
2013/04/16 Javascript
javascript字母大小写转换的4个函数详解
2014/05/09 Javascript
AMD异步模块定义介绍和Require.js中使用jQuery及jQuery插件的方法
2014/06/06 Javascript
JS+CSS实现简单滑动门(滑动菜单)效果
2015/09/19 Javascript
js实现倒计时关键代码
2017/05/05 Javascript
JavaScript闭包_动力节点Java学院整理
2017/06/27 Javascript
基于jquery实现多选下拉列表
2017/08/02 jQuery
bootstrap+jquery项目引入文件报错的解决方法
2018/01/22 jQuery
vue.js系列中的vue-fontawesome使用
2018/02/10 Javascript
详解从买域名到使用pm2部署node.js项目全过程
2018/03/07 Javascript
解决vue打包css文件中背景图片的路径问题
2018/09/03 Javascript
微信小程序使用for循环动态渲染页面操作示例
2018/12/25 Javascript
Vue 组件的挂载与父子组件的传值实例
2020/09/02 Javascript
JavaScript 中的六种循环方法
2021/01/06 Javascript
Python爬虫使用Selenium+PhantomJS抓取Ajax和动态HTML内容
2018/02/23 Python
使用EduBlock轻松学习Python编程
2018/10/08 Python
python 判断linux进程,并杀死进程的实现方法
2019/07/01 Python
Python django框架输入汉字,数字,字符生成二维码实现详解
2019/09/24 Python
python使用SQLAlchemy操作MySQL
2020/01/02 Python
Python实现i人事自动打卡的示例代码
2020/01/09 Python
Python中 Global和Nonlocal的用法详解
2020/01/20 Python
利用Tensorflow构建和训练自己的CNN来做简单的验证码识别方式
2020/01/20 Python
如何教少儿学习Python编程
2020/07/10 Python
selenium设置浏览器为headless无头模式(Chrome和Firefox)
2021/01/08 Python
Python实现邮件发送的详细设置方法(遇到问题)
2021/01/18 Python
html5指南-4.使用Geolocation实现定位功能
2013/01/07 HTML / CSS
美国彩妆品牌:Coastal Scents
2017/04/01 全球购物
医学生求职自荐信
2013/10/25 职场文书
成品仓管员工作职责
2013/12/29 职场文书
运动会广播稿50字
2015/08/19 职场文书
承诺书应该怎么写?
2019/09/10 职场文书
详解MySQL主从复制及读写分离
2021/05/07 MySQL
修改MySQL的默认密码的四种小方法
2021/05/26 MySQL
JavaScript中时间格式化新思路toLocaleString()
2021/11/07 Javascript