OpenCV4入门系列教程53:图像绘制(文字)

入门系列索引:系列教程索引地址

上一篇:OpenCV4入门系列教程52:添加噪声

一般添加噪声是添加水印,也就是将文字写到图片上面。

本文介绍OpenCV在图片上绘制图像的方法。

基本图像绘制

文字

函数原型:

1
2
3
4
5
6
7
8
9
10
11
void cv::putText(
cv::Mat& img, // 待绘制的图像
const string& text, // 待绘制的文字
cv::Point origin, // 文本框的左下角
int fontFace, // 字体 (如cv::FONT_HERSHEY_PLAIN)
double fontScale, // 尺寸因子,值越大文字越大
cv::Scalar color, // 线条的颜色(RGB)
int thickness = 1, // 线条宽度
int lineType = 8, // 线型(4邻域或8邻域,默认8邻域)
bool bottomLeftOrigin = false // true='origin at lower left'
);

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include "opencv2/opencv.hpp"

using namespace std;
using namespace cv;

int main(){
cv::Mat img = cv::imread("1.jpg");
cv::putText(img,"JackeyLea",cv::Point(10,100),1,1,cv::Scalar(255,255,255),2,8,false);
cv::imshow("result",img);

waitKey();
return 0;
}

测试效果如下:

puttext

可以通过getTextSize函数来获取指定字体字号的文字的文本框的宽和高。

直线

函数原型:

1
2
3
4
5
6
7
void line(Mat& img, 
Point pt1,
Point pt2,
const Scalar& color,
int thickness=1,
int lineType=8,
int shift=0);

参数:

  • img: 要绘制线段的图像。
  • pt1: 线段的起点。
  • pt2: 线段的终点。
  • color: 线段的颜色,通过一个Scalar对象定义。
  • thickness: 线条的宽度。
  • lineType: 线段的类型。可以取值8, 4, 和CV_AA, 分别代表8邻接连接线,4邻接连接线和反锯齿连接线。默认值为8邻接。为了获得更好地效果可以选用CV_AA(采用了高斯滤波)。
  • shift: 坐标点小数点位数。

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <stdio.h>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
Mat src=imread("1.jpg");
line(src,Point(1,1),Point(250,250),Scalar(0,0,255),5,LINE_AA);
imshow("1",src);
waitKey(0);

return 0;
}

测试结果:

line

函数原型:

1
2
3
4
5
6
7
void circle(Mat  img, 
Point center,
int radius,
Scalar color,
int thickness=1,
int lineType=8,
int shift=0);

参数说明:

  • img为源图像
  • center为画圆的圆心坐标
  • radius为圆的半径
  • color为设定圆的颜色,规则根据B(蓝)G(绿)R(红)
  • thickness 如果是正数,表示组成圆的线条的粗细程度。否则,表示圆是否被填充
  • line_type 线条的类型。默认是8
  • shift 圆心坐标点和半径值的小数点位数

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <opencv2/opencv.hpp>
#include <stdio.h>

using namespace std;
using namespace cv;

int main()
{
Mat src = imread("1.jpg", 3);
circle(src, Point(src.cols / 2, src.rows / 2), 40, Scalar(0, 0, 255),2);
imshow("src", src);
waitKey(0);
return 0;
}

测试结果如下:

circle

椭圆圆弧和椭圆扇形

1
2
3
4
5
6
7
8
9
10
void ellipse( CvArr* img, 
CvPoint center,
CvSize axes,
double angle,
double start_angle,
double end_angle,
CvScalar color,
int thickness=1,
int line_type=8,
int shift=0 );

参数说明:

  • img:图像。
  • center:椭圆圆心坐标。
  • axes:轴的长度。
  • angle:偏转的角度。
  • start_angle:圆弧起始角的角度。.
  • end_angle:圆弧终结角的角度。
  • color:线条的颜色。
  • thickness:线条的粗细程度。
  • line_type:线条的类型,见CVLINE的描述。
  • shift:圆心坐标点和数轴的精度。

函数ellipse用来绘制或者填充一个简单的椭圆弧或椭圆扇形。圆弧被ROI矩形所忽略。反走样弧线和粗弧线使用线性分段近似值。所有的角都是以角度的形式给定的。图片下面要解释参数的含义。

ellipse

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
cv::Mat img = imread("1.jpg");

double angle=10.0;

int thickhness = 2;
int lineType = 8;

ellipse(img,
Point(50, 50),
Size(40, 30),
angle,
0, 360,
Scalar(255, 129, 0),
thickhness,
lineType);

imshow("ellipse",img);

waitKey();

return 0;
}

测试效果:

ellipse

绘制多边形

函数说明:

1
2
3
4
5
6
7
8
9
10
void cv::polylines  (   Mat &   img,
const Point *const * pts,
const int * npts,
int ncontours,
bool isClosed,
const Scalar & color,
int thickness = 1,
int lineType = LINE_8,
int shift = 0
)

参数说明:

  • img 图像。
  • pts 折线的顶点指针数组。
  • npts 折线的定点个数数组。也可以认为是pts指针数组的大小
  • contours 折线的线段数量。
  • is_closed 指出多边形是否封闭。如果封闭,函数将起始点和结束点连线。
  • color 折线的颜色。
  • thickness 线条的粗细程度。
  • line_type 线段的类型。参见cvLine。
  • shift 顶点的小数点位数。

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
cv::Mat img = imread("1.jpg");
int lineType = 8;
int WINDOW_WIDTH = 400;

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

const Point* ppt[1] = { rookPoints[0] };
int npt[] = { 20 };

cv::polylines(img,
ppt,
npt,
1,
1,//好像只能为1,填其他数程序出错
Scalar(255, 255, 255),
1,
cv::LINE_8,1);

imshow("1",img);

waitKey();
return 0;
}

测试效果如图:

poly

矩形

函数原型为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void rectangle(Mat& img, 
Point pt1,
Point pt2,
const Scalar& color,
int thickness=1,
int lineType=8,
int shift=0)

void rectangle(Mat& img,
Rect rec,
const Scalar& color,
int thickness=1,
int lineType=8,
int shift=0 )

参数说明:

  • img 图像
  • pt1 矩形的一个顶点。
  • pt2 矩形对角线上的另一个顶点 color 线条颜色 (RGB) 或亮度(灰度图像 )(grayscale image)。
  • thickness 组成矩形的线条的粗细程度。取负值时(如 CV_FILLED)函数绘制填充了色彩的矩形。
  • line_type 线条的类型。见cv::line的描述
  • shift 坐标点的小数点位数。

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

int main()
{
Mat img = imread("1.jpg");
Rect r(250, 250, 120, 200);
rectangle(img, r, Scalar(0, 255, 255), 3);

imshow("rect", img);

waitKey();
return 0;
}

测试效果:

rect

下一篇:OpenCV4入门系列教程54:视频文字显示