从图学起OpenCV

众所周知OpenCV是Intel的一个开放视觉库,此前,没有一个开源的库是针对图像处理的,OpenCV的出现可谓是广大爱好图像处理的童鞋们得福音,通过OpenCV,你不但可以获得深刻的理解而且还能增长你编程的能力,同时你也可以参看OpenCV宝贵的开源代码来实现自己的图像处理算法代码,下面由我来给出一些实例用代码来说话来简略领略一下OpenCV的魅力,代码虽长,但是如果能够静下心来,你就会发现其中的奥妙。

好了下面咱们来看看吧。^_^

首先我们看看下面的这段代码的运行结果如何:

需要注意的是,下面图的顺序就是按照程序中的选项的执行进行标注序号的



图1 显示图片




图2 播放视频




图3-1 原图




图3-2 中值滤波(模糊)




图3-3 高斯(滤波)模糊




图4 高斯金字塔的降采样以及高斯模糊




图5 Canny边缘检测




图6-1  原始图




图6-2 对数极坐标反变换效果图




图 6-3 对数极坐标变换效果图




图7 矩阵的存取以及输出和计算




图 8 ROI示例




图9 矩阵的操作以及计算协方差矩阵和平均值矩阵




图10 图像的尺度变换以及灰度转换




图11 采用cvFlip函数对图像进行旋转




图12-1 画直线




图12 -2 画椭圆和多边形




图13 在图像中显示文字示例(图中为简单字体样式)




图14 OpenCV的XML操作的简单的示例




图15 检测库的版本以及是否支持IPP




图16 采用短线段以及鼠标事件进行绘图




图17 几种滤波方法示例




图 18 咱们程序的主界面


好了,终于把图给看完了,接下来咱们来看看代码撒

// OpenImgTest.cpp : 定义控制台应用程序的入口点。
//
/*
*	author:		xizero00
*   mail:		xizero00@163.com
*	created:	2011/08/16
*	purpose:	OpenCV Sample
*/

#include "stdafx.h"
#include "highgui.h"
#include "cv.h"

void ReadImageFile();
void ReadAVIFile();
void MyTrackbar( int pos );
void CaptureAndSmooth();
void PyrDown();
void DoCanny();
void LogPolarTransform();
void MatrixShow();
void RoiSample();
void MatrixOperationSample();
void ConvertSample();
void FilpSample();
void DrawSample();
void FontSample();
void FileSample();
void CheckRunDLL();
void MouseControl();
void MymouseCallback(int event, int x, int y, int flags, void* param);
void Drawpoint( IplImage *img , CvPoint pt1 , CvPoint pt2 );
void SmoothSample();

IplImage* ReloadImage( IplImage *imgSrc , const char *filename );



int main( int argc , char ** argv )
{
	while( 1 )
	{
		//清屏
		system( "cls" );
		printf( "---------OpenCV Samples----------\n" );
		printf( "1.Load Image From Location\n" );
		printf( "2.Load AVI From File\n" );
		printf( "3.Capture an Image To apply Smooth\n" );
		printf( "4.Capture an Image To apply PyrDown\n" );
		printf( "5.Capture an Image To apply Canny\n" );
		printf( "6.Capture Video To apply Log ploar Tramsform\n" );
		printf( "7.Matrix Manipulation\n" );
		printf( "8.ROI Of The Image Sample\n" );
		printf( "9.Matrix Operation Sample\n" );
		printf( "a. Convert Sample\n" );
		printf( "b. Flip Sample\n" );
		printf( "c. Draw Sample\n" );
		printf( "d. Font Sample\n" );
		printf( "e. File Storage Sample\n" );
		printf( "f. Check IPP Sample\n" );
		printf( "g. Mouse Sample\n" );
		printf( "h. Smooth Sample\n" );
		printf( "0.EXIT\n" );
		printf( "Your choice:" );
		char ch = 0;
		scanf_s( "%c" , &ch , 1 );
		getchar();
		//刷新流
		fflush( stdin );
		switch ( ch )
		{
		case '1':
			{
				ReadImageFile();
				break;
			}

		case '2':
			{
				ReadAVIFile();
				break;
			}
		case '3':
			{
				CaptureAndSmooth();
				break;
			}
		case '4':
			{
				PyrDown();
				break;
			}
		case '5':
			{
				DoCanny();
			}
		case '6':
			{
				LogPolarTransform();
				break;
			}
		case '7':
			{
				MatrixShow();
				break;
			}
		case '8':
			{
				RoiSample();
				break;
			}
		case '9':
			{
				MatrixOperationSample();
				break;
			}
		case 'a':
			{
				ConvertSample();
				break;
			}
		case 'b':
			{
				FilpSample();
				break;
			}

		case 'c':
			{
				DrawSample();
				break;
			}
		case 'd':
			{
				FontSample();
				break;
			}
		case 'e':
			{
				FileSample();
				break;
			}
		case 'f':
			{
				CheckRunDLL();
				break;
			}
		case 'g':
			{
				MouseControl();
				break;
			}
		case 'h':
			{
				SmoothSample();
				break;
			}
		case 'q':
		case 'Q':
		case '0':
			{
				exit(0);
				break;
			}
		default:
			break;
		}
	}
	return 0;

}

//从文件读取图像
void ReadImageFile()
{
	CHAR filename[FILENAME_MAX] = { 0 };
	SHORT filesize = 0;
	/*
	if( argc == 1)
	{
		printf( "argv[0] = %s\n" , argv[0] );
		printf( "The program will read from command line\n" );
		printf( "Please Input an Image FileName:" );
		scanf_s( "%s" ,  filename , FILENAME_MAX );
		printf( "%s\n" , filename );
		fflush( stdin );
	}
	else if( argc == 2 )
	{
		filesize = strlen( argv[1] );
		memcpy_s( filename , filesize ,  argv[1] , filesize );

	}
	else
	{
		printf( "argc = %d \n argv[%d] = %s\n" , argc , argc - 1 , argv[argc - 1] );
		printf( "fatal error, cant't open image file\n" );
		exit( 0 );
	}
	*/

	printf( "Please Input an Image FileName:" );
	scanf_s( "%s" ,  filename , FILENAME_MAX );
	printf( "%s\n" , filename );
	fflush( stdin );

	IplImage *imgSrc = NULL;
	imgSrc = cvLoadImage( filename );
	cvNamedWindow( "ShowImage" );
	cvShowImage( "ShowImage" , imgSrc );

	cvWaitKey( 0 );

	cvDestroyWindow( "ShowImage" );
	cvReleaseImage( &imgSrc );
}


//从AVI文件读取数据并播放,并控制播放
//全局变量,便于下面的回调函数进行设置
int g_frameLocation = 0;
int g_frameCount = 0;
CvCapture *g_capture = NULL;
void ReadAVIFile()
{
	char filename[FILENAME_MAX];
	printf( "Please Input an AVI FilePath or FileName:" );
	scanf_s( "%s" , filename , FILENAME_MAX );
	fflush( stdin );

	IplImage *frame = NULL;
	//创建结构体CvCapture
	g_capture = cvCreateFileCapture( filename );

	//创建显示的窗体
	cvNamedWindow( "AVI Video" );

	//获取帧数
	g_frameCount = ( int )cvGetCaptureProperty( g_capture , CV_CAP_PROP_FRAME_COUNT );
	if ( g_frameCount != 0 )
	{
		//创建Trackbar
		cvCreateTrackbar( "Process" , "AVI Video" , &g_frameLocation , g_frameCount , MyTrackbar );
	}
	while( 1 )
	{
		//获取视频帧
		frame = cvQueryFrame( g_capture );
		cvShowImage( "AVI Video" , frame );

		if( cvWaitKey( 33 ) == 28 )
		{
			break;
		}

	}
	//释放CvCapture
	cvReleaseCapture( &g_capture );
	//下面的语句没有必要,因为cvQueryFrame获取的数据不需要释放内存
	//cvReleaseImage( &frame );

	//释放窗体
	cvDestroyWindow( "AVI Video" );
	


}

/*
CALL BACK Function To Control The Stream
回调函数
*/
void MyTrackbar( int pos )
{
	if ( pos && !( pos & g_frameCount ) )
	{
		cvSetCaptureProperty( g_capture , CV_CAP_PROP_POS_FRAMES , pos );
	}
	
}



