生成直线、矩形、椭圆、圆、填充图形、添加文字、生成随机直线
- 代码
- 各种函数使用方法的介绍
- 各种处理后的结果图片对比:
代码
先上代码。
我自学的方式是先看代码,然后在代码中遇到不懂的再逐个查询资料,深入学习,直到学懂。大家按照符合自己的方式学习就好了,适合自己的才是最好的。共勉。
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
Mat src, dst;
void MyLine();
void MyRectangle();
void MyEclipse();
void Mycircle();
void MyPolyLine();
void randomLine();
int main(int argc, char** argv)
{
src = imread("E:/minions.jpg");
if (!src.data)
{
cout << "error" << endl;
return -1;
}
src.copyTo(dst);
MyLine();//生成线段
MyRectangle();//生成矩形
MyEclipse();//生成椭圆
Mycircle();//生成圆形
MyPolyLine();//生成填充图形
putText(src, "Hello World!", Point(300, 300), FONT_HERSHEY_COMPLEX, 1.0, Scalar(12, 255, 200),3,8);//添加文字
namedWindow("pic1", WINDOW_AUTOSIZE);
imshow("pic1", src);
namedWindow("pic2", WINDOW_AUTOSIZE);
imshow("pic2", dst);
randomLine();//生成随机位置、随机颜色的直线
waitKey(0);
return 0;
}
void MyLine()
{
Point p1 = Point(20, 30);
Point p2;
p2.x = 300;
p2.y = 300;
Scalar color = Scalar(0, 0, 255);
line(src, p1, p2, color,10, LINE_AA);
}
void MyRectangle()
{
Rect r = Rect(100, 100, 200, 200);
Scalar color = Scalar(255, 0, 0);
rectangle(src, r, color, 2, LINE_8);
}
void MyEclipse()
{
Scalar color = Scalar(0, 255, 0);
ellipse(src, Point(src.cols / 2, src.rows / 2), Size(src.cols / 4, src.rows / 8), 90, 0, 360, color, 2, LINE_8);
// 图像 椭圆中心 椭圆大学 90是表示倾斜程度 角度 0-360度
}
void Mycircle()
{
Scalar color = Scalar(0, 255, 255);
Point center = Point(dst.cols / 2, dst.rows / 2);
circle(dst, center, 150, color, 2, 8);
}
void MyPolyLine()
{
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 ppt[] = { 5 };
Scalar color = Scalar(255, 255, 0);
fillPoly(dst, ppts, ppt, 1, color, 8);
}
void randomLine()
{
RNG rng(12345);
Point p1;
Point p2;
Mat bg = Mat::zeros(dst.size(), dst.type());
for (int i = 0; i < 100; i++)
{
p1.x = rng.uniform(0, dst.cols);
p1.y = rng.uniform(0, dst.rows);
p2.x = rng.uniform(0, dst.cols);
p2.y = rng.uniform(0, dst.rows);
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
line(bg, p1, p2, color, 1, 8);
if (waitKey(50))
{
namedWindow("随机线条生成", WINDOW_AUTOSIZE);
imshow("随机线条生成", bg);
}
}
}
各种函数使用方法的介绍
- Point(int x, int y)函数,表示2D平面上的一个点.
可以使用类似 Point p.x = 1,p.y = 2 来声明,
也可以使用Point p(1, 2)来声明; - 画直线
line(backgroundImage,Point1,Point2,color,thickness,linetype);
对应(背景图片,点1,点2,颜色,线条宽度,线条类型);
其中点1和点2若在括号内直接输入,要以Point(x, y)的形式,否则会报错;
color是Scalar类型的,可以直接输入Scalar(r, g, b);
线条宽度thickness默认为1;
线条类型默认为8,即LINE_8,表示8邻接线,类似的还有LINE_4(4邻接线)、LINE_AA(抗锯齿线)等; - 画矩形。
画矩形时先要声明一个Rect型的变量,格式为:
Rect r = Rect(x, y, width, height);
然后生成矩形rectangle(backgroundImage,r,color,thickness,linetype);
对应(背景图片,矩形的起始位置和大小,颜色,线条宽度,线条类型); - 画椭圆
ellipse(backgroundImage,center,axes,angle,startangle,endangle,color,thickness,linetype);
对应(背景图片,椭圆中心,椭圆的轴,倾斜角度,开始角度,终止角度,颜色,线条宽度,线条类型);
其中椭圆中心是Point(x, y)类型的,输入时应按照Point(x, y)的形式;
椭圆的轴,类似是Size(w, h)类型的,w和h分别对应椭圆的长半轴和短半轴,注意,是半轴!!!!;
倾斜角度和开始、终止角度下面用图片显示效果,文字说明不是太直观;
ellipse(s1, Point(src.cols / 2, src.rows / 2), Size(src.cols / 4, src.rows / 8), 0, 0, 360, color, 2, LINE_8);
倾斜角度为0,椭圆范围0——360
ellipse(s2, Point(src.cols / 2, src.rows / 2), Size(src.cols / 4, src.rows / 8), 45, 0, 360, color, 2, LINE_8);
倾斜角度为45,椭圆范围0——360
ellipse(s3, Point(src.cols / 2, src.rows / 2), Size(src.cols / 4, src.rows / 8), 90, 0, 360, color, 2, LINE_8);
倾斜角度为90,椭圆范围0——360
ellipse(s4, Point(src.cols / 2, src.rows / 2), Size(src.cols / 4, src.rows / 8), 0, 0, 180, color, 2, LINE_8);
倾斜角度为0,椭圆范围0——180
ellipse(s5, Point(src.cols / 2, src.rows / 2), Size(src.cols / 4, src.rows / 8), 90, 45, 90, color, 2, LINE_8);
倾斜角度为90,椭圆范围45——90
- 画圆形
circle(backgroundImage,center,radius,color,thickness,linetype);
对应(背景图片,圆心坐标,半径,颜色,线条宽度,线条类型),没什么可解释的,和上面的一样,圆心是Point(x, y)型的,其他没区别; - 画填充图形;
fillPoly(backgroundImage,ppts,npts,contours,color,linetype);
对应(背景图片,多边形的顶点组成的数组,数组中点的个数,绘制图像的个数(默认为1),颜色,线条类型);
ppts如下:
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 npts[] = { 5 };
- 以绘制填充的四边形为例,要把四边形全包围,所以有5个点,最后回到起始点。ppts的类型是const Point**,因为是数组,所以仅使用const Point* 进行了声明,const一定要有,有很多时候会报莫名其妙的错就是因为没有const。
因为ppts内共有5个point点,所以int npts[] = { 5 }。 - 添加文字;
putText(backgroundImage,text,org,fontface,fontscale,color,thickness,linetype);
对应(背景图片,文字,位置,字体类型,字体大小,颜色,线条宽度,线条类型);
其中字体类型有FONT_HERSHEY_SIMPLEX(正常大小)、FONT_ITALIC(斜体)等; - 生成随机颜色和位置的直线;
RNG rng(12345);
Point p1;
Point p2;
Mat bg = Mat::zeros(dst.size(), dst.type());
for (int i = 0; i < 100; i++)
{
p1.x = rng.uniform(0, dst.cols);
p1.y = rng.uniform(0, dst.rows);
p2.x = rng.uniform(0, dst.cols);
p2.y = rng.uniform(0, dst.rows);
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
line(bg, p1, p2, color, 1, 8);
if (waitKey(50))
{
namedWindow("随机线条生成", WINDOW_AUTOSIZE);
imshow("随机线条生成", bg);
}
}
这里的RNG是随机数生成器类 ,rng(12345)是随机数的seed,rng.uniform(int a,int b)是随机正态分布在a–b之间生成数字,与之类似的还有rng.gaussian(double sigma)是生成高斯随机数,sigma是高斯分布的标准偏差,从高斯分布N(0,sigma)返回下一个随机数,返回的随机数平均值为0。
各种处理后的结果图片对比: