OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY——Random genenrator and text with OpenCV

2.7 随机产生器和OpenCV当中的文字

目标

在教程中,你会学习到:

1、使用随机数字产生类(RNG)并且如何从均匀分布中获得随机数字。

2、使用OpenCV的putText函数在窗口中显示文字

代码

1、在前一个的教程(Basic Drawing)中,我们画了不同的几何图形,给出了例如坐标(使用Points形式的)的输入参数,颜色,线条粗细,等等。你可能已经注意到我们对于那些参数都是给出了特殊的值。

2、在本教程中,我们打算使用为绘图参数使用随机值。同样,我们打算使用大量的几何图形来填满我们的图形。因为我们打算使用随机的形式来进行初始化,这个过程将通过循环的形式自动进行。

3、这里的代码在OpenCV的事例文件夹(OpenCV\sample)。

/**

* @file Drawing_2.cpp

* @brief Simple sample code

*/

#include <opencv2/core/core.hpp>

#include <opencv2/highgui/highgui.hpp>

#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,100)*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、让我们查看一下main函数。我们看到第一个东西就是创建了一个随机数字产生器类的对象。

RNG rng(0xFFFFFFFF);

RNG表明这是一个随机数字产生器。在这个例子中,rng作为RNG元素被初始化为0xFFFFFFFF

2、然后我们使用zeros函数初始化矩阵(也就是意味着显示出来是黑色的),指明它的高、宽以及它的类型。

Mat image=Mat::zeros(window_height,window_width,CV_8UC3);

imshow(window_name,image);

3、然后我们要画一些杂乱的东西。在对代码进行浏览之后,你可以看到这里主要分成8部分,已定义函数如下:

c=Drawing_Random_Lines(image,window_name,rng);

if(c!=0) return 0;

c=Drawing_Random_Rectangles(image,window_name,rng);

if(c!=0) return 0;

c=Drawing_Random_Ellipses(image,window_name,rng);

if(c!=0) return 0;

c=Drawing_Random_Polylines(image,window_name,rng);

if(c!=0) return 0;

c=Drawing_Random_Filled_Polygons(image,window_name,rng);

if(c!=0) return 0;

c=Drawing_Random_Circles(image,window_name,rng);

if(c!=0) return 0;

c=Drawing_Random_Text(image,window_name,rng);

if(c!=0) return 0;

c=Drawing_Random_Big_End(image,window_name,rng);

if(c!=0) return 0;

所有的这些函数都遵循相同的事例,因此我们将要分析其中几个具有代表性的事例。

4、查看函数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_1);

line(image,pt1,pt2,randomColor(rng),rng.uniform(1,10),8);

Imshow(window_name.image);

If(waitKey(DELAY)>=0)

{

rerturn -1;
}

return 0;
}
}

我们可以看出:

1、for循环将重复NUMBER次。因为line函数在循环里面,也就意味着NUMBER条线会将要被绘制出。

2、每条线的两端的点是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之间的随机数(随机数的范围包括啊,不包括b)。

-从上面的解释中,我们推断出端点pt1和pt2是随机产生的,因此线条的位置是完全不可能预测的,产生了好的视觉效果(可以从Result部分中看到)。

-此外我们还注意line函数的参数,对于color参数的输入,我们使用:

randomColor(rng)

让我们看一下这个函数是什么意思:

static Scalar randomColor(RNG& rng)

{

int icolor=(unsigned) rng;

return Scalar(icolor&255,(icolor>>8)&255,(icolor>>16)&255);

}

正如我们所看到的,返回值是一个使用了三个随即初始化R,G,B值的Scalar类型。这个Scalar对象被用于line函数中。因此线条的颜色也将是个随机值!

5、上面的解释适用于其他的产生圆、椭圆、任意形状等等的函数。参数中例如center和vertices也都是随机产生的。

6、在结束之前,我们同样也应当看一下Display_Random_Text、Displaying_Big_End这两个函数。这两个函数都有一些有意思的特性:

7、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,”Texting 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,”Texting text rendering”,org,rng.uniform(0,8),rng.uniform(0,100)*0.05+0.1,randomColor(rng),rng.uniform(1,10),lineType);

putText这个函数的作用是什么呢?在我们的示例中:

(1)在图像中显示“Testing text rendering”

(2)左下端角落的文字会被定位在点org处。

