您的位置:首页 > 运维架构

图像绘制功能【OpenCV学习笔记5】

2010-09-28 17:19 585 查看
/* 	
功能:展示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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: