众所周知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: [email protected] * 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(); }
您可以新建一个控制台的应用程序,然后把这些代码粘贴进去即可。
代码还未完成,接下来我会继续完整这段代码。祝好运^_^