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);
上面代码中的b
、g
、r
分别代表蓝色、绿色和红色值。
绘图操作
创建图片对象和显示窗口
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); //线条类型:连续线条
}
运行结果如下: