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处理中文编码和判断编码示例
Feb 26 Python
Python多线程下载文件的方法
Jul 10 Python
Python二叉搜索树与双向链表转换实现方法
Apr 29 Python
python3写爬取B站视频弹幕功能
Dec 22 Python
django如何连接已存在数据的数据库
Aug 14 Python
Python面向对象思想与应用入门教程【类与对象】
Apr 12 Python
python区分不同数据类型的方法
Oct 14 Python
Python程序控制语句用法实例分析
Jan 14 Python
python3实现名片管理系统(控制台版)
Nov 29 Python
Selenium环境变量配置(火狐浏览器)及验证实现
Dec 07 Python
python中pd.cut()与pd.qcut()的对比及示例
Jun 16 Python
Python 第三方库 openpyxl 的安装过程
Dec 24 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
phpmyadmin显示utf8_general_ci中文乱码的问题终级篇
2013/04/08 PHP
2个Codeigniter文件批量上传控制器写法例子
2014/07/25 PHP
PHP使用pcntl_fork实现多进程下载图片的方法
2014/12/16 PHP
php实现微信支付之企业付款
2018/05/30 PHP
php数值计算num类简单操作示例
2020/05/15 PHP
翻译整理的jQuery使用查询手册
2007/03/07 Javascript
JavaScript 利用StringBuffer类提升+=拼接字符串效率
2009/11/24 Javascript
JavaScript 闭包在封装函数时的简单分析
2009/11/28 Javascript
不同浏览器对回车提交表单的处理办法
2010/02/13 Javascript
jQuery 获取对象 基本选择与层级
2010/05/31 Javascript
js对列表中第一个值处理与jsp页面对列表中第一个值处理的区别详解
2013/11/05 Javascript
jquery序列化form表单使用ajax提交后处理返回的json数据
2014/03/03 Javascript
js动态删除div元素基本思路及实现代码
2014/05/08 Javascript
本人自用的global.js库源码分享
2015/02/28 Javascript
jquery中添加属性和删除属性
2015/06/03 Javascript
实例代码讲解jquery easyui动态tab页
2015/11/17 Javascript
jQuery ajax分页插件实例代码
2016/01/27 Javascript
分享10个优化代码的CSS和JavaScript工具
2016/05/11 Javascript
jQuery学习笔记之回调函数
2016/08/15 Javascript
JS中BOM相关知识点总结(必看篇)
2016/11/22 Javascript
JavaScript运动框架 多值运动(四)
2017/05/18 Javascript
jQuery序列化form表单数据为JSON对象的实现方法
2018/09/20 jQuery
微信小程序自定义组件传值 页面和组件相互传数据操作示例
2019/05/05 Javascript
浅谈JavaScript中的“!!”作用
2020/08/03 Javascript
nodejs中使用worker_threads来创建新的线程的方法
2021/01/22 NodeJs
Python实现基本数据结构中队列的操作方法示例
2017/12/04 Python
在PyCharm中批量查找及替换的方法
2019/01/20 Python
对python中基于tcp协议的通信(数据传输)实例讲解
2019/07/22 Python
Python openpyxl 插入折线图实例
2020/04/17 Python
北大研究生linux应用求职信
2013/10/29 职场文书
经典大学生求职信范文
2014/01/06 职场文书
违纪检讨书2000字
2014/02/08 职场文书
远程网络教育毕业生自我鉴定
2014/04/14 职场文书
党员教师一句话承诺
2014/05/30 职场文书
云冈石窟导游词
2015/02/04 职场文书
家庭经济困难证明
2015/06/23 职场文书