學習OpenCV(七)——隨機數發生器和繪製文字
阿新 • • 發佈:2019-02-04
本次範例是在上一次博客學習OpenCV範例(六)——基本繪圖的基礎上,加上隨機數發生器和文字顯示,進行更加有趣的開發,當本次範例學習完之後,基本的繪圖函式也就學習完了。
1、介紹
範例通過使用 隨機數發生器類 (RNG) 並得到均勻分佈的隨機數,代入到繪製函式的引數裡面,使得產生各種各樣的圖案,通過使用函式 putText 顯示文字,最後通過迴圈,產生動態效果。
2、程式碼實現
#include "stdafx.h"
/**
* @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_height/2;
int y_2 = window_height*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;
}
3、執行結果
點選這裡還可以看我錄製的關於程式執行的視訊,用手機拍的,效果不是很好,希望大神們可以給點建議,如何錄製視訊。
密碼為cool
4、用到的類和函式
RNG:
功能:隨機數發生器
例項化一個發生器
RNG rng( 0xFFFFFFFF );
用數值 0xFFFFFFFF 來例項化的一個RNG物件
RNG操作
功能:產生服從均勻分佈的隨機數
a:隨機數產生的左邊界,左邊界為閉區間int RNG::uniform(int a, int b) double RNG::gaussian(double sigma) float RNG::uniform(float a, float b)double RNG::uniform(double a, double b)
b:隨機數產生的右邊界,右邊界為開區間
功能:產生服從高斯分佈的隨機數
double RNG::gaussian(double sigma)
sigma:高斯分佈的標準差polylines:
功能:畫多邊形曲線結構:
void polylines(Mat& img, const Point** pts, const int* npts, int ncontours, bool isClosed, const Scalar& color, int thickness=1, int lineType=8, int shift=0 )
img:輸入圖片pts:多邊形頂點集
npts:要繪製的多邊形頂點數目
ncontours:要繪製的多邊形數目
isClosed:繪製的曲線是否閉合
color:顏色值
thickness:線的粗細程度,如果為負數,則說明圓內被填充。
lineType:線的型別,預設為8聯通
getTextSize:
功能:計算一個文字字串的寬度和高度結構:
getTextSize(const string& text, int fontFace, double fontScale, int thickness, int* baseLine)
text:文字字串fontFace:字型的型別
fontScale:字型的縮放比例
thickness:字型的粗細
baseLine:不知
putText:
功能:繪製文字結構:
void putText(Mat& img, const string& text, Point org, int fontFace, double fontScale, Scalar color, int thickness=1, int lineType=8, bool bottomLeftOrigin=false )
img:輸入圖片text:繪製的文字
org:文字的左下角將用點 org 指定
fontFace:字型的型別
fontScale:字型的縮放比例
color:字型的顏色
thickness:字型的粗細