【OpenCV 学习】自带示例:随机数发生器&绘制文字 代码注释解析

来源:互联网 发布:淘宝报名活动有哪些 编辑:程序博客网 时间:2024/05/21 10:55

最近开始尝试学习OpenCV,确实发现了这个东西很有意思。

市面上的书基本上都是关于OpenCV 1.0版本的,包括《学习OpenCV》等,不过考虑到2.0+版本更方(sha)便(gua),我就没有去搞1.0版本,所以那个什么IplImage的,我是真的不懂,看着那么复杂的代码就头大,相较而言Mat就亲切多了。


然后就是发现OpenCV的中文文档非常不错啊(虽然是翻译的,但偷懒没去看英文,英语很捉急。。。),尤其是教程(Tutorial)那一块,示例详尽,解说简洁,没有大讲特讲原理(这些可以通过其他教材来弥补),而是尽快的跑一段程序出来,这才是最重要的!


然后就是我看到随机数发生器和绘制文字那一小节的时候,一方面看到网站上没有给出完整的代码(那个链接貌似失效了),就在网上搜了代码出来(本地文件夹里面也有,在...\opencv\sources\samples\cpp\tutorial_code\core\Matrix目录下面,Drawing_2.cpp),另一方面觉得那个demo效果很酷炫啊,尤其是最后的渐变消失的思想很有意思,另外也考虑到要稍微做点小结,不然看过印象太浅,就自己打算把哥哥随机图形的生成过程稍微解析一下,虽然教程里面已经有示例了,而且教程的前一篇就是各个图形的生成过程,但是。。。


代码先一段一段的贴,文末会附上完整的代码。


首先先大概说一下几个结构体。

Point

Point pt;pt.x = 10;pt.y = 8;
就是一个二维点的坐标。


Scalar

Scalar( a, b, c )

是一个一维数组,最多有四个元素,对应的应该是像素的channel(最多可以有4个channel),一般如果使用RGB的话,用不到第四个参数就不用管它了,同样的如果是黑白的,那就只需要第一个值就够了。

所以Scalar这个类型被大量用于传递像素值。

不过需要注意的是,如果使用上述代码中的定义,a,b,c对应的分别是B,G,R,貌似OpenCV中都是使用BGR,而不是RGB的。


以下是全部的头文件、预定义、函数声明。

#include <iostream>#include <stdio.h>using namespace cv;/// Global Variablesconst 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 headersstatic 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 randomColor * @brief Produces a random color given a random object */static Scalar randomColor( RNG& rng )//这里rng是一个随机数发生器{  int icolor = (unsigned) rng;//将随机数以无符号形式赋给icolor  return Scalar( icolor&255, (icolor>>8)&255, (icolor>>16)&255 );//随机的颜色}

最后return的时候,返回的正是之前提到的Scalar,括号里的3个数分别对应B,G,R。

括号里使用了C语言的位运算, 

icolor&255是与操作,事实上将icolor的低8位保留了下来,作为B channel的值

(icolor >> 8) & 255是右移再与的操作,将随机数icolor右移8位之后,保留现在的低8位

(icolor >> 16) & 255是右移再与的操作,将随机数icolor右移16位之后,保留现在的低8位


这样操作完的结果,就是根据随机的一个数,分别取了其末24位作为三个channel的值,从而就生成了一种随机的颜色。


随机直线函数

