绘制直线:line()
绘制圆:circle()
绘制矩形:rectangle()
绘制椭圆:ellipse()
绘制多边形:
添加文字:putText()
void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,
int thickness = 1, int lineType = LINE_8, int shift = 0);
CV_EXPORTS void rectangle(CV_IN_OUT Mat& img, Rect rec,
const Scalar& color, int thickness = 1,
int lineType = LINE_8, int shift = 0);
Rect_<_Tp>::Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height)
: x(_x), y(_y), width(_width), height(_height) {}
函数声明
CV_EXPORTS_W void ellipse(InputOutputArray img, Point center, Size axes,
double angle, double startAngle, double endAngle,
const Scalar& color, int thickness = 1,
int lineType = LINE_8, int shift = 0);
参数
img :画布容器
center:椭圆中心
axes :大小位于该矩形中,长轴长度,短轴长度
angle:椭圆的旋转角度
startangle:开始弧度
endAngle:结束弧度
color :图形颜色
thickness :线宽
lineType :线型
shift :圆心坐标点和数轴的精度
函数声明
CV_EXPORTS_W void circle(InputOutputArray img, Point center, int radius,
const Scalar& color, int thickness = 1,
int lineType = LINE_8, int shift = 0);
参数
img: 将要画圆的图像;
center: 圆心;
radius: 半径;
color: 圆的颜色;
thickness: 如果值是正,圆外轮廓的厚度,如果值是负,表示要绘制一个填充圆;
lineType:线类型;
函数声明
CV_EXPORTS void fillPoly(Mat& img, const Point** pts,
const int* npts, int ncontours,
const Scalar& color, int lineType = LINE_8, int shift = 0,
Point offset = Point() );
参数
img:图像名称,
pts:顶点列表(这个多边形在array中有四个顶点)
为什么pts要被定义成二级指针?那是因为cvFillPoint函数能够一次绘制多个多边形,所以它用一维数组(一个行指针)存储一个多边形的点,用另一个一位数组(另一个行指针)存储另一个多边形的点,这样就可以实现用一个二维数组来存储多个多边形的点啦。
True表示闭合,
npts: 每一个多边形包含了多少个点
ncontours: 设定你要画的多边形的个数
当然如果你定义的Point数组的行数(也就是多边形的个数,因为一个行指针对应一个多边形)为n,那么contours就应该小于等于n.
color : 线条颜色
RNG::uniform
int RNG::(int a,int b)
float RNG::uniform(float a,float b)
double RNG::uniform(double a,double b)
随机类RNG:计算机的伪随机数是由随机种子根据一定的计算方法计算出来的数值,所以只要计算方法一定,随机种子一定,那么产生的随机数就是固定的。
RNG rng(12345)
opencv 里RNG类构造函数初始化为固定值后,随机种子也是固定的,所以在相同的平台环境下,编译后每次运行它,显示的随机数是一样的。
例如:
RNG rng(12345);
int main(void)
{
for (int i = 0; i < 10; i++) {
int a = rng.uniform(1, 100);
cout << a << endl;
}
return 0;
}
只要平台不变,每次生成的都是:
6
33
12
54
71
65
94
11
64
76
如果想改变成随机生成的数,使用下面的方法:
RNG rng((unsigned)time(NULL));
int main(void)
{
for (int i = 0; i < 10; i++) {
int a = rng.uniform(1, 100);
cout << a << endl;
}
return 0;
}
第一次结果:
76
79
3
3
83
2
34
65
97
9
第二次结果:
35
46
76
52
32
68
69
42
49
91
Mat src;
void myLines() {
Point p1 = Point(20, 30);
Point p2;
p2.x = 300;
p2.y = 300;
Scalar color = Scalar(0, 0, 255);
line(src, p1, p2, color,1,LINE_8);
line(src, p1, Point(200, 400), 1, LINE_AA);
}
void myRectangle() {
Rect rect = Rect(200, 100, 300, 300);
Scalar color = Scalar(0, 0, 255);
rectangle(src, rect, color, 2, LINE_8, 0);
}
void myEllipse() {
Scalar color = Scalar(0, 255, 255);
ellipse(src, Point(src.cols / 2, src.rows / 2), Size(src.cols / 4, src.rows / 8), 45, 0, 360, color, 2);
}
void myCircle() {
Scalar color = Scalar(255, 255, 0);
circle(src, Point(src.cols / 2, src.rows / 2), 100, color, 2);
}
void myPolygon() {
Point p[1][5];
p[0][0] = Point(100, 100);
p[0][1] = Point(100, 200);
p[0][2] = Point(200, 200);
p[0][3] = Point(200, 100);
p[0][4] = Point(100, 100);
const Point *ppts[] = { p[0] };
int npt[] = { 5 };
Scalar color = Scalar(120, 130, 130);
fillPoly(src, ppts, npt, 1, color);
}
void randomLineDemo() {
Mat src1 = Mat::zeros(src.size(), src.type());
RNG rng(12345);
Point p1, p2;
for (size_t i = 0; i < 1000; i++)
{
p1.x = rng.uniform(0, src1.cols);
p1.y = rng.uniform(0, src1.rows);
p2.x = rng.uniform(0, src1.cols);
p2.y = rng.uniform(0, src1.rows);
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
if (waitKey(50)) {
line(src1, p1, p2, color);
imshow("demo", src1);
}
}
}
int main() {
src = imread("D:/test/first.png",1);
if (!src.data) {
cerr << "open error" << endl;
return -1;
}
myLines();
myRectangle();
myEllipse();
myCircle();
myPolygon();
putText(src, "hello world!", Point(300, 300), CV_FONT_HERSHEY_COMPLEX, 1.0, Scalar(0, 144, 223));
imshow("yuantu", src);
randomLineDemo();
//imshow("new", dst);
waitKey(0);
return 0;
}