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