【OpenCV C++20 学习笔记】imgproc模块-绘图基础

news2024/12/25 14:30:06

imgproc模块-绘图基础

  • Point和Scalar类型
    • Point类型
    • Scalar类型
  • 绘图操作
    • 创建图片对象和显示窗口
    • 绘制椭圆
    • 绘制圆
    • 绘制多边形
    • 绘制矩形
    • 画线
  • 完整代码

Point和Scalar类型

Point类型

该类型表示一个2D的点,其坐标由图像中的 x x x y y y坐标确定。可以这样定义一个Point对象:

Point pt;
pt.x = 10;
pt.y = 8;

或者:

Point pt{ Point(10, 8) };

Scalar类型

该类型表示一个四元素的向量或数组,常用于传递像素值。因为完整的BGR颜色值是包含4个值的,即使最后一个值通常不会进行定义,也可以用Scalar类型来表示:

Scalar( b, g, r);

上面代码中的bgr分别代表蓝色、绿色和红色值。

绘图操作

创建图片对象和显示窗口

char atom_window[]{ "画图 1: Atom" };	//窗口1的标题
char rook_window[]{ "画图 2: Rook" };	//窗口2的标题

Mat atom_image{ Mat::zeros(w, w, CV_8UC3) };	//atom图像矩阵,初始值为0
Mat rook_image{ Mat::zeros(w, w, CV_8UC3) };	//rook图像矩阵,初始值为0

绘制椭圆

OpenCV中可用ellipse()函数来画椭圆,下面的自定义函数MyEllipse()中包含了ellipse()的用法:

void MyEllipse(Mat img, double angle)
{
	int thickness{ 2 };
	int lineType{ 8 };

	ellipse(img,				//作图对象
		Point(w / 2, w / 2),	//中心
		Size(w / 4, w / 16),	//最长半径和最短半径
		angle,					//旋转角度
		0,						//显示的起始角度
		360,					//显示的终止角度,这两个参数决定显示弧长的多少
		Scalar(255, 0, 0),		//图形颜色:蓝色
		thickness,				//线条宽度
		lineType);				//线条类型:连续线条
}

以不同的角度画椭圆:

MyEllipse(atom_image, 90);
MyEllipse(atom_image, 0);
MyEllipse(atom_image, 45);
MyEllipse(atom_image, -45);

结果如下:
绘制椭圆

绘制圆

OpenCV中可用circle()函数绘制圆,其用法如下:

void MyFilledCircle(Mat img, Point center)
{
	circle(img,				//作图对象
		center,				//圆心
		w / 32,				//半径
		Scalar(0, 0, 255),	//图形颜色:红色
		FILLED,				//填充,相当于thickness=-1
		LINE_8);			//线条类型:连续线条
}

调用这个自定义的MyFilledCircle()函数:

MyFilledCircle(atom_image, Point(w / 2, w / 2));

得到如下结果:
绘制圆形

绘制多边形

可用fillPoly()函数来绘制被填充颜色的多边形,其用法如下:

void MyPolygon(Mat img)
{
	int lineType{ LINE_8 };

	Point rook_points[1][20];
	rook_points[0][0] = Point(w / 4, 7 * w / 8);
	rook_points[0][1] = Point(3 * w / 4, 7 * w / 8);
	rook_points[0][2] = Point(3 * w / 4, 13 * w / 16);
	rook_points[0][3] = Point(11 * w / 16, 13 * w / 16);
	rook_points[0][4] = Point(19 * w / 32, 3 * w / 8);
	rook_points[0][5] = Point(3 * w / 4, 3 * w / 8);
	rook_points[0][6] = Point(3 * w / 4, w / 8);
	rook_points[0][7] = Point(26 * w / 40, w / 8);
	rook_points[0][8] = Point(26 * w / 40, w / 4);
	rook_points[0][9] = Point(22 * w / 40, w / 4);
	rook_points[0][10] = Point(22 * w / 40, w / 8);
	rook_points[0][11] = Point(18 * w / 40, w / 8);
	rook_points[0][12] = Point(18 * w / 40, w / 4);
	rook_points[0][13] = Point(14 * w / 40, w / 4);
	rook_points[0][14] = Point(14 * w / 40, w / 8);
	rook_points[0][15] = Point(w / 4, w / 8);
	rook_points[0][16] = Point(w / 4, 3 * w / 8);
	rook_points[0][17] = Point(13 * w / 32, 3 * w / 8);
	rook_points[0][18] = Point(5 * w / 16, 13 * w / 16);
	rook_points[0][19] = Point(w / 4, 13 * w / 16);

	const Point* ppt[1] = {rook_points[0]};//创建一个const Point**变量
	int npt[]{ 20 };

	fillPoly(img,				//作图对象
		ppt,					//点的数组
		npt,					//数组中点的数量
		1,						//线条宽度
		Scalar(255, 255, 255),	//图形颜色:白色
		lineType);				//线条类型:连续线条
}