//从摄像头捕获图像并进行模糊
void CaptureAndSmooth()
{
	IplImage *imgSrc = NULL , *imgGaussianDst = NULL , *imgMediaDst = NULL;

	CvCapture *capture = cvCreateCameraCapture( 0 );

	cvNamedWindow( "Press 'S' To Capture an Image" );
	
	while ( 1 )
	{
		imgSrc = cvQueryFrame( capture );
		cvShowImage( "Press 'S' To Capture an Image" , imgSrc );
		
		//115为字母's'的ascii字符的字面值
		if ( cvWaitKey( 33 ) == 115 )
		{
			break;
		}
	}

	//复制图像数据,注意,该指针指向的数据需要释放
	imgSrc = cvCloneImage( imgSrc );
	//为新图像创建图像存储区
	imgGaussianDst = cvCreateImage( cvGetSize( imgSrc ) , imgSrc->depth , imgSrc->nChannels );
	imgMediaDst = cvCreateImage( cvGetSize( imgSrc ) , imgSrc->depth , imgSrc->nChannels );


	cvNamedWindow( "Gaussian Smooth");
	//对图像进行高斯滤波,也叫高斯模糊
	cvSmooth( imgSrc , imgGaussianDst , CV_GAUSSIAN );
	cvShowImage( "Gaussian Smooth" , imgGaussianDst );
	cvNamedWindow( "Media Smooth" );
	//对图像进行中值滤波,同样也是模糊
	cvSmooth( imgSrc , imgMediaDst , CV_MEDIAN );
	cvShowImage( "Media Smooth" , imgSrc );

	if ( cvWaitKey( 0 ) == 28 )
	{
		//释放内存
		cvDestroyWindow( "Press 'S' To Capture an Image" );
		cvDestroyWindow( "Gaussian Smooth" );
		cvReleaseImage( &imgSrc );
		cvReleaseImage( &imgGaussianDst );
		cvReleaseImage( &imgMediaDst );
		cvReleaseCapture( &capture );
	}

	

}

//高斯模糊以及降采样
void PyrDown()
{
	IplImage *imgSrc = NULL;
	//从摄像头创建CvCapture结构
	CvCapture *capture = cvCreateCameraCapture( 0 );
	cvNamedWindow( "Press 's' To Capture an Image" );
	while ( 1 )
	{
		//从摄像头获取帧
		imgSrc = cvQueryFrame( capture );
		//显示每一帧
		cvShowImage( "Press 's' To Capture an Image" ,imgSrc );

		if ( cvWaitKey( 33 ) == 115 )
		{
			break;
		}



	}

	cvDestroyWindow( "Press 's' To Capture an Image" );
	imgSrc = cvCloneImage( imgSrc );
	IplImage *imgDst = cvCreateImage( cvSize( imgSrc->width / 2 , imgSrc->height / 2 ) , imgSrc->depth , imgSrc->nChannels );

	cvNamedWindow( "PyrDown" );
	//采用高斯模糊以及降采样进行处理,此函数在SIFT中的构建高斯金字塔特别有用!
	cvPyrDown( imgSrc ,  imgDst );

	cvShowImage( "PyrDown" , imgDst );

	//若用户按下esc则退出
	if ( cvWaitKey( 0 ) == 28 )
	{
		;
	}

	//释放资源
	cvDestroyWindow( "PyrDown" );
	cvReleaseImage( &imgSrc );
	cvReleaseImage( &imgDst );
	cvReleaseCapture( &capture );

}


//Canny边缘检测
void DoCanny()
{
	IplImage *imgSrc = NULL;
	CvCapture *capture = cvCreateCameraCapture( 0 );
	cvNamedWindow( "Press 's' To Capture an Image" );
	while( 1 )
	{
		imgSrc = cvQueryFrame( capture );
		cvShowImage( "Press 's' To Capture an Image" , imgSrc );

		if( cvWaitKey( 33 ) == 115 )
		{
			break;
		}
	}
	cvDestroyWindow( "Press 's' To Capture an Image" );
	imgSrc = cvCloneImage( imgSrc );
	imgSrc->nChannels = 1;

	//因为Canny边缘检测只有一个通道,即针对的是灰度图像
	IplImage *imgDst = cvCreateImage( cvGetSize( imgSrc ) , IPL_DEPTH_8U , 1 );
	cvCanny( imgSrc , imgDst , 10 , 100, 3 );
	cvNamedWindow( "Canny Detection" );
	cvShowImage( "Canny Detection" , imgDst );

	if ( cvWaitKey( 0 )  ==115 )
	{
		;
	}
	cvReleaseCapture( &capture );
	cvReleaseImage( &imgSrc );
	cvReleaseImage( &imgDst );
	cvDestroyWindow( "Canny Detection" );
}

