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

2.7 隨機產生器和OpenCV當中的文字

目標

在教程中,你會學習到:ios

一、使用隨機數字產生類(RNG)而且如何從均勻分佈中得到隨機數字。dom

二、使用OpenCVputText函數在窗口中顯示文字函數

 

代碼

一、在前一個的教程(Basic Drawing)中,咱們畫了不一樣的幾何圖形,給出了例如座標(使用Points形式的)的輸入參數,顏色,線條粗細,等等。你可能已經注意到咱們對於那些參數都是給出了特殊的值。學習

二、在本教程中,咱們打算使用爲繪圖參數使用隨機值。一樣,咱們打算使用大量的幾何圖形來填滿咱們的圖形。由於咱們打算使用隨機的形式來進行初始化,這個過程將經過循環的形式自動進行。字體

三、這裏的代碼在OpenCV的事例文件夾(OpenCV\sample)。ui

/**this

 * @file Drawing_2.cppspa

 * @brief Simple sample codecode

 */orm

 

#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;

}

 

解釋

一、讓咱們查看一下main函數。咱們看到第一個東西就是建立了一個隨機數字產生器類的對象。

   RNG rng(0xFFFFFFFF);

RNG代表這是一個隨機數字產生器。在這個例子中,rng做爲RNG元素被初始化爲0xFFFFFFFF

二、而後咱們使用zeros函數初始化矩陣(也就是意味着顯示出來是黑色的),指明它的高、寬以及它的類型。

 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=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;

全部的這些函數都遵循相同的事例,所以咱們將要分析其中幾個具備表明性的事例。

四、查看函數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;
}
}

 

咱們能夠看出:

一、for循環將重複NUMBER次。由於line函數在循環裏面,也就意味着NUMBER條線會將要被繪製出。  

二、每條線的兩端的點是pt1pt2,。對於pt1,我麼能夠看到:

pt1.x=rng.uniform(x_1,x_2);

pt1.y=rng.uniform(y_1,y_2);

  -咱們知道rng是隨機生成數字類的對象。在上面的對象咱們調用rng.uniform(a,b)。這個函數使用均勻分佈產生了在ab之間的隨機數(隨機數的範圍包括啊,不包括b)。

  -從上面的解釋中,咱們推斷出端點pt1pt2是隨機產生的,所以線條的位置是徹底不可能預測的,產生了好的視覺效果(能夠從Result部分中看到)。

  -此外咱們還注意line函數的參數,對於color參數的輸入,咱們使用:

randomColorrng

讓咱們看一下這個函數是什麼意思:

 

static Scalar randomColorRNG& rng

{

int icolor=(unsigned) rng;

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

 

正如咱們所看到的,返回值是一個使用了三個隨即初始化R,G,B值的Scalar類型。這個Scalar對象被用於line函數中。所以線條的顏色也將是個隨機值!

五、上面的解釋適用於其餘的產生圓、橢圓、任意形狀等等的函數。參數中例如centervertices也都是隨機產生的。

六、在結束以前,咱們一樣也應當看一下Display_Random_TextDisplaying_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,」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條文字。

八、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);

所以,image2imageScalar::all(i)的差。事實上,這個操做就是image2image的每個像素和i值(記住對於每個像素,咱們要考慮例如RGB三個值,所以其中任何一個都會被影響到)得差的結果。

一樣要記得的是減操做老是包含了saturate操做,也就是說結果老是在容許的範圍內存在(在咱們的示例中,不會是負數,只會在0-255之間)。

相關文章
相關標籤/搜索