注意:fillPoly的第二个参数必须是一个const Point**类型的变量。
绘图结果如下:
绘制多边形

绘制矩形

用rectangle()函数可以绘制矩形,具体用法如下:

rectangle(rook_image,		//作图对象
	Point(0, 7 * w / 8),	//左上角的点
	Point(w, w),			//右下角的点
	Scalar(0, 255, 255),	//图形颜色:黄色
	FILLED,					//填充
	LINE_8);				//线条类型:连续线条

绘制结果如下:
绘制矩形

画线

用line()函数可以绘制线条,具体用法如下:

void MyLine(Mat img, Point start, Point end)
{
	int thickness{ 2 };
	int lineType{ LINE_8 };

	line(img,				//作图对象
		start,				//开始点
		end,				//结束点
		Scalar(0, 0, 0),	//线条颜色,这里是黑色
		thickness,			//线条宽度
		lineType);			//线条类型,这里是8—连续线条
}

调用自定义函数MyLine():

MyLine(rook_image, Point(0, 15 * w / 16), Point(w, 15 * w / 16));
MyLine(rook_image, Point(w / 4, 7 * w / 8), Point(w / 4, w));
MyLine(rook_image, Point(w / 2, 7 * w / 8), Point(w / 2, w));
MyLine(rook_image, Point(3 * w / 4, 7 * w / 8), Point(3 * w / 4, w));

绘制结果如下:
绘制线条

完整代码

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>

import <iostream>;

#define w 400

using namespace cv;
using namespace std;

void MyLine(Mat img, Point start, Point end);
void MyEllipse(Mat img, double angle);
void MyFilledCircle(Mat img, Point center);
void MyPolygon(Mat img);

int main() {
	char atom_window[]{ "画图 1: Atom" };
	char rook_window[]{ "画图 2: Rook" };

	Mat atom_image{ Mat::zeros(w, w, CV_8UC3) };
	Mat rook_image{ Mat::zeros(w, w, CV_8UC3) };

	MyEllipse(atom_image, 90);
	MyEllipse(atom_image, 0);
	MyEllipse(atom_image, 45);
	MyEllipse(atom_image, -45);

	MyFilledCircle(atom_image, Point(w / 2, w / 2));

	MyPolygon(rook_image);

	rectangle(rook_image,		//作图对象
		Point(0, 7 * w / 8),	//左上角的点
		Point(w, w),			//右下角的点
		Scalar(0, 255, 255),	//图形颜色:黄色
		FILLED,					//填充
		LINE_8);				//线条类型:连续线条

	MyLine(rook_image, Point(0, 15 * w / 16), Point(w, 15 * w / 16));
	MyLine(rook_image, Point(w / 4, 7 * w / 8), Point(w / 4, w));
	MyLine(rook_image, Point(w / 2, 7 * w / 8), Point(w / 2, w));
	MyLine(rook_image, Point(3 * w / 4, 7 * w / 8), Point(3 * w / 4, w));

	imshow(atom_window, atom_image);
	moveWindow(atom_window, 0, 200);	//以屏幕左上角为原点移动窗口
	imshow(rook_window, rook_image);
	moveWindow(rook_window, w, 200);

	waitKey(0);
	return(0);
}

void MyLine(Mat img, Point start, Point end)
{
	int thickness{ 2 };
	int lineType{ LINE_8 };

	line(img,				//作图对象
		start,				//开始点
		end,				//结束点
		Scalar(0, 0, 0),	//线条颜色:黑色
		thickness,			//线条宽度
		lineType);			//线条类型:8—连续线条
}

void MyEllipse(Mat img, double angle)
{
	int thickness{ 2 };
	int lineType{ 8 };

	ellipse(img,				//作图对象
		Point(w / 2, w / 2),	//中心
		Size(w / 4, w / 16),	//最长直径和最短直径,也可以理解其外接矩形的长和宽
		angle,					//旋转角度
		0,						//显示的起始角度
		360,					//显示的终止角度,这两个参数决定显示弧长的多少
		Scalar(255, 0, 0),		//图形颜色:蓝色
		thickness,				//线条宽度
		lineType);				//线条类型:连续线条
}

void MyFilledCircle(Mat img, Point center)
{
	circle(img,				//作图对象
		center,				//圆心
		w / 32,				//半径
		Scalar(0, 0, 255),	//图形颜色:红色
		FILLED,				//填充,相当于thickness=-1
		LINE_8);			//线条类型:连续线条
}