//对数极坐标变换
void LogPolarTransform()
{
	IplImage *frame = NULL;
	CvCapture *capture = cvCreateCameraCapture( 0 );
	frame = cvQueryFrame( capture );
	IplImage *imgDst = cvCreateImage(
		cvSize( cvGetCaptureProperty( capture , CV_CAP_PROP_FRAME_WIDTH ) , 
		cvGetCaptureProperty( capture , CV_CAP_PROP_FRAME_HEIGHT ) ) ,
		IPL_DEPTH_8U,//frame->depth , 
		3//frame->nChannels
		);
	IplImage *imgDst2 = cvCreateImage( cvGetSize( frame ) , frame->depth , frame->nChannels  );


	cvNamedWindow( "原始" );
	cvNamedWindow( "对数极坐标变换" );
	cvNamedWindow( "对数极坐标反变换" );
	
	//打开视频,获取视频的各种属性
	while ( 1 )
	{
		frame = cvQueryFrame( capture );
		cvShowImage( "原始" , frame );

		//对数极坐标变换
		//cvLogPolar函数可以用来模拟人类的中央视觉(foveal vision),并可以用于物体跟踪方面的尺度及旋转不变模板的快速匹配
		cvLogPolar( frame , imgDst , cvPoint2D32f( frame->width / 2 , frame->height / 2 ) , 40 , CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS  );
		cvShowImage( "对数极坐标变换" , imgDst );
		cvLogPolar( frame , imgDst2 , cvPoint2D32f( frame->width / 2 , frame->height / 2 ) , 40 , CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS+CV_WARP_INVERSE_MAP );
		cvShowImage( "对数极坐标反变换" , imgDst2 );
		if ( cvWaitKey( 33 ) == 115 )
		{
			break;
		}

	}


	cvReleaseImage( &imgDst );
	cvReleaseImage( &imgDst2 );
	cvDestroyWindow( "Capture Video" );
	cvReleaseCapture( &capture );



}

void MatrixShow()
{
	float arr[] = { 1.212 , 12.2323 , 4.5 , 1.4 };
	//初始化矩阵的第一种方法
	printf( "Init Matrix With cvInitMatHeader() Function\n" );
	CvMat mat = { 0 };
	cvInitMatHeader( &mat , 2 , 2 ,CV_32FC1 , arr );

	//访问矩阵元素
	float ff = CV_MAT_ELEM( mat , float , 1 , 1 );
	printf( "%f\n" , ff );


	//使用宏定义来访问矩阵中的元素
	printf( "Create Matrix With cvCreateMatHeader() Funciton\n" );

	//创建矩阵
	CvMat *mat2 = cvCreateMatHeader( 2 , 2 , CV_32FC1 );
	//初始化矩阵头,使用arr数据的数据进行初始化
	cvInitMatHeader( mat2 , 2 , 2 ,CV_32FC1 , arr );


	printf( "Use The Macro CV_MAT_ELEM()\n" );
	for ( int col = 0; col < 2 ; ++col )
	{
		for ( int row = 0 ; row < 2 ; ++row )
		{
			printf( "%f " , CV_MAT_ELEM( *mat2 , float , row , col ) );
		}
		printf( "\n" );
	}

	//使用宏访问矩阵指向的元素的指针,然后通过指针访问元素
	printf("Use The Macro CV_MAT_ELEM_PTR()\n");
	for ( int col = 0; col < 2 ; ++col )
	{
		for ( int row = 0 ; row < 2 ; ++row )
		{
			printf( "%f " , *( (float *)CV_MAT_ELEM_PTR( *mat2 , row , col ) ) );
		}
		printf( "\n" );
	}

	printf( "Use The cvPtr3D() Function\n" );
	
	//下面的语句出错
	//为什么呢?
	//因为我们定义的矩阵是2维的,所以不能用三维的指针访问,只能用2维或者1维的指针访问,否则就会出错
	//printf( "%f\n" , *( ( float* )cvPtr3D( &mat , 0, 0 ,0 ) ) );
	
	
	//注意到没有cvPtr2D返回的是uchar *指针,我们需要将他转换为float *的指针,然后对其进行访问
	printf( "Use The cvPtr2D() Function\n" );
	for( int col = 0 ; col < 2 ; ++ col )
	{
		for( int row = 0 ; row < 2 ; ++row )
		{
			printf( "%f " , *( (float *)cvPtr2D( &mat , row , col ) ) );
		}
		printf( "\n" );	
	}

	//使用cvPtr1D函数访问矩阵元素
	printf( "Use The cvPtr1D() Function\n" );
	for ( int index = 0 ; index < 4 ; ++index )
	{
		printf( "%f " , *( (float *)cvPtr1D( &mat , index ) ) );
	}

	//计算矩阵中的所有元素,使用指针定位
	printf( "Use Pointer To Access The Elements In The Matrix\n" );
	printf( "Calculate The Sum of each element in the Matrix\n" );
	float sum = 0.0f;
	const float *ptr = NULL;
	printf( "The Element Of The Matrix follows:\n" );
	for( int row = 0 ; row < 2 ; ++row )
	{
		//step为每行的字节数, ptr为指向数据的首指针
		//所以每一行遍历之后就要设置指针,使改行指向下一行,因为每行的数据是4字节对其的
		ptr = ( const float* )( mat.data.ptr + row * mat.step );

		for( int col = 0 ; col < 2 ; ++ col )
		{
			printf( "%f " , *ptr );
			sum += *ptr++;
		}
		printf( "\n" );
	}
	printf( "The Sum is %f\n" , sum );

	while(1)
	{
		if(  cvWaitKey( 0 ) == 115 )
		{
			break;
		}
	}

}



