从图学起OpenCV

来源:互联网 发布:网络大电影数据 编辑:程序博客网 时间:2024/05/18 01:25

众所周知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;//创建结构体CvCaptureg_capture = cvCreateFileCapture( filename );//创建显示的窗体cvNamedWindow( "AVI Video" );//获取帧数g_frameCount = ( int )cvGetCaptureProperty( g_capture , CV_CAP_PROP_FRAME_COUNT );if ( g_frameCount != 0 ){//创建TrackbarcvCreateTrackbar( "Process" , "AVI Video" , &g_frameLocation , g_frameCount , MyTrackbar );}while( 1 ){//获取视频帧frame = cvQueryFrame( g_capture );cvShowImage( "AVI Video" , frame );if( cvWaitKey( 33 ) == 28 ){break;}}//释放CvCapturecvReleaseCapture( &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 Heightprintf( "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 ImageIplImage *imgSrc = cvLoadImage( filename );//Set ROIcvSetImageROI( imgSrc , cvRect( x, y , width , height )  );//对着ROI的区域进行变换cvAddS( imgSrc , cvScalar( 250 , 1 , 1 , 0 ) ,  imgSrc );//Reset ROIcvResetImageROI( imgSrc );//Show ImagecvNamedWindow( "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 ImageimgSrc = ReloadImage( imgSrc , filename );//计算矩阵中的两个矩阵相减的每个元素的绝对值printf( "Matrix AbsDiff Operation\n" );cvAbsDiff( imgSrc , imgSrc , imgSrc );cvNamedWindow( "Matrix AbsDiff" );cvShowImage( "Matrix AbsDiff" , imgSrc );//Reload ImageimgSrc = ReloadImage( imgSrc , filename );//计算图像的权重公式为: alpha * 图像1 + beta * 图像2 + gammaprintf( "Matrix AddWeighted\n" );cvAddWeighted( imgSrc , 0.1 , imgSrc , 0.8 , 0 , imgSrc );cvNamedWindow( "Matrix AddWeighted" );cvShowImage( "Matrix AddWeighted" , imgSrc );//Reload ImageimgSrc = 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*3matCo = 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 ImageimgSrc = 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();}


如何编译代码?

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


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