随机数生成器以及OpenCV中的文本
2016-03-04 11:07
225 查看
目标:
在这个教程中你将学会:
使用随机数生成类(RNG)并且如何从一个均匀分布中得到一个随机数;
使用putText函数在OpenCV窗口中显示文本;
代码:
在之前的教程中我们通过给定输入参数例如坐标,颜色,线宽等来绘制了各种不同的几何图形。你可能已经注意到了我们对每个参数给定了特定的值。
在这个教程中,我们打算对这些参数使用随机数。同时,我们打算让很多几何图形来填充我们的图像。因为我们使用随机数的方式来初始化这些参数,因此这个过程将会使用一个循环来自动进行。
代码如下:
解释:
1、 让我们先来看一下主函数,我们可以看到我们做的第一件事就是先创建一个随机数生成器的对象。
RNG rng(oxFFFFFFFF);
RNG实现一个随机数生成器,在这个例子中,rng是一个以0xFFFFFFFF初始化的RNG元素。
2、 然后我们创建一个矩阵并初始化为0.指定它的高,宽和类型:
Mat image=Mat::zeros(window_height,window_width,CV_8UC3);
Imshow(window_name,image);
3、 然后我们就开始绘制一些比较疯狂的东西。代码可以分成8个部分,分别被定义为了函数:
所有的函数都是遵循同样的模式,所以我们可以只分析他们中的几个就可以了。
1、 让我们来看一下函数Drawing_Random_Lines:
我们可以看到:
For循环将重复NUMBER次,因为line函数在循环里面,这就意味着将会产生NUMBER条直线。
直线的两个端点由pt1和pt2确定,从pt1我们可以看到:
pt1.x = rng.uniform( x_1, x_2 );
pt1.y = rng.uniform( y_1, y_2 );
我们知道rng是一个随机数对象,在上面的代码中我们调用了rng.uniform(a,b)。这个将产生一个在a和b之间的一个随机均匀分布。
从上面的解释我们可以知道直线的两个端点pt1和pt2将是随机值。所以直线的位置是不可预知的,这将产生一个很好的视觉效果。
另外,我们还可以看到line的参数,颜色的输入我们是这样确定的:
randomColor(rng);
让我们来看一下这个函数的实现:
Static Scalar randomColor(RNG& rng)
{
Int icolor=(unsigned)rng;
Return Scalar(icolor&255,(icolor>>8)&255,(icolor>>16)&255);
}
正如我们所看到的,返回值是一个由3个随机数初始化的Scalar,因此,直线的颜色也将是随机的。
1、 上面的解释对于其他函数同样是适用的,诸如中心点以及顶点这些参数也都是随机数。
2、 在结束之前,我们也应该看一下函数Display_Random_Text以及Display_Big_End,因为他们都有一些有趣的特点。
3、 Display_Random_Text:
所有的东西看起来都很熟悉,但是下面这个表达式:
putText( image,"Testing text rendering", org, rng.uniform(0,8),
rng.uniform(0,100)*0.05+0.1,randomColor(rng), rng.uniform(1, 10), lineType);
这个函数是做什么的?在我们这个例子中:
在image图像中绘制文本”Testingtext rendering”
文本的左下角将位于点org
字体类型是一个范围在0-8之间的随机整数
字体的大小将用表达式rng.uniform(0,100)x0.05+0.1来确定(也就是0.1-5.1范围)
文本的颜色是随机的(由randomColor(rng)确定)
文本的厚度在1-10之间,由rng.uniform(1,10)确定
最终,我们将在我们的的图像上随机的位置上得到NUMBER个文本。
1、 Display_Big_End
除了函数getTextSize(这将得到文本的尺寸),在for循环中我们可以看到新的操作:
Image2=image-Scalar::all(i)
所以,image2是image减去Scalar::all(i)得到的。实际上,在image2中的每一个像素都是image图像的对应像素减去一个i值得到的结果。
同样需要记住的是在这个减操作的内部是包含有saturate操作的,这就意味着所获得的结果都将在允许的范围内。
在这个教程中你将学会:
使用随机数生成类(RNG)并且如何从一个均匀分布中得到一个随机数;
使用putText函数在OpenCV窗口中显示文本;
代码:
在之前的教程中我们通过给定输入参数例如坐标,颜色,线宽等来绘制了各种不同的几何图形。你可能已经注意到了我们对每个参数给定了特定的值。
在这个教程中,我们打算对这些参数使用随机数。同时,我们打算让很多几何图形来填充我们的图像。因为我们使用随机数的方式来初始化这些参数,因此这个过程将会使用一个循环来自动进行。
代码如下:
/* Random generator and Text with OpenCV * Author:York * Email:y_zhou1991@163.com * Date:2016/03/04 */ #include <cv.h> #include <highgui.h> #include <iostream> #include <stdio.h> using namespace cv; /// Global Variables const int NUMBER = 100; const int DELAY = 5; const int window_width = 900; const int window_height = 600; int x_1 = -window_width / 2; int x_2 = window_width * 3 / 2; int y_1 = -window_width / 2; int y_2 = window_width * 3 / 2; /// Function headers static Scalar randomColor(RNG& rng); int Drawing_Random_Lines(Mat image, char* window_name, RNG rng); int Drawing_Random_Rectangles(Mat image, char* window_name, RNG rng); int Drawing_Random_Ellipses(Mat image, char* window_name, RNG rng); int Drawing_Random_Polylines(Mat image, char* window_name, RNG rng); int Drawing_Random_Filled_Polygons(Mat image, char* window_name, RNG rng); int Drawing_Random_Circles(Mat image, char* window_name, RNG rng); int Displaying_Random_Text(Mat image, char* window_name, RNG rng); int Displaying_Big_End(Mat image, char* window_name, RNG rng); /** * @function main */ int main(void) { int c; /// Start creating a window char window_name[] = "Drawing_2 Tutorial"; /// Also create a random object (RNG) RNG rng(0xFFFFFFFF); /// Initialize a matrix filled with zeros Mat image = Mat::zeros(window_height, window_width, CV_8UC3); /// Show it in a window during DELAY ms imshow(window_name, image); waitKey(DELAY); /// Now, let's draw some lines c = Drawing_Random_Lines(image, window_name, rng); if (c != 0) return 0; /// Go on drawing, this time nice rectangles c = Drawing_Random_Rectangles(image, window_name, rng); if (c != 0) return 0; /// Draw some ellipses c = Drawing_Random_Ellipses(image, window_name, rng); if (c != 0) return 0; /// Now some polylines c = Drawing_Random_Polylines(image, window_name, rng); if (c != 0) return 0; /// Draw filled polygons c = Drawing_Random_Filled_Polygons(image, window_name, rng); if (c != 0) return 0; /// Draw circles c = Drawing_Random_Circles(image, window_name, rng); if (c != 0) return 0; /// Display text in random positions c = Displaying_Random_Text(image, window_name, rng); if (c != 0) return 0; /// Displaying the big end! c = Displaying_Big_End(image, window_name, rng); if (c != 0) return 0; waitKey(0); return 0; } /// Function definitions /** * @function randomColor * @brief Produces a random color given a random object */ static Scalar randomColor(RNG& rng) { int icolor = (unsigned)rng; return Scalar(icolor & 255, (icolor >> 8) & 255, (icolor >> 16) & 255); } /** * @function Drawing_Random_Lines */ int Drawing_Random_Lines(Mat image, char* window_name, RNG rng) { Point pt1, pt2; for (int i = 0; i < NUMBER; i++) { pt1.x = rng.uniform(x_1, x_2); pt1.y = rng.uniform(y_1, y_2); pt2.x = rng.uniform(x_1, x_2); pt2.y = rng.uniform(y_1, y_2); line(image, pt1, pt2, randomColor(rng), rng.uniform(1, 10), 8); imshow(window_name, image); if (waitKey(DELAY) >= 0) { return -1; } } return 0; } /** * @function Drawing_Rectangles */ int Drawing_Random_Rectangles(Mat image, char* window_name, RNG rng) { Point pt1, pt2; int lineType = 8; int thickness = rng.uniform(-3, 10); for (int i = 0; i < NUMBER; i++) { pt1.x = rng.uniform(x_1, x_2); pt1.y = rng.uniform(y_1, y_2); pt2.x = rng.uniform(x_1, x_2); pt2.y = rng.uniform(y_1, y_2); rectangle(image, pt1, pt2, randomColor(rng), MAX(thickness, -1), lineType); imshow(window_name, image); if (waitKey(DELAY) >= 0) { return -1; } } return 0; } /** * @function Drawing_Random_Ellipses */ int Drawing_Random_Ellipses(Mat image, char* window_name, RNG rng) { int lineType = 8; for (int i = 0; i < NUMBER; i++) { Point center; center.x = rng.uniform(x_1, x_2); center.y = rng.uniform(y_1, y_2); Size axes; axes.width = rng.uniform(0, 200); axes.height = rng.uniform(0, 200); double angle = rng.uniform(0, 180); ellipse(image, center, axes, angle, angle - 100, angle + 200, randomColor(rng), rng.uniform(-1, 9), lineType); imshow(window_name, image); if (waitKey(DELAY) >= 0) { return -1; } } return 0; } /** * @function Drawing_Random_Polylines */ int Drawing_Random_Polylines(Mat image, char* window_name, RNG rng) { int lineType = 8; for (int i = 0; i< NUMBER; i++) { Point pt[2][3]; pt[0][0].x = rng.uniform(x_1, x_2); pt[0][0].y = rng.uniform(y_1, y_2); pt[0][1].x = rng.uniform(x_1, x_2); pt[0][1].y = rng.uniform(y_1, y_2); pt[0][2].x = rng.uniform(x_1, x_2); pt[0][2].y = rng.uniform(y_1, y_2); pt[1][0].x = rng.uniform(x_1, x_2); pt[1][0].y = rng.uniform(y_1, y_2); pt[1][1].x = rng.uniform(x_1, x_2); pt[1][1].y = rng.uniform(y_1, y_2); pt[1][2].x = rng.uniform(x_1, x_2); pt[1][2].y = rng.uniform(y_1, y_2); const Point* ppt[2] = { pt[0], pt[1] }; int npt[] = { 3, 3 }; polylines(image, ppt, npt, 2, true, randomColor(rng), rng.uniform(1, 10), lineType); imshow(window_name, image); if (waitKey(DELAY) >= 0) { return -1; } } return 0; } /** * @function Drawing_Random_Filled_Polygons */ int Drawing_Random_Filled_Polygons(Mat image, char* window_name, RNG rng) { int lineType = 8; for (int i = 0; i < NUMBER; i++) { Point pt[2][3]; pt[0][0].x = rng.uniform(x_1, x_2); pt[0][0].y = rng.uniform(y_1, y_2); pt[0][1].x = rng.uniform(x_1, x_2); pt[0][1].y = rng.uniform(y_1, y_2); pt[0][2].x = rng.uniform(x_1, x_2); pt[0][2].y = rng.uniform(y_1, y_2); pt[1][0].x = rng.uniform(x_1, x_2); pt[1][0].y = rng.uniform(y_1, y_2); pt[1][1].x = rng.uniform(x_1, x_2); pt[1][1].y = rng.uniform(y_1, y_2); pt[1][2].x = rng.uniform(x_1, x_2); pt[1][2].y = rng.uniform(y_1, y_2); const Point* ppt[2] = { pt[0], pt[1] }; int npt[] = { 3, 3 }; fillPoly(image, ppt, npt, 2, randomColor(rng), lineType); imshow(window_name, image); if (waitKey(DELAY) >= 0) { return -1; } } return 0; } /** * @function Drawing_Random_Circles */ int Drawing_Random_Circles(Mat image, char* window_name, RNG rng) { int lineType = 8; for (int i = 0; i < NUMBER; i++) { Point center; center.x = rng.uniform(x_1, x_2); center.y = rng.uniform(y_1, y_2); circle(image, center, rng.uniform(0, 300), randomColor(rng), rng.uniform(-1, 9), lineType); imshow(window_name, image); if (waitKey(DELAY) >= 0) { return -1; } } return 0; } /** * @function Displaying_Random_Text */ int Displaying_Random_Text(Mat image, char* window_name, RNG rng) { int lineType = 8; for (int i = 1; i < NUMBER; i++) { Point org; org.x = rng.uniform(x_1, x_2); org.y = rng.uniform(y_1, y_2); putText(image, "Testing text rendering", org, rng.uniform(0, 8), rng.uniform(0.15, 5.1)/*0.05 + 0.1*/, randomColor(rng), rng.uniform(1, 10), lineType); imshow(window_name, image); if (waitKey(DELAY) >= 0) { return -1; } } return 0; } /** * @function Displaying_Big_End */ int Displaying_Big_End(Mat image, char* window_name, RNG) { Size textsize = getTextSize("OpenCV forever!", FONT_HERSHEY_COMPLEX, 3, 5, 0); Point org((window_width - textsize.width) / 2, (window_height - textsize.height) / 2); int lineType = 8; Mat image2; for (int i = 0; i < 255; i += 2) { image2 = image - Scalar::all(i); putText(image2, "OpenCV forever!", org, FONT_HERSHEY_COMPLEX, 3, Scalar(i, i, 255), 5, lineType); imshow(window_name, image2); if (waitKey(DELAY) >= 0) { return -1; } } return 0; }
解释:
1、 让我们先来看一下主函数,我们可以看到我们做的第一件事就是先创建一个随机数生成器的对象。
RNG rng(oxFFFFFFFF);
RNG实现一个随机数生成器,在这个例子中,rng是一个以0xFFFFFFFF初始化的RNG元素。
2、 然后我们创建一个矩阵并初始化为0.指定它的高,宽和类型:
Mat image=Mat::zeros(window_height,window_width,CV_8UC3);
Imshow(window_name,image);
3、 然后我们就开始绘制一些比较疯狂的东西。代码可以分成8个部分,分别被定义为了函数:
/// Now, let's draw some lines c = Drawing_Random_Lines(image, window_name, rng); if( c != 0 ) return 0; /// Go on drawing, this time nice rectangles c = Drawing_Random_Rectangles(image, window_name, rng); if( c != 0 ) return 0; /// Draw some ellipses c = Drawing_Random_Ellipses( image, window_name, rng ); if( c != 0 ) return 0; /// Now some polylines c = Drawing_Random_Polylines( image, window_name, rng ); if( c != 0 ) return 0; /// Draw filled polygons c = Drawing_Random_Filled_Polygons( image, window_name, rng ); if( c != 0 ) return 0; /// Draw circles c = Drawing_Random_Circles( image, window_name, rng ); if( c != 0 ) return 0; /// Display text in random positions c = Displaying_Random_Text( image, window_name, rng ); if( c != 0 ) return 0; /// Displaying the big end! c = Displaying_Big_End( image, window_name, rng );
所有的函数都是遵循同样的模式,所以我们可以只分析他们中的几个就可以了。
1、 让我们来看一下函数Drawing_Random_Lines:
int Drawing_Random_Lines( Mat image, char* window_name, RNG rng ) { int lineType = 8; Point pt1, pt2; for( int i = 0; i < NUMBER; i++ ) { pt1.x = rng.uniform( x_1, x_2 ); pt1.y = rng.uniform( y_1, y_2 ); pt2.x = rng.uniform( x_1, x_2 ); pt2.y = rng.uniform( y_1, y_2 ); line( image, pt1, pt2, randomColor(rng), rng.uniform(1, 10), 8 ); imshow( window_name, image ); if( waitKey( DELAY ) >= 0 ) { return -1; } } return 0; }
我们可以看到:
For循环将重复NUMBER次,因为line函数在循环里面,这就意味着将会产生NUMBER条直线。
直线的两个端点由pt1和pt2确定,从pt1我们可以看到:
pt1.x = rng.uniform( x_1, x_2 );
pt1.y = rng.uniform( y_1, y_2 );
我们知道rng是一个随机数对象,在上面的代码中我们调用了rng.uniform(a,b)。这个将产生一个在a和b之间的一个随机均匀分布。
从上面的解释我们可以知道直线的两个端点pt1和pt2将是随机值。所以直线的位置是不可预知的,这将产生一个很好的视觉效果。
另外,我们还可以看到line的参数,颜色的输入我们是这样确定的:
randomColor(rng);
让我们来看一下这个函数的实现:
Static Scalar randomColor(RNG& rng)
{
Int icolor=(unsigned)rng;
Return Scalar(icolor&255,(icolor>>8)&255,(icolor>>16)&255);
}
正如我们所看到的,返回值是一个由3个随机数初始化的Scalar,因此,直线的颜色也将是随机的。
1、 上面的解释对于其他函数同样是适用的,诸如中心点以及顶点这些参数也都是随机数。
2、 在结束之前,我们也应该看一下函数Display_Random_Text以及Display_Big_End,因为他们都有一些有趣的特点。
3、 Display_Random_Text:
int Displaying_Random_Text( Mat image, char* window_name, RNG rng ) { int lineType = 8; for ( int i = 1; i < NUMBER; i++ ) { Point org; org.x = rng.uniform(x_1, x_2); org.y = rng.uniform(y_1, y_2); putText( image, "Testing text rendering", org, rng.uniform(0,8), rng.uniform(0,100)*0.05+0.1, randomColor(rng), rng.uniform(1, 10), lineType); imshow( window_name, image ); if( waitKey(DELAY) >= 0 ) { return -1; } } return 0; }
所有的东西看起来都很熟悉,但是下面这个表达式:
putText( image,"Testing text rendering", org, rng.uniform(0,8),
rng.uniform(0,100)*0.05+0.1,randomColor(rng), rng.uniform(1, 10), lineType);
这个函数是做什么的?在我们这个例子中:
在image图像中绘制文本”Testingtext rendering”
文本的左下角将位于点org
字体类型是一个范围在0-8之间的随机整数
字体的大小将用表达式rng.uniform(0,100)x0.05+0.1来确定(也就是0.1-5.1范围)
文本的颜色是随机的(由randomColor(rng)确定)
文本的厚度在1-10之间,由rng.uniform(1,10)确定
最终,我们将在我们的的图像上随机的位置上得到NUMBER个文本。
1、 Display_Big_End
int Displaying_Big_End( Mat image, char* window_name, RNG rng ) { Size textsize = getTextSize("OpenCV forever!", CV_FONT_HERSHEY_COMPLEX, 3, 5, 0); Point org((window_width - textsize.width)/2, (window_height - textsize.height)/2); int lineType = 8; Mat image2; for( int i = 0; i < 255; i += 2 ) { image2 = image - Scalar::all(i); putText( image2, "OpenCV forever!", org, CV_FONT_HERSHEY_COMPLEX, 3, Scalar(i, i, 255), 5, lineType ); imshow( window_name, image2 ); if( waitKey(DELAY) >= 0 ) { return -1; } } return 0; }
除了函数getTextSize(这将得到文本的尺寸),在for循环中我们可以看到新的操作:
Image2=image-Scalar::all(i)
所以,image2是image减去Scalar::all(i)得到的。实际上,在image2中的每一个像素都是image图像的对应像素减去一个i值得到的结果。
同样需要记住的是在这个减操作的内部是包含有saturate操作的,这就意味着所获得的结果都将在允许的范围内。
相关文章推荐
- Xshell从windows与服务器之间的文件传送rz/sz
- Linux查看内存情况
- JNI开发第三步:20130801_NDK_JNI的.so文件开发-安卓访问LINUX驱动
- 20130801 linux添加驱动 在dev下可以看到
- shell学习笔记
- [国嵌攻略][100][嵌入式Linux内核制作]
- linux mysql 安装和配置
- linux rz上传与sz下载
- NanoPi 2 Fire 连接使用USB WiFi
- centos彻底删除mysql以及查看MySQL的安装路径
- Centos服务器下禅道管理软件安装与部署
- Java中通过jsch来连接远程服务器执行linux命令
- linux深入分析进程调度
- 学习OpenCV(3)CvMat,Mat和IplImage之间的转化和拷贝
- Linux 常用命令
- 从Hadoop到Spark的架构实践
- 负载均衡—大型网站架构系列:负载均衡详解(上)
- Linux wget安装详解
- linux 下定时器timer的使用
- 解决linux挂载U盘时:Not authorized to perform operation