- /*
- 功能:展示OpenCV的图像绘制功能
- */
- #include "stdafx.h"
- #include "cv.h"
- #include "highgui.h"
- #include <stdlib.h>
- #include <stdio.h>
- #define NUMBER 100
- #define DELAY 5
- char wndname[] = "Drawing Demo";
- CvScalar random_color(CvRNG* rng)
- {
- int icolor = cvRandInt(rng);
- return CV_RGB(icolor&255, (icolor>>8)&255, (icolor>>16)&255);
- }
- //CV_RGB
- //创建一个色彩值.
- // #define CV_RGB( r, g, b ) cvScalar( (b), (g), (r) )
- //======================================================================
- //RandInt
- //返回 32-bit 无符号整型并更新 RNG
- //unsigned cvRandInt( CvRNG* rng );
- //rng
- //被 cvRNG 初始化的 RNG 状态,被 RandSetRange
- //(虽然, 后面这个函数对我们正讨论的函数的结果没有什么影响)随意地设置。
- //函数 cvRandInt 返回均匀分布的随机 32-bit 无符号整型值并更新 RNG 状态。
- //它和 C 运行库里面的 rand() 函数十分相似,
- //但是它产生的总是一个 32-bit 数而 rand() 返回一个 0 到 RAND_MAX
- //(它是 2**16 或者 2**32, 依赖于操作平台)之间的数。
- //该函数用来产生一个标量随机数,例如点, patch sizes, table indices 等,
- //用模操作可以产生一个确定边界的整数,人和其他特定的边界缩放到 0.. 1可以产生一个浮点数。
- //==============================================================================================
- int main( int argc, char** argv )
- {
- int line_type = CV_AA; // change it to 8 to see non-antialiased graphics
- // Line
- //绘制连接两个点的线段
- //void cvLine( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color,
- // int thickness=1, int line_type=8, int shift=0 );
- //img
- //图像。
- //pt1
- //线段的第一个端点。
- //pt2
- //线段的第二个端点。
- //color
- //线段的颜色。
- //thickness
- //线段的粗细程度。
- //line_type
- //线段的类型。
- //8 (or 0) - 8-connected line(8邻接)连接 线。
- //4 - 4-connected line(4邻接)连接线。
- //CV_AA - antialiased 线条。
- //shift
- //坐标点的小数点位数。
- //函数cvLine 在图像中的点1和点2之间画一条线段。
- //线段被图像或感兴趣的矩形(ROI rectangle)所裁剪。
- //对于具有整数坐标的non-antialiasing 线条,
- //使用8-连接或者4-连接Bresenham 算法。画粗线条时结尾是圆形的。
- //画 antialiased 线条使用高斯滤波。要指定线段颜色,用户可以使用使用宏CV_RGB( r, g, b )。
- int i;
- CvPoint pt1,pt2;
- double angle;
- CvSize sz;
- CvPoint ptt[6];
- CvPoint* pt[2];
- int arr[2];
- CvFont font;
- CvRNG rng;
- int width = 1000, height = 700;
- int width3 = width*3, height3 = height*3;
- CvSize text_size;
- int ymin = 0;
- // Load the source image
- IplImage* image = cvCreateImage( cvSize(width,height), 8, 3 );
- // CreateImage
- //创建头并分配数据
- //IplImage* cvCreateImage( CvSize size, int depth, int channels );
- //size
- //图像宽、高.
- //depth
- //图像元素的位深度,可以是下面的其中之一:
- //IPL_DEPTH_8U - 无符号8位整型
- //IPL_DEPTH_8S - 有符号8位整型
- //IPL_DEPTH_16U - 无符号16位整型
- //IPL_DEPTH_16S - 有符号16位整型
- //IPL_DEPTH_32S - 有符号32位整型
- //IPL_DEPTH_32F - 单精度浮点数
- //IPL_DEPTH_64F - 双精度浮点数
- //channels
- //每个元素(像素)的颜色通道数量.
- //可以是 1, 2, 3 或 4.通道是交叉存取的,
- //例如通常的彩色图像数据排列是:
- //b0 g0 r0 b1 g1 r1 ...
- //虽然通常 IPL 图象格式可以存贮非交叉存取的图像,
- //并且一些OpenCV 也能处理他, 但是这个函数只能创建交叉存取图像.
- //函数 cvCreateImage 创建头并分配数据,这个函数是下列的缩写型式
- //header = cvCreateImageHeader(size,depth,channels);
- //cvCreateData(header); //只是创建空间,并不会初始化空间内的数据
- IplImage* image2;
- // Create a window
- cvNamedWindow(wndname, 1 );
- // cvNamedWindow
- //
- //创建窗口
- //int cvNamedWindow( const char* name, int flags=CV_WINDOW_AUTOSIZE );
- //name
- //窗口的名字,它被用来区分不同的窗口,并被显示为窗口标题。
- //flags
- //窗口属性标志,为1时表示会根据图像自动调整窗口大小。
- //目前唯一支持的标志是CV_WINDOW_AUTOSIZE。当这个标志被设置后,
- //用户不能手动改变窗口大小,窗口大小会自动调整以适合被显示图像(参考cvShowImage)。
- //函数cvNamedWindow创建一个可以放置图像和trackbar的窗口。
- //被创建的窗口可以通过它们的名字被引用。
- //如果已经存在这个名字的窗口,这个函数将不做任何事情。
- cvZero( image );
- //将要显示的矩阵置零,即显示黑色
- cvShowImage(wndname,image);
- //cvShowImage
- //
- //在指定窗口中显示图像
- //void cvShowImage( const char* name, const CvArr* image );
- //name
- //窗口的名字。
- //image
- //被显示的图像。
- //函数cvShowImage 在指定窗口中显示图像。
- //如果窗口创建的时候被设定标志CV_WINDOW_AUTOSIZE,那么图像将以原始尺寸显示;
- //否则,图像将被伸缩以适合窗口大小。
- rng = cvRNG((unsigned)-1);
- pt[0] = &(ptt[0]);
- pt[1] = &(ptt[3]);
- arr[0] = 3;
- arr[1] = 3;
- for (i = 0; i< NUMBER; i++)
- {
- pt1.x=cvRandInt(&rng) % width3 - width;
- pt1.y=cvRandInt(&rng) % height3 - height;
- pt2.x=cvRandInt(&rng) % width3 - width;
- pt2.y=cvRandInt(&rng) % height3 - height;
- //Line
- //绘制连接两个点的线段
- //void cvLine( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color,
- // int thickness=1, int line_type=8, int shift=0 );
- //img
- //图像。
- //pt1
- //线段的第一个端点。
- //pt2
- //线段的第二个端点。
- //color
- //线段的颜色。
- //thickness
- //线段的粗细程度。
- //line_type
- //线段的类型。
- //8 (or 0) - 8-connected line(8邻接)连接 线。
- //4 - 4-connected line(4邻接)连接线。
- //CV_AA - antialiased 线条。
- //shift
- //坐标点的小数点位数。
- //函数cvLine 在图像中的点1和点2之间画一条线段。
- //线段被图像或感兴趣的矩形(ROI rectangle)所裁剪。
- //对于具有整数坐标的non-antialiasing 线条,使用8-连接或者4-连接Bresenham 算法。
- //画粗线条时结尾是圆形的。画 antialiased 线条使用高斯滤波。
- //要指定线段颜色,用户可以使用使用宏CV_RGB( r, g, b )。
- //cvLine( image, pt1, pt2, random_color(&rng), cvRandInt(&rng)%10, line_type, 0 );
- cvLine( image, pt1, pt2, random_color(&rng), cvRandInt(&rng)%10, line_type, 0 );
- cvShowImage(wndname,image);
- //cvWaitKey
- //
- //等待按键事件
- //int cvWaitKey( int delay=0 );
- //delay
- //延迟的毫秒数。
- //函数cvWaitKey无限制的等待按键事件(delay<=0时);
- //或者延迟"delay"毫秒。返回值为被按键的值,如果超过指定时间则返回-1。
- //注释:这个函数是HighGUI中唯一能够获取和操作事件的函数,
- //所以在一般的事件处理中,它需要周期地被调用,
- //除非HighGUI被用在某些能够处理事件的环境中。
- //译者注:比如在MFC环境下,这个函数不起作用。
- cvWaitKey(DELAY);
- }
- for (i = 0; i< NUMBER; i++)
- {
- pt1.x=cvRandInt(&rng) % width3 - width;
- pt1.y=cvRandInt(&rng) % height3 - height;
- pt2.x=cvRandInt(&rng) % width3 - width;
- pt2.y=cvRandInt(&rng) % height3 - height;
- //Rectangle
- //绘制简单、指定粗细或者带填充的 矩形
- //void cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color,
- // int thickness=1, int line_type=8, int shift=0 );
- //img
- //图像.
- //pt1
- //矩形的一个顶点。
- //pt2
- //矩形对角线上的另一个顶点
- //color
- //线条颜色 (RGB) 或亮度(灰度图像 )(grayscale image)。
- //thickness
- //组成矩形的线条的粗细程度。取负值时(如 CV_FILLED)函数绘制填充了色彩的矩形。
- //line_type
- //线条的类型。见cvLine的描述
- //shift
- //坐标点的小数点位数。
- //
- //函数 cvRectangle 通过对角线上的两个顶点绘制矩形。
- cvRectangle( image,pt1, pt2, random_color(&rng), cvRandInt(&rng)%10-1, line_type, 0 );
- cvShowImage(wndname,image);
- cvWaitKey(DELAY);
- }
- for (i = 0; i< NUMBER; i++)
- {
- pt1.x=cvRandInt(&rng) % width3 - width;
- pt1.y=cvRandInt(&rng) % height3 - height;
- sz.width =cvRandInt(&rng)%200;
- sz.height=cvRandInt(&rng)%200;
- angle = (cvRandInt(&rng)%1000)*0.180;
- //Ellipse
- //绘制椭圆圆弧和椭圆扇形。
- //void cvEllipse( CvArr* img, CvPoint center, CvSize axes, double angle,
- // double start_angle, double end_angle, CvScalar color,
- // int thickness=1, int line_type=8, int shift=0 );
- //img
- //图像。
- //center
- //椭圆圆心坐标。
- //axes
- //轴的长度。
- //angle
- //偏转的角度。
- //start_angle
- //圆弧起始角的角度。.
- //end_angle
- //圆弧终结角的角度。
- //color
- //线条的颜色。
- //thickness
- //线条的粗细程度。
- //line_type
- //线条的类型,见CVLINE的描述。
- //shift
- //圆心坐标点和数轴的精度。
- //具体参数显示属性参考:http://www.opencv.org.cn/index.php/Cxcore%E7%BB%98%E5%9B%BE%E5%87%BD%E6%95%B0#Rectangle
- cvEllipse( image, pt1, sz, angle, angle - 100, angle + 200,
- random_color(&rng), cvRandInt(&rng)%10-1, line_type, 0 );
- cvShowImage(wndname,image);
- cvWaitKey(DELAY);
- }
- for (i = 0; i< NUMBER; i++)
- {
- pt[0][0].x=cvRandInt(&rng) % width3 - width;
- pt[0][0].y=cvRandInt(&rng) % height3 - height;
- pt[0][1].x=cvRandInt(&rng) % width3 - width;
- pt[0][1].y=cvRandInt(&rng) % height3 - height;
- pt[0][2].x=cvRandInt(&rng) % width3 - width;
- pt[0][2].y=cvRandInt(&rng) % height3 - height;
- pt[1][0].x=cvRandInt(&rng) % width3 - width;
- pt[1][0].y=cvRandInt(&rng) % height3 - height;
- pt[1][1].x=cvRandInt(&rng) % width3 - width;
- pt[1][1].y=cvRandInt(&rng) % height3 - height;
- pt[1][2].x=cvRandInt(&rng) % width3 - width;
- pt[1][2].y=cvRandInt(&rng) % height3 - height;
- //PolyLine
- //绘制简单线段或折线。
- //void cvPolyLine( CvArr* img, CvPoint** pts, int* npts, int contours, int is_closed,
- // CvScalar color, int thickness=1, int line_type=8, int shift=0 );
- //img
- //图像。
- //pts
- //折线的顶点指针数组。
- //npts
- //折线的定点个数数组。也可以认为是pts指针数组的大小
- //contours
- //折线的线段数量。
- //is_closed
- //指出多边形是否封闭。如果封闭,函数将起始点和结束点连线。
- //color
- //折线的颜色。
- //thickness
- //线条的粗细程度。
- //line_type
- //线段的类型。参见cvLine。
- //shift
- //顶点的小数点位数。
- //函数cvPolyLine 绘制一个简单直线或折线。
- cvPolyLine( image, pt, arr, 2, 1, random_color(&rng), cvRandInt(&rng)%10, line_type, 0 );
- cvShowImage(wndname,image);
- cvWaitKey(DELAY);
- }
- for (i = 0; i< NUMBER; i++)
- {
- pt[0][0].x=cvRandInt(&rng) % width3 - width;
- pt[0][0].y=cvRandInt(&rng) % height3 - height;
- pt[0][1].x=cvRandInt(&rng) % width3 - width;
- pt[0][1].y=cvRandInt(&rng) % height3 - height;
- pt[0][2].x=cvRandInt(&rng) % width3 - width;
- pt[0][2].y=cvRandInt(&rng) % height3 - height;
- pt[1][0].x=cvRandInt(&rng) % width3 - width;
- pt[1][0].y=cvRandInt(&rng) % height3 - height;
- pt[1][1].x=cvRandInt(&rng) % width3 - width;
- pt[1][1].y=cvRandInt(&rng) % height3 - height;
- pt[1][2].x=cvRandInt(&rng) % width3 - width;
- pt[1][2].y=cvRandInt(&rng) % height3 - height;
- //FillPoly
- //填充多边形内部
- //void cvFillPoly( CvArr* img, CvPoint** pts, int* npts, int contours,
- // CvScalar color, int line_type=8, int shift=0 );
- //img
- //图像。
- //pts
- //指向多边形的数组指针。
- //npts
- //多边形的顶点个数的数组。
- //contours
- //组成填充区域的线段的数量。
- //color
- //多边形的颜色。
- //line_type
- //组成多边形的线条的类型。
- //shift
- //顶点坐标的小数点位数。
- //函数cvFillPoly用于一个单独被多边形轮廓所限定的区域内进行填充。
- //函数可以填充复杂的区域,例如,有漏洞的区域和有交叉点的区域等等。
- cvFillPoly( image, pt, arr, 2, random_color(&rng), line_type, 0 );
- cvShowImage(wndname,image);
- cvWaitKey(DELAY);
- }
- for (i = 0; i< NUMBER; i++)
- {
- pt1.x=cvRandInt(&rng) % width3 - width;
- pt1.y=cvRandInt(&rng) % height3 - height;
- //Circle
- //绘制圆形。
- //void cvCircle( CvArr* img, CvPoint center, int radius, CvScalar color,
- // int thickness=1, int line_type=8, int shift=0 );
- //img
- //图像。
- //center
- //圆心坐标。
- //radius
- //圆形的半径。
- //color
- //线条的颜色。
- //thickness
- //如果是正数,表示组成圆的线条的粗细程度。否则,表示圆是否被填充。
- //line_type
- //线条的类型。见 cvLine 的描述
- //shift
- //圆心坐标点和半径值的小数点位数。
- //函数cvCircle绘制或填充一个给定圆心和半径的圆。圆被感兴趣矩形所裁剪。
- //若指定圆的颜色,可以使用宏 CV_RGB ( r, g, b )。
- cvCircle( image, pt1, cvRandInt(&rng)%300, random_color(&rng),
- cvRandInt(&rng)%10-1, line_type, 0 );
- cvShowImage(wndname,image);
- cvWaitKey(DELAY);
- }
- for (i = 1; i< NUMBER; i++)
- {
- pt1.x=cvRandInt(&rng) % width3 - width;
- pt1.y=cvRandInt(&rng) % height3 - height;
- //InitFont
- //初始化字体结构体。
- //void cvInitFont( CvFont* font, int font_face, double hscale,
- // double vscale, double shear=0,
- // int thickness=1, int line_type=8 );
- //font
- //被初始化的字体结构体。
- //font_face
- //字体名称标识符。只是Hershey 字体集( http://sources.isc.org/utils/misc/hershey-font.txt )的一个子集得到支持。
- //CV_FONT_HERSHEY_SIMPLEX - 正常大小无衬线字体。
- //CV_FONT_HERSHEY_PLAIN - 小号无衬线字体。
- //CV_FONT_HERSHEY_DUPLEX - 正常大小无衬线字体。( 比CV_FONT_HERSHEY_SIMPLEX更复杂)
- //CV_FONT_HERSHEY_COMPLEX - 正常大小有衬线字体。
- //CV_FONT_HERSHEY_TRIPLEX - 正常大小有衬线字体 ( 比CV_FONT_HERSHEY_COMPLEX更复杂)
- //CV_FONT_HERSHEY_COMPLEX_SMALL - CV_FONT_HERSHEY_COMPLEX 的小译本。
- //CV_FONT_HERSHEY_SCRIPT_SIMPLEX - 手写风格字体。
- //CV_FONT_HERSHEY_SCRIPT_COMPLEX - 比CV_FONT_HERSHEY_SCRIPT_SIMPLEX更复杂。
- //这个参数能够由一个值和可选择的CV_FONT_ITALIC字体标记合成,就是斜体字。
- //hscale
- //字体宽度。如果等于1.0f,字符的宽度是最初的字体宽度。如果等于0.5f,字符的宽度是最初的字体宽度的一半。
- //vscale
- //字体高度。如果等于1.0f,字符的高度是最初的字体高度。如果等于0.5f,字符的高度是最初的字体高度的一半。
- //shear
- //字体的斜度。当值为0时 ,字符不倾斜;当值为1.0f时,字体倾斜≈45度,等等。厚度让字母着重显示。函数cvLine用于绘制字母。
- //thickness
- //字体笔划的粗细程度。
- //line_type
- //字体笔划的类型,参见cvLine。
- //函数cvInitFont初始化字体结构体,字体结构体可以被传递到文字显示函数中。
- cvInitFont( &font, cvRandInt(&rng) % 8,
- (cvRandInt(&rng)%100)*0.05+0.1,
- (cvRandInt(&rng)%100)*0.05+0.1,
- (cvRandInt(&rng)%5)*0.1, cvRound(cvRandInt(&rng)%10),
- line_type );
- //PutText
- //在图像中显示文本字符串。
- //void cvPutText( CvArr* img, const char* text, CvPoint org, const CvFont* font, CvScalar color );
- //img
- //输入图像。
- //text
- //要显示的字符串。
- //org
- //第一个字符左下角的坐标。
- //font
- //字体结构体。
- //color
- //文本的字体颜色。
- //函数cvPutText将具有指定字体的和指定颜色的文本加载到图像中。
- //加载到图像中的文本被感兴趣的矩形框(ROI rectangle)剪切。
- //不属于指定字体库的字符用矩形字符替代显示。
- cvPutText( image, "Testing text rendering!", pt1, &font, random_color(&rng));
- cvShowImage(wndname,image);
- cvWaitKey(DELAY);
- }
- cvInitFont( &font, CV_FONT_HERSHEY_COMPLEX, 3, 3, 0.0, 5, line_type );
- //GetTextSize
- //获得字符串的宽度和高度。
- //void cvGetTextSize( const char* text_string, const CvFont* font, CvSize* text_size, int* baseline );
- //font
- //字体结构体
- //text_string
- //输入字符串。
- //text_size
- //合成字符串的字符的大小。文本的高度不包括基线以下的部分。
- //baseline
- //相对于文字最底部点的基线的Y坐标。
- //函数cvGetTextSize是用于在指定字体时计算字符串的绑定区域(binding rectangle)。
- cvGetTextSize( "I LOVE GuaGua!", &font, &text_size, &ymin );
- pt1.x = (width - text_size.width)/2;
- pt1.y = (height + text_size.height)/2;
- // CloneImage
- //制作图像的完整拷贝
- //IplImage* cvCloneImage( const IplImage* image );
- //image
- //原图像.
- //函数 cvCloneImage 制作图像的完整拷贝包括头、ROI和数据
- image2 = cvCloneImage(image);
- for( i = 0; i < 255; i++ )
- {
- //SubS
- //计算数组和数量之间的差
- //void cvSubS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );
- //src
- //原数组.
- //value
- //被减的数量.
- //dst
- //输出数组.
- //mask
- //操作覆盖面( 8-bit 单通道数组); 只有覆盖面指定的输出数组被修改
- //函数 cvSubS 从原数组的每个元素中减去一个数量:
- //dst(I)=src(I)-value if mask(I)!=0
- //除覆盖面外所有数组都必须有相同的类型,相同的大小(或ROI大小)。
- //===============================================================
- //cvScalarAll()
- //四个纯量都是同一个输入的数字,通常为灰阶的形态
- //cvScalarAll(输入全部纯量值的数据)
- cvSubS( image2, cvScalarAll(i), image, 0 );
- cvPutText( image, "I LOVE GuaGua!", pt1, &font, CV_RGB(255,i,i));
- cvShowImage(wndname,image);
- cvWaitKey(DELAY);
- }
- // Wait for a key stroke; the same function arranges events processing
- cvWaitKey(0);
- cvReleaseImage(ℑ);
- cvReleaseImage(&image2);
- cvDestroyWindow(wndname);
- return 0;
- }