void MyPolygon(Mat img)
{
	int lineType{ LINE_8 };

	Point rook_points[1][20];
	rook_points[0][0] = Point(w / 4, 7 * w / 8);
	rook_points[0][1] = Point(3 * w / 4, 7 * w / 8);
	rook_points[0][2] = Point(3 * w / 4, 13 * w / 16);
	rook_points[0][3] = Point(11 * w / 16, 13 * w / 16);
	rook_points[0][4] = Point(19 * w / 32, 3 * w / 8);
	rook_points[0][5] = Point(3 * w / 4, 3 * w / 8);
	rook_points[0][6] = Point(3 * w / 4, w / 8);
	rook_points[0][7] = Point(26 * w / 40, w / 8);
	rook_points[0][8] = Point(26 * w / 40, w / 4);
	rook_points[0][9] = Point(22 * w / 40, w / 4);
	rook_points[0][10] = Point(22 * w / 40, w / 8);
	rook_points[0][11] = Point(18 * w / 40, w / 8);
	rook_points[0][12] = Point(18 * w / 40, w / 4);
	rook_points[0][13] = Point(14 * w / 40, w / 4);
	rook_points[0][14] = Point(14 * w / 40, w / 8);
	rook_points[0][15] = Point(w / 4, w / 8);
	rook_points[0][16] = Point(w / 4, 3 * w / 8);
	rook_points[0][17] = Point(13 * w / 32, 3 * w / 8);
	rook_points[0][18] = Point(5 * w / 16, 13 * w / 16);
	rook_points[0][19] = Point(w / 4, 13 * w / 16);

	const Point* ppt[1] = {rook_points[0]};	//创建一个const Point**变量
	int npt[]{ 20 };

	fillPoly(img,				//作图对象
		ppt,					//点的数组
		npt,					//数组中点的数量
		1,						//线条宽度
		Scalar(255, 255, 255),	//图形颜色:白色
		lineType);				//线条类型:连续线条
}

运行结果如下:
绘图结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1972248.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何基于欧拉系统完成数据库的安装

一、安装 当我们直接进行安装软件包时&#xff0c;会提示有冲突&#xff0c;此时&#xff0c;我们应该这样来解决 使用rpm命令 [rootlocalhost yum.repos.d]# rpm -qa | grep selinux使用 rpm命令卸载以下两个软件包 [rootlocalhost yum.repos.d]# rpm -e selinux-policy-3…

B站安全开发流程落地实践

一. 什么是安全开发生命周期&#xff08;SDL&#xff09; 1.1 SDL诞生背景 随着互联网技术的快速发展&#xff0c;网络系统及应用在给人们的生活带来巨大便利的同时&#xff0c;信息安全问题也逐渐成为用户和企业关注的焦点。然而&#xff0c;安全问题的管理和解决需要一个系统…

TCP半关闭过程

TCP半关闭过程 简介 tcp半关闭是指在一端发送完数据后&#xff0c;关闭发送通道&#xff0c;而保持接收通道继续接收数据。 过程 这里设序号为Seqx&#xff0c;确认号为Acky 客户端&#xff08;也可以是服务端发起&#xff09;发送 [FIN&#xff0c;ACK] 报文段&#xff0…

【已解决】树莓派5使用VNC远程,无法正常显示桌面,黑屏提示:cannot currently show the desktop

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

外贸干货|业务员寻找客户的7个思维技巧,都掌握的才算合格

更多外贸干货及开发客户的方法&#xff0c;尽在微信【千千外贸干货】 做外贸最基本的是找到客户&#xff0c;如果没有完成这一步&#xff0c;纵使你有千万种转化客户的方法&#xff0c;也都只是纸上谈兵。 #一 关键词法 选择适当的关键词&#xff0c;直接查找潜在客户发布的求…

Manim实现在坐标轴上添加元素和获取元素

Manim实现在坐标轴上添加元素和获取元素 1.坐标轴上获取元素 构造函数&#xff1a; _get_axis_label(label, axis, edge, direction, buff0.1) 函数 _get_axis_label 旨在为图形表示中的给定轴生成和定位标签&#xff08;通常用于绘图或数学上下文中&#xff0c;可能是在某…

PostgreSQL 15

一、安装前的准备 1、版本信息 操作系统CentOS 7.9.2009PostgreSQL 版本PostgreSQL 15-15.7 2、下载安装包 RPM Chart - PostgreSQL YUM Repositoryhttps://yum.postgresql.org/rpmchart/进入官网&#xff0c;找到相应版本 点击框选内容 依次进入下载页面&#xff0c;下载相…

ASUS/华硕幻15 2020 冰刃4 GX502L GU502L系列 原厂win10系统 工厂文件 带F12 ASUS Recovery恢复

华硕工厂文件恢复系统 &#xff0c;安装结束后带隐藏分区&#xff0c;一键恢复&#xff0c;以及机器所有驱动软件。 系统版本&#xff1a;windows10 原厂系统下载网址&#xff1a;http://www.bioxt.cn 需准备一个20G以上u盘进行恢复 请注意&#xff1a;仅支持以上型号专用…