void RoiSample()
{
	//获取文件路径
	printf( "Please Input a Filename As Source Image:" );
	char filename[FILENAME_MAX] = { 0 };
	scanf_s( "%s" , filename , FILENAME_MAX );
	fflush( stdin );


	//Get X Y Width Height
	printf( "Please Input x, y the width and height( e.g. x=12 y=12 w=25 h=25 ):" );
	int x = 0 , y = 0 , width = 0 , height = 0;
	scanf( "x=%d y=%d w=%d h=%d" , &x , &y , &width , &height );
	
	//Load Image
	IplImage *imgSrc = cvLoadImage( filename );

	//Set ROI
	cvSetImageROI( imgSrc , cvRect( x, y , width , height )  );

	//对着ROI的区域进行变换
	cvAddS( imgSrc , cvScalar( 250 , 1 , 1 , 0 ) ,  imgSrc );

	//Reset ROI
	cvResetImageROI( imgSrc );

	//Show Image
	cvNamedWindow( "ROI Sample" );
	cvShowImage( "ROI Sample" , imgSrc );
	cvWaitKey( 0 );

	cvDestroyWindow( "ROI Sample" );
}

//矩阵操作示例
void MatrixOperationSample()
{
	printf( "Matrix Operation Sample\n" );
	char filename[FILENAME_MAX] = { 0 };
	
	printf( "Please Input Filename:" );
	scanf_s( "%s" , filename , FILENAME_MAX );
	IplImage *imgSrc = cvLoadImage( filename );



	printf( "Matrix Add Operation\n" );
	cvAddS( imgSrc , cvScalar( 255 , 0 , 0 ) , imgSrc );
	cvNamedWindow( "Matrix Add" );
	cvShowImage( "Matrix Add" , imgSrc );
	

	//重载图像数据
	imgSrc = ReloadImage( imgSrc , filename );

	printf( "Matrix Abs Operaion\n" );
	cvAbs( imgSrc , imgSrc );
	cvNamedWindow( "Matrix Abs" );
	cvShowImage( "Matrix Abs" , imgSrc );


	//Reload Image
	imgSrc = ReloadImage( imgSrc , filename );

	//计算矩阵中的两个矩阵相减的每个元素的绝对值
	printf( "Matrix AbsDiff Operation\n" );
	cvAbsDiff( imgSrc , imgSrc , imgSrc );
	cvNamedWindow( "Matrix AbsDiff" );
	cvShowImage( "Matrix AbsDiff" , imgSrc );


	//Reload Image
	imgSrc = ReloadImage( imgSrc , filename );

	//计算图像的权重公式为: alpha * 图像1 + beta * 图像2 + gamma
	printf( "Matrix AddWeighted\n" );
	cvAddWeighted( imgSrc , 0.1 , imgSrc , 0.8 , 0 , imgSrc );
	cvNamedWindow( "Matrix AddWeighted" );
	cvShowImage( "Matrix AddWeighted" , imgSrc );

	//Reload Image
	imgSrc = ReloadImage( imgSrc , filename );


	//计算图像的平均的像素值
	printf( "Matrix Avg\n" );
	CvScalar scalar = cvAvg( imgSrc );
	printf( "Average Pixel is R = %lf G = %lf B = %lf A = %lf\n" , scalar.val[0] , scalar.val[1] , scalar.val[2] , scalar.val[3] );


	printf( "Matrix Avg And Standard divide\n" );
	CvScalar scalar_stddev = { 0 };
	//计算图像的像素值的标准差
	cvAvgSdv( imgSrc , &scalar , &scalar_stddev );
	printf( "Standard divide R = %lf  G = %lf  B = %lf A = %lf\n" , \
		scalar_stddev.val[0] , scalar_stddev.val[1] , scalar_stddev.val[2] , scalar_stddev.val[3] );


	//计算数据的协方差和均值
	//要特别注意协方差是怎么计算的,该函数使用的时候要非常小心哦
	printf( "Matrix Covariance Sample\n" );
	double arr[] = { 1 , 9 , 21 , 1 , 13 , 12 , 56 , 54 , 12 };
	CvMat *matCo = NULL , *matAvg = NULL , *mat[3] = { NULL };

	//初始化矩阵,以将数组中的元素存放其中
	mat[0] = cvCreateMatHeader( 1 , 3 , CV_32FC1 );
	cvInitMatHeader( mat[0] , 1 , 3 , CV_32FC1 , arr );
	mat[1] = cvCreateMatHeader( 1 , 3 , CV_32FC1 );
	cvInitMatHeader( mat[1] , 1 , 3 , CV_32FC1 , arr + 3 );
	mat[2] = cvCreateMatHeader( 1 , 3 , CV_32FC1 );
	cvInitMatHeader( mat[2] , 1 , 3 , CV_32FC1 , arr + 6 );

	//存储协方差的矩阵为3*3
	matCo = cvCreateMat( 3 , 3 , CV_32FC1 );


	//存储矩阵的平均值该矩阵和传入的矩阵的大小应该一致
	matAvg = cvCreateMat( 1 , 3 ,CV_32FC1 );

	//在计算协方差的函数(即下面这个函数中)count 是指矩阵的个数
	cvCalcCovarMatrix( (const CvArr **) mat , 3 , matCo , matAvg , CV_COVAR_SCALE + CV_COVAR_NORMAL );//计算一般的协方差和均值

	printf("协方差矩阵的值为:\n");
	for ( int col = 0 ; col < 3 ; ++col )
	{
		for ( int row = 0 ; row < 3 ; ++row  )
		{
			printf( "%lf ", cvGetReal2D( matCo , row , col ) );
		}
		printf( "\n" );
	}


	printf( "\n平均值矩阵的值为:\n" );
	for ( int col = 0 ; col < 3 ; ++col )
	{
		for ( int row = 0 ; row < 1 ; ++row  )
		{
			printf( "%lf ", cvGetReal2D( matAvg , row , col )  /*CV_MAT_ELEM( *matCo , double , row , col )*/ );
		}
	}


	//Reload Image
	imgSrc = ReloadImage( imgSrc , filename );





	if( cvWaitKey( 0 ) == 115 )
	{
		;
	}

	cvDestroyWindow( "Matrix Add" );
	cvDestroyWindow( "Matrix Abs" );
	cvDestroyWindow( "Matrix AbsDiff" );
	cvDestroyWindow( "Matrix AddWeighted" );
}


