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

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);				//线条类型:连续线条
}

运行结果如下:
绘图结果

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值