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中操作文件之write()方法的使用教程
May 25 Python
python使用正则表达式提取网页URL的方法
May 26 Python
Python 中pandas.read_excel详细介绍
Jun 23 Python
Python编程之列表操作实例详解【创建、使用、更新、删除】
Jul 22 Python
Python去除、替换字符串空格的处理方法
Apr 01 Python
python Elasticsearch索引建立和数据的上传详解
Aug 04 Python
python利用7z批量解压rar的实现
Aug 07 Python
Python数学形态学实例分析
Sep 06 Python
Python Opencv提取图片中某种颜色组成的图形的方法
Sep 19 Python
Python 支持向量机分类器的实现
Jan 15 Python
Python如何把多个PDF文件合并代码实例
Feb 13 Python
Python yield的用法实例分析
Mar 06 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
从C/C++迁移到PHP——判断字符类型的函数
2006/10/09 PHP
深入phpMyAdmin的安装与配置的详细步骤
2013/05/07 PHP
php观察者模式应用场景实例详解
2017/02/03 PHP
PHP判断当前使用的是什么浏览器(推荐)
2019/10/27 PHP
围观tangram js库
2010/12/28 Javascript
不用构造函数(Constructor)new关键字也能实现JavaScript的面向对象
2013/01/11 Javascript
js简易namespace管理器 实例代码
2013/06/21 Javascript
学习JavaScript设计模式之策略模式
2016/01/12 Javascript
浅谈jQuery中hide和fadeOut的区别 show和fadeIn的区别
2016/08/18 Javascript
探究react-native 源码的图片缓存问题
2017/08/24 Javascript
微信小程序 swiper组件构建轮播图的实例
2017/09/20 Javascript
JavaScript中Require调用js的实例分享
2017/10/27 Javascript
实例分析javascript中的异步
2020/06/02 Javascript
vue导入.md文件的步骤(markdown转HTML)
2020/12/31 Vue.js
js实现类选择器和name属性选择器的示例步骤
2021/02/07 Javascript
[33:42]LGD vs OG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
[01:59][TI9趣味视频] 全明星赛奖励
2019/08/23 DOTA
Python中处理字符串之endswith()方法的使用简介
2015/05/18 Python
Django中利用filter与simple_tag为前端自定义函数的实现方法
2017/06/15 Python
Python Selenium Cookie 绕过验证码实现登录示例代码
2018/04/10 Python
python实现微信自动回复功能
2018/04/11 Python
解决python xx.py文件点击完之后一闪而过的问题
2019/06/24 Python
django url到views参数传递的实例
2019/07/19 Python
python线程池如何使用
2020/05/28 Python
使用Python提取文本中含有特定字符串的方法示例
2020/12/09 Python
CSS3混合模式mix-blend-mode/background-blend-mode简介
2018/03/15 HTML / CSS
全球摩托车装备领导者:RevZilla
2017/09/04 全球购物
民政局个人整改措施
2014/09/24 职场文书
死亡赔偿协议书
2015/01/28 职场文书
大学毕业生个人总结
2015/02/28 职场文书
银行工作心得体会范文
2016/01/23 职场文书
对PyTorch中inplace字段的全面理解
2021/05/22 Python
低版本Druid连接池+MySQL驱动8.0导致线程阻塞、性能受限
2021/07/01 MySQL
Java数据开发辅助工具Docker与普通程序使用方法
2021/09/15 Java/Android
微信小程序中使用vant框架的具体步骤
2022/02/18 Javascript
进行数据处理的6个 Python 代码块分享
2022/04/06 Python