//重新载入图像
IplImage* ReloadImage( IplImage *imgSrc , const char *filename )
{
	if( NULL == imgSrc || NULL == filename )
	{
		return NULL;
	}

	cvReleaseImage( &imgSrc );
	return cvLoadImage( filename );
}



//转换示例
void ConvertSample()
{
	IplImage *imgSrc = NULL;

	printf( "Convert Scale Sample\n" );
	printf( "Please Input Image Filename:" );

	char filename[FILENAME_MAX] = { 0 };

	scanf_s( "%s" , filename , FILENAME_MAX );

	imgSrc = cvLoadImage( filename );

	cvNamedWindow( "Source Image" );
	cvShowImage( "Source Image" , imgSrc );

	IplImage *imgDst = cvCloneImage( imgSrc );
	cvConvertScale( imgSrc , imgDst , 0.5 , 2  );

	cvNamedWindow( "ConvertScale" );
	cvShowImage( "ConvertScale" , imgDst );


	printf( "Convert To Gray Image" );
	IplImage *imgGray = cvCreateImage( cvGetSize( imgSrc ) , imgSrc->depth , 1 );


	cvCvtColor( imgSrc ,  imgGray , CV_RGB2GRAY );

	cvNamedWindow( "Gray Color" );
	cvShowImage( "Gray Color" , imgGray );



	printf( "计算特征值和特征向量\n" );
	int arr[] = { 2 , 2 , 2 , 2 };
	CvMat *mat = cvCreateMatHeader( 2 , 2 , CV_32FC1 );
	cvInitMatHeader( mat , 2 , 2 , CV_32SC1 , arr );
	CvMat evects = cvMat( 1 , 2  , CV_32FC1 );
	cvInitMatHeader( &evects , 1 , 2 , CV_32FC1 );
	CvMat evals = cvMat( 1 , 2 ,CV_32FC1 );
	cvInitMatHeader( &evals , 1 , 2 , CV_32FC1 );
	//cvEigenVV( mat , &evects , &evals , 0 );

	



	if ( cvWaitKey( 0 )  ==  's' )
	{
		;
	}

	cvDestroyWindow( "ConvertScale" );
	cvDestroyWindow( "Gray Color" );
	cvDestroyWindow( "Source Image" );
	cvReleaseImage( &imgDst );
	cvReleaseImage( &imgSrc );
	cvReleaseImage( &imgGray );


}

