OpenCV-C++ 绘制基本形状与编写文字
这一小节首先介绍一下Point
与Scalar
两个类的使用,以及介绍如何在图像上绘制一些几何形状和添加文字, 具体包括: 线, 矩形, 圆, 椭圆, 多边形等
完整的代码在最下方;
Point与Scalar
Point
Point
表示的是二维平面上的一个点,包含两个属性\(x, y\);
使用方式如下:
// 构建一个点
Point pt = Point(10, 20);
// 或者
Point pt;
pt.x = 10;
pt.y = 20;
Scalar
Scalar
表示的是一个向量, 其本质是一个由长度为4的数组作为元素的结构体;
typedef struct Scalar{
double val[4];
}Scalar;
使用场景在下面绘制几何图形时会用到;
绘制几何图形
绘制几何图形包括线, 矩形, 椭圆, 圆,多边形
画线
关于line
的API如下:
void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,
int thickness = 1, int lineType = LINE_8, int shift = 0);
img
表示需要绘制线的图像;pt1
与pt2
表示线段的两端;color
表示线的颜色,以Scalar
进行定义;thickness
表示线的粗细;lineType
表示线的类型;
在图像上绘制一条线, API的使用:
// 画线方法
void MyLine(Mat src){
Point p1 = Point(10, 20);
Point p2;
p2.x = 300;
p2.y = 300;
Scalar color = Scalar(0, 0, 255);
//画线
line(src, p1, p2, color, 2, LINE_8);
}
- 首先创建线段两个端点的位置,利用
Point
; - 其次利用Scalar创建一个颜色;
绘制矩形
关于rectangle
的API介绍如下:
void rectangle(InputOutputArray img, Rect rec,
const Scalar& color, int thickness = 1,
int lineType = LINE_8, int shift = 0);
img
输入图像rec
表示一个矩形类,下面介绍color
,thickness
,lineType
,shift
含义与上述相同;
关于Rect
的API介绍如下:
class Rect_{
public:
Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
}
- 其中
_x, _y
分别表示矩形的左上角坐标,_width, _height
表示矩形的宽度和高度;
举例, 在一张图像上绘制矩形:
// 绘制矩形方法
void MyRectangle(Mat src){
Rect rect = Rect(200, 100, 300, 300);
Scalar color = Scalar(0, 0, 255);
// 绘制矩形
rectangle(src, rect, color, 2, LINE_8);
}
- 首先,构建矩形
rect
; - 其次绘图;
绘制椭圆
有关ellipse
绘制椭圆的API介绍如下:
void ellipse(InputOutputArray img, Point center, Size axes,
double angle, double startAngle, double endAngle,
const Scalar& color, int thickness = 1,
nt lineType = LINE_8, int shift = 0);
img
为输入图像;center
表示椭圆中心;axes
分别表示椭圆横,纵向长度;angle
表示顺时针旋转多少度;startAngle
与endAngle
配合使用,表示从左上角逆时针,绘制多少度的椭圆;- 后面参数与前述相同;
举例,在一张图像上绘制椭圆:
// 绘制椭圆
void MyEllipse(Mat src){
Point center = Point(src.rows/2, src.cols/2);
Size size = Size(src.cols/4, src.rows/8);
Scalar color = Scalar(0, 0, 255);
ellipse(src, center, size, 30, 0, 360, color, LINE_8);
}
- 构造中心点
- 椭圆横,纵长度
- 颜色
绘制圆
有关circle
的API的介绍如下:
void circle(InputOutputArray img, Point center, int radius,
const Scalar& color, int thickness = 1,
int lineType = LINE_8, int shift = 0);
img
表示需要绘制的图像;center
表示中心点坐标;radius
表示半径大小;- 其他如前述一致;
举例,在图像上绘制一个圆:
// 绘制圆
void MyCircle(Mat src){
Scalar color = Scalar(0, 0, 255);
Point center = Point(src.rows/4, src.cols/2);
int radius = 100;
// 绘制圆
circle(src, center, radius, color, 2, LINE_8);
}
绘制多边形
有关绘制多边形fillPoly
API的使用介绍如下:
void fillPoly(InputOutputArray img, const Point** pts,
const int* npts, int ncontours,
const Scalar& color, int lineType = LINE_8, int shift = 0,
Point offset = Point() );
img
多边形将要绘制到该图像上;pts
表示多边形的顶点集npts
表示顶点数目;ncontours
表示要绘制的多边形数量- 其他与前述一致
举例,在图像中绘制一个多边形,如下:
// 绘制多边形
void MyPolygon(Mat src){
Point pts[1][5];
pts[0][0] = Point(100, 100);
pts[0][1] = Point(100, 200);
pts[0][2] = Point(200, 200);
pts[0][3] = Point(200, 100);
pts[0][4] = Point(100, 100);
const Point* ppts[] = {pts[0]};
int npt[] = {5};
Scalar color = Scalar(255, 0, 255);
// 绘制多边形
fillPoly(src, ppts, npt, 1, color, LINE_8);
}
pts
顶点集,ppts
指针
随机画线
举例,在一张图像上随机画出一些线段;
// 随机画线
void RandomLineDemo(Mat src){
// 新的图像
Mat dst = Mat::zeros(src.size(), src.type());
RNG rng(12345);
Point pt1;
Point pt2;
namedWindow("dst", WINDOW_AUTOSIZE);
for (int i = 0; i < 10000000; i++){
pt1.x = rng.uniform(0, src.cols);
pt2.x = rng.uniform(0, src.cols);
pt1.y = rng.uniform(0, src.rows);
pt2.y = rng.uniform(0, src.rows);
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); // 随机产生颜色
// 停止条件
if (waitKey(50) > 0) {
break;
}
line(dst, pt1, pt2, color, 1, LINE_8);
imshow("dst", dst);
}
}
添加文字
在图像中添加文字,putText
方法的使用介绍如下:
void putText( InputOutputArray img, const String& text, Point org,
int fontFace, double fontScale, Scalar color,
int thickness = 1, int lineType = LINE_8,
bool bottomLeftOrigin = false );
img
表示将要添加文字的图像;text
表示需要添加的文本org
表示文件左下角坐标位置;fontFace
表示字体类型fontScale
表示问题缩放尺度,有一个默认的大小;color
表示图像颜色,其他如前述一致;
举例,在一张图像中绘制一段文字;
putText(src,
"Hello OpenCV",
Point(100, 100),
FONT_HERSHEY_COMPLEX,
0.8,
Scalar(0, 255, 255), 2, LINE_8);
完整代码如下:
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
void MyLine(Mat src); // 画线方法
void MyRectangle(Mat src); // 绘制矩形方法
void MyEllipse(Mat src); // 绘制椭圆
void MyCircle(Mat src); // 绘制圆
void MyPolygon(Mat src); // 绘制多边形
void RandomLineDemo(Mat src); // 随机画线
int main(){
// 读取图像
Mat src = imread("/home/chen/dataset/lena.jpg");
if (src.empty()){
printf("could not load image.\n");
return -1;
}
// 在图像上画线
MyLine(src);
// 在图像上画矩形
MyRectangle(src);
// 在凸显上绘制椭圆
MyEllipse(src);
// 绘制圆
MyCircle(src);
// 绘制多边形
MyPolygon(src);
// 写入文字
// 字体左下端的坐标
putText(src, "Hello OpenCV", Point(100, 100), FONT_HERSHEY_COMPLEX, 0.8, Scalar(0, 255, 255), 2, LINE_8);
// 随机画线
RandomLineDemo(src);
namedWindow("src", WINDOW_AUTOSIZE);
imshow("src", src);
waitKey(0);
return 0;
}
// 画线方法
void MyLine(Mat src){
Point p1 = Point(10, 20);
Point p2;
p2.x = 300;
p2.y = 300;
Scalar color = Scalar(0, 0, 255);
//画线
line(src, p1, p2, color, 2, LINE_8);
}
// 绘制矩形方法
void MyRectangle(Mat src){
Rect rect = Rect(200, 100, 300, 300);
Scalar color = Scalar(0, 0, 255);
// 绘制矩形
rectangle(src, rect, color, 2, LINE_8);
}
// 绘制椭圆
void MyEllipse(Mat src){
Point center = Point(src.rows/2, src.cols/2);
Size size = Size(src.cols/4, src.rows/8);
Scalar color = Scalar(0, 0, 255);
// 绘制椭圆
// 第一个参数表示绘图
// 第二个参数表示椭圆中心
// 第三个参数分别表示横轴, 纵轴长度,用Size类型表示
// 第四个参数表示顺时针倾斜角度
// 第五,六个参数表示从左上角逆时针开始绘制,绘制多少角度
ellipse(src, center, size, 30, 0, 360, color, LINE_8);
}
// 绘制圆
void MyCircle(Mat src){
Scalar color = Scalar(0, 0, 255);
Point center = Point(src.rows/4, src.cols/2);
int radius = 100;
// 绘制圆
circle(src, center, radius, color, 2, LINE_8);
}
// 绘制多边形
void MyPolygon(Mat src){
Point pts[1][5];
pts[0][0] = Point(100, 100);
pts[0][1] = Point(100, 200);
pts[0][2] = Point(200, 200);
pts[0][3] = Point(200, 100);
pts[0][4] = Point(100, 100);
const Point* ppts[] = {pts[0]};
int npt[] = {5};
Scalar color = Scalar(255, 0, 255);
// 绘制多边形
fillPoly(src, ppts, npt, 1, color, LINE_8);
}
// 随机画线
void RandomLineDemo(Mat src){
// 新的图像
Mat dst = Mat::zeros(src.size(), src.type());
RNG rng(12345);
Point pt1;
Point pt2;
namedWindow("dst", WINDOW_AUTOSIZE);
for (int i = 0; i < 10000000; i++){
pt1.x = rng.uniform(0, src.cols);
pt2.x = rng.uniform(0, src.cols);
pt1.y = rng.uniform(0, src.rows);
pt2.y = rng.uniform(0, src.rows);
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); // 随机产生颜色
// 停止条件
if (waitKey(50) > 0) {
break;
}
line(dst, pt1, pt2, color, 1, LINE_8);
imshow("dst", dst);
}
}