從頭開始opencv(九)——core:random generator and text
從頭開始opencv(九)——core:random generator and text
Goals
- Use the Random Number generator class and how to get a random number from a uniform distribution(使用Random Number generator class以及如何從均勻分佈中獲取隨機數)
- Display text on an OpenCV window by using the function
cv::putText
Code
In this tutorial, we intend to use *random* values for the drawing parameters. Also, we intend to populate our image with a big number of geometric figures. Since we will be initializing them in a random fashion, this process will be automatic and made by using *loops* .
和上一章節相比,我們使用隨機數來進行圖形的生成,同時,我們打算用大量幾何圖形來填充影像。
Explanation
RNG rng( 0xFFFFFFFF );
RNG implements a random number generator. In this example, rng is a RNG element initialized with the value 0xFFFFFFFF
RNG是一個隨機數生成器。在上面這個程式碼中,rng是初始值為0xFFFFFFFF的RNG型別的資料。
RNG類可以壓縮一個64位的i整數並得到scalar和array的隨機數。隨機數的產生採用的是Multiply-With-Carry演算法和Ziggurat演算法。
其建構函式的初始化可以傳入一個64位的整型引數作為隨機數產生器的初值。next可以取出下一個隨機數,uniform函式可以返回指定範圍的隨機數,Gaussian函式返回一個高斯隨機數,fill則用隨機數填充矩陣。
Then we create a matrix initialized to zeros (which means that it will appear as black), specifying its height, width and its type
然後我們建立一個初始化為0的矩陣,並指定其高度、寬度和型別。
Mat image = Mat::zeros( window_height, window_width, CV_8UC3 );
imshow( window_name, image );
然後我們開始瘋狂畫東西:
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 = Displaying_Random_Text( image, window_name, rng );
if( c != 0 ) return 0;
c = Displaying_Big_End( image, window_name, rng );
上述程式碼中的每個Drawing_Random_Lines()
之類的程式碼都是自定義的,函式原型如下:
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
次,也就是說,總工會生成NUMBER
條直線。
可以知道,直線的兩個端點為pt1
和pt2
。
程式碼rng.uniform(x_1,x_2)
的意思是生成一個[x_1,x_2)範圍內的隨機數。
static Scalar randomColor( RNG& rng )
{
int icolor = (unsigned) rng;
return Scalar( icolor&255, (icolor>>8)&255, (icolor>>16)&255 );
}
這段程式碼用於生成隨機的顏色。
生成如下所示的圖片:
Drawing_Random_Rectangles()
和Drawing_Random_Lines()
生成方法類似:
int Drawing_Random_Rectangles(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);
rectangle(image,pt1,pt2,randomColor(rng),rng.uniform(1, 10),lineType);
/*if (waitKey(DELAY) >= 0)
{
return -1;
}*/
}
imshow(window_name, image);
waitKey(0);
return 0;
}
Display_Random_Text()
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;
}
完整程式碼
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#define NUMBER 5
#define x_1 100
#define x_2 400
#define y_1 100
#define y_2 400
#define DELAY 0
#define window_width 500
#define window_height 500
using namespace cv;
int Drawing_Random_Lines(Mat image, char* window_name, RNG rng);
int Drawing_Random_Rectangles(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);
static Scalar randomColor(RNG& rng);
int main()
{
RNG rng(0xFFFFFFFF);
Mat image = Mat::zeros(500, 500, CV_8UC3);
imshow("first window", image);
waitKey(0);
char window_name[] = "lines window";
int c = Drawing_Random_Lines(image, window_name, rng);
image = Mat::zeros(500, 500, CV_8UC3);
if (c != 0) return 0;
char window_name2[] = "rectangle window";
c = Drawing_Random_Rectangles(image, window_name2, rng);
image = Mat::zeros(500, 500, CV_8UC3);
if (c != 0) return 0;
char window_name3[] = "text window";
c = Displaying_Random_Text(image, window_name3, rng);
if (c != 0) return 0;
image = Mat::zeros(500, 500, CV_8UC3);
c = Drawing_Random_Lines(image, window_name, rng);
c = Drawing_Random_Rectangles(image, window_name, rng);
c = Displaying_Random_Text(image, window_name, rng);
c = Displaying_Big_End(image, window_name, rng);
return 0;
}
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);
/*if (waitKey(DELAY) >= 0)
{
return -1;
}*/
}
imshow(window_name, image);
waitKey(0);
return 0;
}
int Drawing_Random_Rectangles(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);
rectangle(image,pt1,pt2,randomColor(rng),rng.uniform(1, 10),lineType);
/*if (waitKey(DELAY) >= 0)
{
return -1;
}*/
}
imshow(window_name, image);
waitKey(0);
return 0;
}
int Displaying_Random_Text(Mat image, char* window_name, RNG rng)
{
int lineType = 8;
Point org;
for (int i = 1; i < NUMBER; i++)
{
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);
/*if (waitKey(DELAY) >= 0)
{
return -1;
}*/
}
imshow(window_name, image);
waitKey(0);
return 0;
}
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 < 10; 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;
}
static Scalar randomColor(RNG& rng)
{
int icolor = (unsigned)rng;
return Scalar(icolor & 255, (icolor >> 8) & 255, (icolor >> 16) & 255);
}
總結:在具體實現過程中,可以發現其實是偽隨機,因為不管怎樣,我們生成的隨機數始終是一個值。
對官方教程的改進
因為RNG生成的隨機數是偽隨機的,細究原因,很容易發現和經典C語言生成隨機數的侷限是一致的,當種子固定不變時,生成的隨機數自然始終是一個了。
如此,只要改變每次的種子即可。將原來的RNG生成程式碼RNG rng( 0xFFFFFFFF );
改為:
RNG rng((unsigned)time(NULL));
當然得加上相應標頭檔案:
完整程式碼如下:
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <ctime>
#define NUMBER 5
#define x_1 100
#define x_2 400
#define y_1 100
#define y_2 400
#define DELAY 0
#define window_width 500
#define window_height 500
using namespace cv;
int Drawing_Random_Lines(Mat image, char* window_name, RNG rng);
int Drawing_Random_Rectangles(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);
static Scalar randomColor(RNG& rng);
int main()
{
/*RNG rng(0xFFFFFFFF);*/
RNG rng((unsigned)time(NULL));
Mat image = Mat::zeros(500, 500, CV_8UC3);
imshow("first window", image);
waitKey(0);
char window_name[] = "lines window";
int c = Drawing_Random_Lines(image, window_name, rng);
image = Mat::zeros(500, 500, CV_8UC3);
if (c != 0) return 0;
char window_name2[] = "rectangle window";
c = Drawing_Random_Rectangles(image, window_name2, rng);
image = Mat::zeros(500, 500, CV_8UC3);
if (c != 0) return 0;
char window_name3[] = "text window";
c = Displaying_Random_Text(image, window_name3, rng);
if (c != 0) return 0;
image = Mat::zeros(500, 500, CV_8UC3);
c = Drawing_Random_Lines(image, window_name, rng);
c = Drawing_Random_Rectangles(image, window_name, rng);
c = Displaying_Random_Text(image, window_name, rng);
c = Displaying_Big_End(image, window_name, rng);
return 0;
}
int Drawing_Random_Lines(Mat image, char* window_name, RNG rng)
{
rng((unsigned)time(NULL));
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);
/*if (waitKey(DELAY) >= 0)
{
return -1;
}*/
}
imshow(window_name, image);
waitKey(0);
return 0;
}
int Drawing_Random_Rectangles(Mat image, char* window_name, RNG rng)
{
rng((unsigned)time(NULL));
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);
rectangle(image,pt1,pt2,randomColor(rng),rng.uniform(1, 10),lineType);
/*if (waitKey(DELAY) >= 0)
{
return -1;
}*/
}
imshow(window_name, image);
waitKey(0);
return 0;
}
int Displaying_Random_Text(Mat image, char* window_name, RNG rng)
{
rng((unsigned)time(NULL));
int lineType = 8;
Point org;
for (int i = 1; i < NUMBER; i++)
{
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);
/*if (waitKey(DELAY) >= 0)
{
return -1;
}*/
}
imshow(window_name, image);
waitKey(0);
return 0;
}
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 < 10; 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;
}
static Scalar randomColor(RNG& rng)
{
rng((unsigned)time(NULL));
int icolor = (unsigned)rng;
return Scalar(icolor & 255, (icolor >> 8) & 255, (icolor >> 16) & 255);
}
相關文章
- different random numbers generatorrandom
- 從頭開始學習VuexVue
- 從頭開始學習vue-routerVue
- java從頭開始--物件導向1Java物件
- ASP.NET Core - 從Program和Startup開始ASP.NET
- 使用Python從頭開始構建比特幣Python比特幣
- 從零開始,開發一個 Web Office 套件(5):Mouse hover over textWeb套件
- 技術的採用必須從頭開始
- 從頭開始的Java學習Day05Java
- 從頭開始,手寫android應用框架(一)Android框架
- 併發程式設計從零開始(九)-ConcurrentSkipListMap&Set程式設計
- 從頭開始學習 Kubernetes 核心原理和術語
- 從頭開始瞭解PyTorch的簡單實現PyTorch
- 不怕從零開始,只怕從未開始!
- 小白開學Asp.Net Core 《九》ASP.NET
- 從零開始學Python:第九課-常用資料結構之字串Python資料結構字串
- 從零開始實現ASP.NET Core MVC的外掛式開發(九) - 升級.NET 5及啟用預編譯檢視ASP.NETMVC編譯
- 從零開始
- Core Text 程式設計指南程式設計
- 【譯】如何從頭開始搭建React,Webpack4,Babel7工程ReactWebBabel
- Android 從零開始實現RecyclerView分組及粘性頭部效果AndroidView
- 如何使用 Webpack 5 + Babel 從頭開始建立 React 應用程式 - DevDojoWebBabelReactdev
- 今天開始頭腦風暴
- 從零開始寫 Docker(九)---實現 mydocker ps 檢視執行中的容器Docker
- 從頭開始-手把手用webpack4搭建vue/react環境WebVueReact
- 從頭開始,建立Neo4j圖資料庫,詳細版資料庫
- Sebastian Raschka最新部落格:從頭開始,用Llama 2構建Llama 3.2AST
- Implementation of Make-A-Video, new SOTA text to video generator from Meta AI, in PytorchIDEAIPyTorch
- android opencv 前置攝像頭AndroidOpenCV
- OpenCV Core functionality翻譯總結OpenCVFunction
- 從0開始用MavenMaven
- flutter 從零開始-1Flutter
- 從零開始學PythonPython
- Arch! 從安裝開始
- Python Web開發:從 wsgi 開始PythonWeb
- [每日一題] 第九題:從尾到頭列印連結串列每日一題
- [前端漫談_1] 從 for of 聊到 Generator前端
- [前端怪談_1] 從 for of 聊到 Generator前端