//旋转示例
void FilpSample()
{
	printf( "旋转图像\n" );
	printf( "请输入图像位置或者图像名称:" );
	char filename[FILENAME_MAX] = { 0 };

	scanf_s( "%s" , filename , FILENAME_MAX );
	IplImage *imgSrc = cvLoadImage( filename );

	cvNamedWindow( "原图" );
	cvShowImage( "原图" , imgSrc );

	IplImage *imgDst = cvCloneImage( imgSrc );
	if ( NULL  == imgDst  )
	{
		printf( "NULL\n" );
	}



	//特别要注意cvFilp的参数!!
	//第二个参数为NULL为直接对原图进行旋转,若第二个参数不为NULL则会将结果给第二个参数所指向的内存空间
	cvFlip( imgDst , NULL , 0 );
	cvNamedWindow( "旋转之后的图" );
	cvShowImage( "旋转之后的图", imgDst );


	while ( 1 )
	{

		if ( cvWaitKey( 0 ) == 's' )
		{
			break;
		}
	}

	cvDestroyAllWindows();
	cvReleaseImage( &imgSrc );
	cvReleaseImage( &imgDst );


}

//绘图示例
void DrawSample()
{
	printf("Draw Ellipse\n");
	IplImage *img = cvCreateImage( cvSize( 500 , 500 ) , 16 , 3 );
	

	printf( "画线\n" );
	//其中的第二个和第三个为起始点和终止点坐标
	cvLine( img , cvPoint( 0 ,0 ) , cvPoint( 500 , 500 ) , cvScalar( 255 , 0 , 0 ,0 ) , 1 , 8  ,0 );
	cvNamedWindow( "Line" );
	cvShowImage( "Line" , img );


	printf( "椭圆形\n" );
	cvEllipse( img , cvPoint( 250 , 250 ) , cvSize( 100 , 150 ) , 120 , 0 , 360 , cvScalar( 255 , 0  , 0 )  );
	cvNamedWindow( "Ellipse" );
	cvShowImage( "Ellipse" , img  );

	printf( "多边形\n" );

	//设置指针数组用来存放点的坐标
	CvPoint **pt = new CvPoint*[1];
	pt[0] = new CvPoint[4];
	pt[0][0] = cvPoint( 120 , 120 );
	pt[0][1] = cvPoint( 240 , 240 );
	pt[0][2] = cvPoint( 450 , 320 );
	pt[0][3] = cvPoint( 100 , 45 );


	int count = 4;
	//第一个参数为图像 , 第二个参数为点的指针 , 第三个参数为d点数组的个数
	//第四个为线段个数,第五个为是否闭合第六个为线段颜色
	cvPolyLine( img , pt , &count , 1 , TRUE ,cvScalar(  255 , 0 ,0  ) );
	cvNamedWindow( "多边形" );
	cvShowImage( "多边形", img );

	if ( cvWaitKey( 0 ) == 's' )
	{
		;
	}

	cvReleaseImage( &img );
	cvDestroyWindow( "Line" );
	cvDestroyWindow( "Ellipse" );
	cvDestroyWindow( "多边形" );
}

//字体设显示示例
void FontSample()
{
	printf( "Font Sample\n" );
	IplImage *img = cvCreateImage( cvSize( 500 , 500 ) , 16 , 1 );


	cvNamedWindow( "字体"  );

	CvFont font = { 0 };

	//初始化字体为简单的字体,第三个参数为高度 ,第四个参数为宽度
	cvInitFont( &font , CV_FONT_HERSHEY_SIMPLEX , 1.0 , 5.0   );
	//将hello显示在图像中
	cvPutText( img , "hello" , cvPoint( 255 , 255 ) , &font , cvScalar( 255 , 255 , 255 ) );


	cvShowImage( "字体" , img );

	//暂停
	if ( cvWaitKey( 0 ) == 's' )
	{
		;
	}

	cvDestroyWindow( "字体" );
	cvReleaseImage( &img );
}


//文件存储示例
void FileSample()
{
	//这里只是简单地使用一下OpenCV的XML的简单的一些操作,没有深入,以后会深入下去学习
	printf( "File Storage Sample\n" );

	CvFileStorage *file = cvOpenFileStorage( "1.xml" , 0 , CV_STORAGE_WRITE );

	cvWriteComment( file , "This File is Made by xizero00^_^" , 0 );

	//写入字符串的函数竟然不支持中文......-_-!!!!!
	cvWriteString( file , "name" , "zhangsan" , 1 );
	cvWriteInt( file , "age" , 23 );

	
	cvReleaseFileStorage( &file );

}

