阅读(115) (11)

随机生成器和OpenCV文本

2017-08-30 10:52:43 更新

目标

在本教程中,您将学习如何:

  • 使用随机数生成器类(cv :: RNG)以及如何从均匀分布中获取随机数。
  • 使用函数cv :: putText在OpenCV窗口中显示文本

Code

  • 在前面的教程(基本绘图)中,我们绘制了不同的几何图形,作为输入参数,如坐标(以cv :: Point的形式),颜色,厚度等。您可能已经注意到,我们给出了这些参数的特定值。
  • 在本教程中,我们打算为绘图参数使用随机值。此外,我们打算用大量的几何图形填充我们的形象。由于我们将以随机的方式对它们进行初始化,所以这个过程将是自动的,并且使用循环。
  • 此代码位于您的OpenCV示例文件夹中。否则你可以从这里抓住它

说明

  • 我们首先检查主要功能。我们观察到,我们首先做的是创建一个随机数生成器对象(RNG):
RNG rng( 0xFFFFFFFF );

RNG实现一个随机数生成器。在本例中,rng是以0xFFFFFFFF值初始化的RNG元素

  • 然后我们创建一个初始化为零的矩阵(这意味着它将显示为黑色),指定其高度,宽度和类型:
Mat image = Mat :: zeros(window_height,window_width,CV_8UC3);
imshow(window_name,image);
  • 然后我们继续画疯狂的东西。看看代码后,可以看到它主要分为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 = Displaying_Random_Text(image,window_name,rng);
if(c!= 0)return 0;
c = Displaying_Big_End(image,window_name,rng);

所有这些功能都遵循相同的模式,因此我们将仅分析其中的一些功能,因为同样的解释适用于所有的功能。

  • 检出函数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;
}
  • 我们可以看到以下内容:
  1. 该用于循环将重复NUMBER次。由于函数cv :: 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之间的随机均匀分布(包括在a中,排除在b中)。
  • 从上面的解释,我们推导出极值pt1和pt2将是随机值,所以线位置将是非常不可预测的,给出一个很好的视觉效果(查看下面的结果部分)。
  • 另外观察一下,我们注意到在cv :: line参数中,输入颜色:
    randomColor(RNG)
    

我们来看看功能的实现:

static Scalar randomColor( RNG& rng )
  {
  int icolor = (unsigned) rng;
  return Scalar( icolor&255, (icolor>>8)&255, (icolor>>16)&255 );
  }

我们可以看到,返回值是具有3个随机初始化值的标量,它被用作线颜色的RGB参数。因此,线条的颜色也是随机的!

  • 上面的说明适用于生成圆,椭圆,多边形等的其他函数。中心和顶点等参数也随机生成。
  • 在完成之前,我们还应该看看Display_Random_Text和Displaying_Big_End的功能,因为它们都有一些有趣的功能:
  • 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);

那么函数cv :: putText是做什么的呢?在我们的例子中:

  1. 绘制文本**“测试文本渲染”**在图像中
  2. 文本的左下角将位于Point org中
  3. 字体类型是一个随机整数值,范围为:。[0,8>
  4. 字体的大小由表达式rng.uniform(0,100)x0.05 + 0.1表示(表示其范围为 0.1,5.1 ][0.1,5.1>
  5. 文本颜色是随机的(由randomColor(rng)表示))
  6. 文本厚度范围介于1到10之间,由rng.uniform(1,10)

因此,我们将在随机位置获得(分析其他绘图功能)NUMBER个文本在我们的图像上。

  • Displaying_Big_End

int Displaying_Big_End( Mat image, char* window_name, RNG 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;
}

除了函数getTextSize(获取参数文本的大小)之外,我们可以观察到的新操作在foor循环中:

image2 = image  -  Scalar :: all(i)

所以,image2是图像和Scalar :: all(i)的减法。事实上,这里发生的一切是,image2的每个像素都将减去图像的每个像素减去i的值(记住,对于每个像素,我们考虑三个值,如R,G和B,因此每个像素会受到影响)

还要记住,减法运算总是在内部执行饱和运算,这意味着获得的结果将始终在允许的范围内(对于我们的示例,不会为负值,在0到255之间)。

结果

正如您刚才在“代码”部分所看到的,程序将依次执行不同的绘图功能,这将产生:

  • 首先,一个随机的NUMBER行将出现在屏幕上,如可以在这个屏幕截图中看到的:

随机生成器和OpenCV文本

  • 然后,一组新的数字,这些时间矩形将跟随。
  • 现在将出现一些椭圆,其中每个都有随机位置,大小,厚度和弧长:

随机生成器和OpenCV文本

  • 现在,具有03段的折线将出现在屏幕上,再次以随机配置。

随机生成器和OpenCV文本

  • 填充的多边形(在此示例中为三角形)将跟随。
  • 最后几何图形出现:圈子!

随机生成器和OpenCV文本

  • 接近尾声,文字*“测试文字呈现”*将以各种字体,大小,颜色和位置出现。
  • 而大端(也是这样表达了一个大道理):

随机生成器和OpenCV文本