免费好用的 CI/CD 工具有哪些?

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab &#xff1a;https://gitlab.cn/install 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 更多关于极狐GitLab &a…

V.PS日本东京VPS详细测评

V.PS日本VPS怎么样&#xff1f;V.PS日本机房怎么样&#xff1f; V.PS在日本有东京和大阪两个机房都在运作VPS/云服务器&#xff0c;大阪机房的默认接入IIJ网络&#xff0c;日本东京机房的是日本软银网络&#xff0c;另外日本东京分两个系列&#xff0c;一个是Intel另外一个是AM…

【文件fd】深入理解重定向和缓冲区

目录 1.重定向 1.1dup2 2.缓冲区 2.1什么是缓冲区 2.2为什么存在缓冲区 2.3缓冲区的刷新策略 2.4查看源码​ 3.0/1/2 3.1 0/1/2是什么&为什么存在 3.2 2和1区别 3.3 2为什么存在 1.重定向 重定向的本质&#xff1a;是在内核中改变文件描述符表特定下标的内容和…

Flutter 插件之http(介绍、使用、二次封装)

背景 在我们日常开发过程中,经常会使用到网络请求,而在Flutter插件中,最常用的请求插件一共两个,分别是: 1、dio 2、http 其中dio我已经做过详细介绍了(post、get等请求、文件上传、请求重试等),这里就不做过多阐述,下面附上文章链接,如有需要可前往查看。 http…

「11月·西安」第十二届信息系统与计算技术国际会议(ISCTech 2024)

随着信息技术的飞速发展&#xff0c;信息系统与计算技术已成为推动社会进步与产业升级的重要力量。在这样的背景下&#xff0c;第十二届信息系统与计算技术国际会议&#xff08;ISCTech 2024&#xff09;的召开&#xff0c;无疑为全球专家学者搭建了一个交流思想、共享成果的高…

ProfiNet 转 CAN/CANopen 网关

一、功能概述 1.1 设备简介 本产品是 PN(Profinet)和 COE(CANopen)/CAN(自由口)网关&#xff0c;使用数据映射 方式工作。 本产品在 PN 侧作为 PN IO 从站&#xff0c;接西门子 PLC&#xff1b;在 COE 侧做为 COE 主站&#xff0c; 接 COE 设备&#xff0c;如伺服、变频器、…

漏洞挖掘 | edusrc记一次某中学小程序渗透测试

一、搜集渗透目标 现在的EDU挖web端的上分效率远不如小程序&#xff0c;因此这篇文章浅浅记录一次小程序的挖掘吧。如果各位大牛想要快速出洞&#xff0c;不妨跳过大学&#xff0c;学院等小程序&#xff0c;而重点关注小学、中学、幼儿园等&#xff0c;这些小程序的出洞率还是…

第L3周:机器学习|逻辑回归

本文为&#x1f517;365天深度学习训练营中的学习记录博客 &#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 &#x1f680; 文章来源&#xff1a;K同学的学习圈子深度学习第J6周&#xff1a;ResNeXt-50实战解析 1.逻辑回归定义 逻辑回归&#xff08;Logistic Re…

hive udf去掉map中的一个或者多个key

实现一个hive udf,可以将Map中的某一个或者多个key去掉,这里要继承GenericUDF 这个抽象类,然后Override evaluate这个函数即可,可以把执行这个udf前初始化的一些内容放在initialize方法内,比如参数的判断,函数的返回值类型等等。 代码写好之后,可以用如下方法创建这个函…

Golang之OpenGL(一)

使用OpenGL实现窗口中绘制三角形&#xff08;纯色|彩色&#xff09;、正方形&#xff08;变色&#xff09; 一、简单实现窗口绘制三角形二、绘制的多颜色三角形&#xff08;基于 ‘ 简单实现窗口绘制三角形 ’ &#xff09;1、在顶点着色器和片段着色器中添加了颜色的输入和输出…

【考研高数】反函数的那些事

在这里给同学们推荐来自「荒原之梦考研数学」网的三篇文章&#xff0c;分别是反函数的性质汇总&#xff0c;以及两道相关习题&#xff0c;有需要加强这部分练习的同学&#xff0c;可以长按下方二维码&#xff0c;在「荒原之梦考研数学」官网中打开对应的文章&#xff1a; 《反…

基于单片机的防火防盗报警系统设计

摘要&#xff1a; 该多功能防火防盗系统既具有根据环境温度和烟雾浓度进行火灾检测的功能&#xff0c;也有能对人体检测实现防盗的功能。多功能智能防火防盗控制系统的主控制器是 STC89C52 单片机&#xff0c;环境温度的检测采用 DS18B20 &#xff0c; MQ2 检测烟雾浓度&…