//检测库文件版本以及是否安装IPP库
void CheckRunDLL()
{
	char *libraries = NULL , *modules = NULL;

	cvGetModuleInfo( 0 , ( const char** ) &libraries ,( const char** ) &modules  );


	printf( "库:%s\n" , libraries  );
	printf( "模块:%s\n" , modules );
	system( "pause" );

}


void MouseControl()
{
	IplImage *img = cvCreateImage( cvSize( 450 , 450 ) , IPL_DEPTH_16U , 1 );
	
	printf( "mouse control sample" );
	cvNamedWindow( "mouse" );
	cvShowImage( "mouse" , img );

	//设置鼠标回调函数
	cvSetMouseCallback( "mouse" , MymouseCallback ,(void *) img );
	
	while ( 1 )
	{

		if ( cvWaitKey( 0 ) == 's' )
		{
			break;
		}
	}

	//销毁所有打开的窗体
	cvDestroyAllWindows();
	cvReleaseImage( &img );



}
//画短线
void Drawpoint( IplImage *img , CvPoint pt1 , CvPoint pt2 )
{
	cvDrawLine( img , pt1 , pt2 , cvScalar( 255 , 128 , 0 )  , 1  , 8 , 0 );
}

//鼠标回调函数
void MymouseCallback(int event, int x, int y, int flags, void* param)
{

	IplImage *img = ( IplImage * )param;
	CvPoint pt1 = { 0 } , pt2 = { 0 };
	//获取鼠标位置,然后画短线段模拟笔迹
	pt1.x = x;
	pt1.y = y;
	pt2.x = x + 1;
	pt2.y = y + 1;
	switch( event )
	{
	case CV_EVENT_LBUTTONDOWN:
		break;
	case CV_EVENT_MOUSEMOVE:
		{
			//画短线段
			Drawpoint( img , pt1 , pt2 );
			//刷新窗体
			cvShowImage( "mouse" , img );
			break;
		}
	}


}



void SmoothSample()
{
	printf( "Smoot Sample" );

	IplImage *imgSrc = NULL;
	char filename[FILENAME_MAX] = { 0 };

	printf( "Please Input the Filename:" );
	scanf_s( "%s" , filename , FILENAME_MAX );

	imgSrc = cvLoadImage( filename );


	cvNamedWindow( "原图" );
	cvShowImage( "原图", imgSrc );


	printf( "简单模糊\n" );

	IplImage *imgSimple = cvCreateImage( cvGetSize( imgSrc ) , imgSrc->depth , imgSrc->nChannels );
	cvSmooth( imgSrc , imgSimple , CV_BLUR , 4 , 4  );//简单模糊的两个参数4 ,4 是对4*4的领域求和,然后做缩放

	cvNamedWindow( "简单模糊" );
	cvShowImage( "简单模糊" ,imgSimple );


	printf( "中值滤波\n" );
	IplImage *imgMedian = cvCreateImage( cvGetSize( imgSrc ) , imgSrc->depth , imgSrc->nChannels );
	cvSmooth( imgSrc , imgMedian , CV_MEDIAN  );//中值滤波的是对默认参数(Opencv第四个参数默认为3)所以为对3*3的领域为大小进行中值滤波
	cvNamedWindow( "中值滤波" );
	cvShowImage( "中值滤波" , imgMedian );



	printf( "高斯滤波\n" );
	
	IplImage *imgGaussian = cvCreateImage( cvGetSize( imgSrc ) , imgSrc->depth , imgSrc->nChannels );
	cvSmooth( imgSrc , imgGaussian , CV_GAUSSIAN  );//高斯滤波:对图像进行核默认大小为0的高斯卷积进行滤波
	cvNamedWindow( "高斯模糊" );
	cvShowImage( "高斯模糊" , imgGaussian );



	printf( "双边滤波\n" );
	IplImage *imgBiLateral = cvCreateImage( cvGetSize( imgSrc ) , imgSrc->depth , imgSrc->nChannels ); 
	cvSmooth( imgSrc , imgBiLateral , CV_BILATERAL , 3 , 3 , 11 , 11  );//注意双边滤波的参数 3  3  11 11  ,颜色sigma 为3, 空间sigma为3后面的11没有用处,不能省略
	cvNamedWindow( "双边滤波" );
	cvShowImage( "双边滤波" , imgBiLateral );



	while( 1 )
	{
		if ( cvWaitKey( 0 ) == 's' )
		{
			break;
		}
		
	}

	cvReleaseImage( &imgSimple );
	cvReleaseImage( &imgSrc );
	cvDestroyAllWindows();

}


如何编译代码?

您可以新建一个控制台的应用程序,然后把这些代码粘贴进去即可。


代码还未完成,接下来我会继续完整这段代码。祝好运^_^


  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值