opencv(c++)随机生成器和文本

参考:
1、https://docs.opencv.org/3.2.0/
2、https://github.com/opencv/opencv/


Random generator and text with OpenCV

  • 使用随机数生成器类(cv :: RNG)以及如何从统一分布中获得一个随机数。
  • 通过使用函数cv :: putText在OpenCV窗口上显示文本

代码

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

说明

1、我们先看看主要的功能。 我们观察到,我们所做的第一件事是创建一个随机数生成器对象(RNG):

RNG rng( 0xFFFFFFFF );

RNG实现一个随机数字发生器。 在这个例子中,rng是一个用值0xFFFFFFFF初始化的RNG元素

2、然后,我们创建一个初始化为0的矩阵(意味着它将显示为黑色),指定其高度,宽度和类型:

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 = Displaying_Random_Text( image, window_name, rng );
if( c != 0 ) return 0;
c = Displaying_Big_End( image, window_name, rng );

所有这些函数都遵循相同的模式,所以我们只分析其中的几个,因为所有的解释都是一样的。

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_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次。 由于函数cv :: 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)
    这会在值ab之间产生一个随机均匀分布(包括在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个随机初始化值的标量,用作线颜色的R,G和B参数。 因此,线条的颜色也是随机的!


5、上面的解释适用于生成圆,椭圆,多边形等其他函数。中心和顶点等参数也是随机生成的。

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, "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做了什么? 在我们的例子中:

  • image中绘制文本“Testing text rendering”
  • 文本的左下角将位于Point org
  • 字体类型是一个随机的整数值,范围:[0,8>。
  • 字体的比例由表达式rng.uniform(0,100)x0.05 + 0.1(表示它的范围是[0.1,5.1>)
  • 文本颜色是随机的(由randomColor(rng)表示)
  • 文本厚度在1到10之间,由rng.uniform(1,10)

因此,我们将在随机位置获取(与其他绘图功能类似的)NUMBER文本在我们的图像上。

8、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)

因此,image2imageScalar :: all(i)的减法运算。 事实上,这里发生的事情是image2 的每个像素将是减去image 的每个像素减去i的值的结果(记住,对于每个像素,我们考虑三个值,例如R,G和B,因此它们中的每一个 会受到影响)

另外请记住,减法运算总是在内部执行一个饱和运算,这意味着得到的结果总是在允许的范围内(对于我们的例子来说在0到255之间没有负数)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值