/** * @function 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++ )//NUMBER 定义为 100,表示的是要随机画的直线条数  {    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;}

函数解释:

x_1,x_2,y_1,y_2均在开头定义了

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;

另外,代码中调用了rng.uniform(a, b),这里实质上就是产生了一个[a, b)的随机值


核心的一句

line( image, pt1, pt2, randomColor(rng), rng.uniform(1, 10), 8 );
意思是:

  • 画一条从点 pt1 到点 pt2 的直线段
  • 此线段将被画到图像 img 上
  • 线的颜色由 randomColor(rng) 来定义(这里是随机颜色)
  • 线的粗细由 rng.uniform(1,10) 设定(这里是随机粗细)
  • 此线为8联通 (lineType = 8)

然后用imshow在图像上显示就可以了。


随机长方形函数

/** * @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;}

这里其他部分和画直线的函数基本一致,核心的一句

rectangle( image, pt1, pt2, randomColor(rng), MAX( thickness, -1 ), lineType );
意思是:

  • 矩形将被画到图像 image 上
  • 矩形两个对角顶点为 pt1 和 pt2
  • 矩形的颜色为 randomColor(rng),这里是随机颜色 
  • 线条的粗细是MAX(thickness, -1),取得二者较大值,如果最后结果不是-1,就表示的是线条的粗细,如果线粗为 -1, 此矩形将被填充

随机椭圆函数

/** * @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;<span style="white-space:pre"></span>//定义了一个中心点    center.x = rng.uniform(x_1, x_2);    center.y = rng.uniform(y_1, y_2);        Size axes;<span style="white-space:pre"></span>//定义了一个长方形    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;}

画椭圆的话参数稍微多一些,

    ellipse( image, center, axes, angle, angle - 100, angle + 200,             randomColor(rng), rng.uniform(-1,9), lineType );
意思是:

  • 椭圆将被画到图像 image 上
  • 椭圆中心为点 center 并且大小位于矩形 axes 内
  • 椭圆旋转角度为 angle
  • 椭圆扩展的弧度从 angle - 100 度到 angle + 100 度
  • 图形颜色为 randomColor(rng) ,即随机颜色
  • 椭圆的线粗为rng.uniform(-1, 9)



随机多边形函数

/** * @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;}    

要画随机的多边形当然得随机产生一些折点。

核心的一句:

polylines(image, ppt, npt, 2, true, randomColor(rng), rng.uniform(1,10), lineType);
意思是:

  • 多边形将被画到图像 image 上
  • 多边形的顶点集为 ppt
  • 要绘制的多边形顶点数目为 npt
  • 要绘制的多边形数量为 2
  • 该多边形是封闭的
  • 多边形的颜色定义为 randomColor(rng)
  • 多边形的线条粗细是rng.uniform(1, 10)


随机填充多边形函数

/** * @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;}

这个函数产生的是随机的填充的多边形,核心语句基本同上:

fillPoly( image, ppt, npt, 2, randomColor(rng), lineType );
意思是:

  • 多边形将被画到图像 iamge 上
  • 多边形的顶点集为 ppt
  • 要绘制的多边形顶点数目为 npt
  • 要绘制的多边形数量为 2
  • 多边形的颜色定义为randomColor(rng)

随机圆函数
/** * @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;}

随机产生圆,核心语句:
circle( image, center, rng.uniform(0, 300), randomColor(rng),            rng.uniform(-1, 9), lineType );
意思是:
  • 圆将被画到图像  image 上
  • 圆心由点 center 定义
  • 圆的半径为: rng.uniform(0, 300)
  • 圆的颜色为: randomColor(rng)
  • 线粗定义为 rng.uniform(-1, 9),当线粗为-1时,圆将被填充

随机文本函数

/** * @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;}

函数功能是按照随机的格式位置显示字符串“Testing test rendering”

核心的一句:

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);
意思是:

  • 在 image 上绘制文字 “Testing text rendering” 。
  • 文字的左下角将用点 org 指定。
  • 字体参数是用一个在 [0 , 8) 之间的整数来定义。
  • 字体的缩放比例是用表达式 rng.uniform(0, 100)*0.05 + 0.1 指定,表示它的范围是 [0.1, 5.1)。
  • 字体的颜色是随机的 (记为 randomColor(rng))。
  • 字体的粗细范围是从 1 到 10, 表示为 rng.uniform(1,10) 。


结束文本输出函数

/** * @function Displaying_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 forever!", org, CV_FONT_HERSHEY_COMPLEX, 3,             Scalar(i, i, 255), 5, lineType );            imshow( window_name, image2 );    if( waitKey(DELAY) >= 0 )       { return -1; }  }  return 0;}

其中的for循环产生了一种渐变的效果,实现方式也很有意思。

首先,getTextSize取得了某一种特定格式字符串的尺寸(长,宽),

核心语句:

putText( image2, "OpenCV forever!", org, CV_FONT_HERSHEY_COMPLEX, 3,             Scalar(i, i, 255), 5, lineType );
意思是:

  • 在 image2 上绘制文字 “OpenCV forever!” 。
  • 文字的左下角将用点 org 指定。
  • 字体固定为CV_FONT_HERSHEY_COMPLEX。
  • 字体的缩放比例固定为3
  • 字体的颜色是随i变化的, 最初i = 0的时候,颜色是Scalar(0, 0, 255),根据BGR对应可知,最初颜色是纯红色,之后i逐渐增大,导致的结果是字体颜色像白色渐变,最终变成纯白色
  • 字体的粗细固定为5

如何实现渐变?

上面已经说了颜色的渐变实现方式,从红色渐变到白色就是同时增加另外两个channel的分量值,那其他的地方要渐变到黑色怎么做呢?

根据代码可以看到,有这么两句话:

image2 = image - Scalar::all(i);
imshow( window_name, image2 );
第一句话,将Image减去 i 不断增大的全 i 图像,可以料想image必定是不断的全面往黑色靠近。。。

第二句话将减去全 i 图像的新image2显示到原来的窗口,而putText的时候是显示到image2上面的,所以

实质上,渐变效果的形成就是通过不断的刷新窗口图像达到的(博主是第一次接触到这个尴尬,感觉很新鲜的样子,见怪不怪的牛牛们莫喷。。。)


最后附上完整的代码:

#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <iostream>#include <stdio.h>using namespace cv;/// Global Variablesconst 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 headersstatic 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( int argc, char** argv ){  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 ){  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;}/** * @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 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 forever!", org, CV_FONT_HERSHEY_COMPLEX, 3,             Scalar(i, i, 255), 5, lineType );            imshow( window_name, image2 );    if( waitKey(DELAY) >= 0 )       { return -1; }  }  return 0;}

再次强烈推荐OpenCV的文档!大笑

0 0
原创粉丝点击