(3)字体类型是是随机的在[0,8>之间的整数值。[ >这个应该是包括前不包括后的意思。

(4)字体被显示的范围在这个rng.uniform(0,100)*0.05+0.1这个表达式(也就是在[0.1,5.1>范围)

(5)文字的颜色是随机的(由randomColor(rng)函数进行)

(6)文字的粗细范围在1-10之间,被指定于函数rng.uniform(1,10)

就像结果中显示的,我们会(映射到其他绘图程序)在图像的随即位置中得到NUMBER条文字。

8、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 forerve!”,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值(记住对于每一个像素,我们要考虑例如R,G,B三个值,因此其中任何一个都会被影响到)得差的结果。

同样要记得的是减操作总是包含了saturate操作,也就是说结果总是在允许的范围内存在(在我们的示例中,不会是负数,只会在0-255之间)。

时间: 2025-01-12 11:35:34

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY——Random genenrator and text with OpenCV的相关文章

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY—— File Input and Output using XML and YAML files

2.9XML和YAML格式作为文件输入输出 目标 你会从文中找到下面问题的答案: 1.如何从OpenCV使用的YAML或者XML文件中读取和打印文字条目.? 2.对于OpenCV数据结构如何做到相同的事情? 3.对你的数据结构如何做到? 4.OpenCV的数据结构,例如FileStorage,FileNode或者FileNodeIterator的使用方法. 源代码 你可以从这里下载代码或者从OpenCV的源代码库的samples/cpp/tutorial_code/core/file_input

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY—— Interoperability with OpenCV 1

2.10 和OpenCV的互用性 目标 对于OpenCV的开发团队来说,不断提升OpenCV库是非常重要的.我们不断考虑那些可以减轻你工作过程的方法,同时还要保障库的灵活性.新的C++接口就是我们为了这个而开发出来的东西.然而,向后兼容性仍然是很重要的.我们不想打碎那些你使用更早的OpenCV库写下的代码.因此,我们为了保障这个事情从而加上了一些函数.在下面的教程中,你会学习到: 1.相比于同样使用的第一版本的OpenCV库,第二版本中有了什么变化. 2.如何在图像中添加一些高斯噪点. 3.什么

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY—— Discrete Fourier Transform

2.8 离散的傅立叶变换 目标 我们要寻找以下问题的答案: 1.什么是傅立叶变换,为什么我们要用这个? 2.在OpenCV中如何做到? 3.例如copyMakeBorder(),merge(),dft(),getOptimalDFGSize(),log()以及normalize()函数的用法. 源代码 你可以从这里下载或者从samples/cpp/tutorial_code/core/discrete_fourier_transform/discrete找到代码. #include "openc

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY—— Adding(blending) two images using OpenCV

2.5 改变图像的对比度和明暗 目标 在教程中,你会学到如何: 1.读取像素值 2.用0初始化一个矩阵 3.学习staurate_cast是做什么的 4.获取有关像素变换的一些更酷的信息(Get some cool info about pixel transformations) 理论 注意,下面的解释来自于Richard Szeliski所写的<Computer Vision:Algorithms and Applications> 图像处理 1.一般的图像处理机是一个接受一个或多个输入图

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY——Adding (blending) two images using OpenCV

目标 在教程中你会学到: 1.什么事线性混合,它有什么用. 2.如何使用addWeighted将两个图像相加 理论 注意:下面的解释来自Richard Szeliski写的<Computer Vision:Algorithms and Application>. 在前面的教程中,我们已经学习了一些像素的运算.一个有意思的二元(两个输入)运算符就是线性混合运算符: 通过α从0到1变化这个运算符可以被用做两个图像或者录像之间的时间交融(cross-dissolve,这里tutorial里面用的是c

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY—— Mat - The Basic Image Container

在家这段时间内,发现了这样的OpenCV库自带的教程,感觉不错,尝试翻译并且添加一些tips,帮助自己学习,同时也与各位交流一下. 核心模块.核心功能 这里这两部分说的是核心模块以及核心功能的简介,其中蓝字部分可以链接到相关部分,这里我采用顺序方法,从第一部分,即 “Mat:The Basic Image Container”开始叙述. 2.1 基本的图像容器—矩阵 目标 我们可以通过许多途径从真实世界获取数字图像,例如:数码相机.扫描仪.计算机断层扫描以及磁成像共振等等.不管怎样,那些都只是我

OpenCV Tutorials &mdash;&mdash; Random generator and text with OpenCV

creating a Random Number Generator object (RNG): RNG rng( 0xFFFFFFFF ); 创建并初始化随机数生成子 create a matrix initialized to zeros (which means that it will appear as black), specifying its height, width and its type: /// Initialize a matrix filled with zeros

Nginx - Core Module Directives

The following is the list of directives made available by the Core module. Most of these directives must be placed at the root of the configuration file and can only be used once. However, some of them are valid in multiple contexts. If that is the c

AngularJS------Error: Cannot find module &#39;@angular-devkit/core&#39;

如图: 解决方法: 进入项目目录下执行以下代码 npm i --save-dev @angular-devkit/core AngularJS------Error: Cannot find module '@angular-devkit/core' 原文地址:https://www.cnblogs.com/tianhengblogs/p/8452045.html