当前位置:文档之家› 基于opencv对图像的预处理

基于opencv对图像的预处理

基于opencv 对图像的预处理1.问题描述本次设计是基于opencv 结合c++语言实现的对图像的预处理,opencv 是用于开发实时的图像处理、计算机视觉及模式识别程序;其中图像的预处理也就是利用opencv 对图像进行简单的编辑操作;例如对图像的对比度、亮度、饱和度进行调节,同时还可以对图像进行缩放和旋转,这些都是图像预处理简单的处理方法;首先通过opencv 加载一幅原型图像,显示出来;设置五个滑动控制按钮,当拖动按钮时,对比度、亮度、饱和度的大小也会随之改变,也可以通过同样的方式调节缩放的比例和旋转的角度,来控制图像,对图像进行处理,显示出符合调节要求的图像,进行对比观察他们的之间的变化。

2.模块划分此次设计的模块分为五个模块,滑动控制模块、对比度和亮度调节模块、饱和度调节模块、缩放调节模块、旋转调节模块,他们之间的关系如下所示:图一、各个模块关系图调用调用调用调用滑动控制模块对比度和亮度调节模块饱和度调节模块缩放调节模块旋转调节模块滑动控制模块处于主函数之中,是整个设计的核心部分,通过createTrackbar创建五个滑动控制按钮并且调用每个模块实现对图像相应的调节。

3.算法设计(1)滑动控制:滑动控制是整个设计的核心部分,通过创建滑动控制按钮调节大小来改变相应的数据,进行调用函数实现对图像的编辑,滑动控制是利用createTrackbar(),函数中包括了滑动控制的名称,滑动控制显示在什么窗口上,滑动变量的地址和它调节的最大围,以及每个控制按钮应该调用什么函数实现什么功能;(2)对比度和亮度的调节:对比度和亮度的调节的原理是依照线性理论,它的公式如下所示:g(x)=a* f(x) +b,其中f(x)表示源图像的像素,g(x)表示输出图像的像素,参数a(需要满足a>0)被称为增益(gain),常常被用来控制图像的对比度,参数b通常被称为偏置(bias),常常被用来控制图像的亮度;(3)饱和度的调节:饱和度调节利用cvCvtColor( src_image, dst_image, CV_BGR2HSV )将RGB 颜色空间转换为HSV颜色空间,其中“H=Hue”表示色调,“S=Saturation”表示饱和度,“V=Value ”表示纯度;所以饱和度的调节只需要调节S的大小,H 和V的值不需要做任何的改变;(4)旋转的调节:旋转是以某参考点为圆心,将图像的个点(x,y)围绕圆心转动一个逆时针角度θ,变为新的坐标(x1,y1),x1=rcos(α+θ),y1=rsin(α+θ),其中r是图像的极径,α是图像与水平的坐标的角度的大小;(5)缩放的调节:首先得到源图像的宽度x和高度y,变换后新的图像的宽度和高度分别为x1和y1,x1=x*f,y1=y*f,其中f是缩放因子;4.函数功能描述(1)主函数main()用来设置滑动控制按钮,当鼠标拖动按钮可以得到相应的数据大小,实现手动控制的功能,当鼠标拖动对比度和亮度调节是,主函数调用对比度和亮度调节函数,类似这样分别对每个功能模块实现调用;(2)对比度和亮度调节函数ContrastAndBright(),当鼠标拖动对比度和亮度时将对比度和亮度的值传递给ContrastAndBright(),实现对图片的对比度和亮度的控制,并创建一个对比度和亮度显示窗口,将图像显示出来;(3)饱和度调节函数Statiate(),当鼠标拖动饱和度控制条将值从0~512时,饱和度的值就会传递给Statiate(),图像的饱和度就会随控制条变化而变化,将变化后图像显示在饱和度窗口上;(4)旋转函数Rotate(),旋转的角度变化围是0~360,在Rotate()中创建一个旋转图像显示窗口,当拖动鼠标改变旋转角度的变化,图像也会发生旋转; (5)缩放函数Zoom(),缩放的围是0~2,当缩放因为小于1时表示图像的缩小,当缩放因子大于1时,表示图像的放大,将缩放的图像显示在创建的缩放图像的窗口上;5.详细设计整个设计函数之间的的关系如下所示:图二、函数关系图Main ()createTrackbar ()ContrastAndBright ()Statiate ()Rotate()Zoom()利用include加载整个程序需要的库函数;定义相应的字符串变量、整形变量和指针变量并给他们赋初值;以下是整个设计中函数设计和运行的结果:(1)main()利用imread和cvLoadImage从文件夹中加载图像,运用if判断语句看是否读入图像成功,如过读入图像没有成功,则退出程序,如果读入图像成功则利用nameWindow创建并命名为原始图、滑动控制和对比度和亮度窗口,然后将图像显示在特定的窗口上,执行滑动控制函数createTrackbar();主函数得到原始图如下所示:(2)createTrackbar()其中括号的包括的容为(conststring& trackbarname, conststring& winname, int* value, int count, TrackbarCallback onChange=0,);第一个参数,const string&类型的trackbarname,表示轨迹条的名字,用来代表我们创建的轨迹条;第二个参数,const string&类型的winname,填窗口的名字,表示这个轨迹条会依附到哪个窗口上,即对应namedWindow()创建窗口时填的某一个窗口名;第三个参数,int* 类型的value,一个指向整型的指针,表示滑块的位置。

并且在创建时,滑块的初始位置就是该变量当前的值;第四个参数,int 类型的count,表示滑块可以达到的最大位置的;第五个参数,TrackbarCallback 类型的onChange,首先注意他有默认值0。

这是一个指向回调函数的指针,每次滑块位置改变时,这个函数都会进行回调。

并且这个函数的原型必须为void XXXX(int,void*);它的运行结果如下所示:(3)ContrastAndBright(),将图像转为矩阵阵列之后,执行运算g_dstImage(i,j) =a*g_srcImage(i,j) + b,其中i和j表示该像素点位于第i行和第j列,在执行上述运算在访问图像的每一个像素时,因为是对GBR图像进行运算,每个像素有三个值(G、B、R),所以我们必须分别访问它们,在访问像素的代码片段,利用三个for循环解决,第一个循环控制行,第二个循环控制列,第三个循环控制G、B、R,当调节亮度和对比度的轨迹条时所得的结果如下所示:(4)Statiate(),利用cvCloneImage复制源图像到地址dst3中去,在运用cvCloneImage()将RGB颜色空间转为HSV颜色空间,定义个lut[256][3]矩阵,矩阵的列表示H、S、V,利用一个for循环改变每个像素点饱和度S的值,它的色调和纯度不发生变化,它的效果图如下所示:(5)Zoom(),新的图像的宽度dst2_cvsize.width=rsc->width*g_nScaleValue/10.0和高度dst2_cvsize.height=rsc->height*g_nScaleValue/10.0,其中rsc->width、rsc-> —height分别为源图像的宽度和高度,g_nScaleValue为缩放因为,为了实现该图像的缩小功能,所以缩放因为除以10.0,小于1时实现缩小功能,大于1时实现的是放大的功能;运行结果如下所示:(6)Rotate(),定义一个浮点型的m[6]的数组,定义一个图形矩阵CvMat M,将m[6]中的数据可看做一个2行3列的矩阵,旋转就是是调节矩阵每个元素的值;获取源图像的宽度w和高度h,其中旋转中心为m[2]=w*0.5f,m[5]=h*0.5f;创建显示图像的窗口,最后将图像显示出来;它的运行结果如下所示:6.心得与体会计算机视觉是在图像处理的基础上发展起来的新兴学科。

opencv是一个开源的计算机视觉库,它为图像处理、模式识别、三维重建、物体跟踪、机器学习和线性代数提供了各种各样的算法;此次设计是我首次接触opencv,从opencv 基本的安装,到对图形,图像一些基本的操作,让我学到一点opencv的一些知识,尽管学到的东西不太多,但已经有了个初步的接触,在进行本次设计的过程中也遇到一些问题,例如滑动控制如何控制,饱和度如何设置,以及图像如何转为矩阵;在此次设计中仍然还有些地方不足,图像不能再同一个窗口上进行操作显示;虽然开始对opencv不了解,而且在此过程也会经常出现错误,我认为只有不断的出现错误,不断的调试,在做中学,不断的动手,才会掌握的更多,学到的更多,运用起来更加的熟练。

7.程序源代码#include "cv.h"#include<stdio.h>#include "highgui.h"using namespace cv;static void ContrastAndBright(int, void *);static void Rotate(int, void *);static void Zoom(int, void *);static void Statiate( int ,void * );string strWindowName = "滑动控制";string strWindowName1="对比度亮度效果图窗口";string strTraName = "对比度";string strTraName1 = "亮度";string strTraName2 = "饱和度";string strTraName3 = "缩放";string strTraName4 = "旋转";int g_nContraValue = 0;int g_nBrightValue = 0;int factor=0;int g_nScaleValue=0;int angle=0;IplImage *rsc = 0; //源图像指针IplImage *dst1 = 0; //目标图像指针IplImage *dst2 = 0;IplImage *dst3 = 0;CvSize dst1cv_size; //目标图像尺寸CvSize dst2_cvsize; //Mat g_srcImage,g_dstImage;int main( ){system("color 5E");g_srcImage= imread("E:\\程序\\新建文件夹\\opencv\\Debug\\1.jpg",1 );rsc=cvLoadImage("E:\\程序\\新建文件夹\\opencv\\Debug\\1.jpg",1);if(!g_srcImage.data ) { printf("Oh,no,读取g_srcImage图片错误~!\n"); return -1; }g_dstImage= Mat::zeros( g_srcImage.size(), g_srcImage.type() );//创建窗口namedWindow("【原始图窗口】", 1);//显示图像imshow("【原始图窗口】", g_srcImage);namedWindow(strWindowName);namedWindow(strWindowName1);//轨迹条的生成createTrackbar(strTraName,strWindowName,&g_nContraValue,100,ContrastAnd Bright);createTrackbar(strTraName1,strWindowName,&g_nBrightValue,100,ContrastAn dBright);createTrackbar(strTraName2,strWindowName,&factor,512,Statiate);createTrackbar(strTraName3,strWindowName,&g_nScaleValue,20,Zoom);createTrackbar(strTraName4,strWindowName,&angle,360,Rotate);waitKey(0);return 0;}void ContrastAndBright(int, void *)//对比和亮度的调节{ //三个for循环,执行运算g_dstImage(i,j) =a*g_srcImage(i,j) + b for(int y = 0; y < g_srcImage.rows; y++ ){for(int x = 0; x < g_srcImage.cols; x++ ){for(int c = 0; c < 3; c++ ){g_dstImage.at<Vec3b>(y,x)[c]=saturate_cast<uchar>( (g_nContraValue*0.01)*(g_srcImage.at<Vec3b>(y,x)[c] ) + g_nBrightValue );}}}imshow(strWindowName1, g_dstImage);}void Statiate( int ,void * ) //饱和度的调节{IplImage *hist_image = 0;dst3 = cvCloneImage(rsc);cvCvtColor( rsc, dst3, CV_BGR2HSV );int hue=factor-256;int i;float max_value = 0;uchar lut[256][3];CvMat* lut_mat;lut_mat = cvCreateMatHeader( 1, 256, CV_8UC3 );cvSetData( lut_mat, lut,0);for( i = 0; i < 256; i++ ) {int v = (i+hue);if( v < 0 )v = 0;if( v > 255 )v = 255;lut[i][1] = (uchar)v;lut[i][0] = (uchar)i;lut[i][2] = (uchar)i;}cvLUT( dst3, dst3, lut_mat );cvCvtColor( dst3, dst3, CV_HSV2BGR );cvShowImage("饱和度窗口", dst3 );}void Rotate(int, void *)//旋转的调节{dst1=cvCloneImage(rsc);float m[6];CvMat M=cvMat(2,3,CV_32F,m);int w=rsc->width;int h=rsc->height;m[0]=(float)(1*cos(-angle*CV_PI/180.));m[1]=(float)(1*sin(-angle*CV_PI/180.));m[3]=-m[1];m[4]=m[0];m[2]=w*0.5f;m[5]=h*0.5f;cvZero(dst1);cvGetQuadrangleSubPix(rsc,dst1,&M);cvShowImage( "旋转图窗口", dst1 ); //显示目标图像}void Zoom(int,void *)//缩放的调节{dst2_cvsize.width=int(rsc->width*g_nScaleValue/10.0);dst2_cvsize.height=int(rsc->height*g_nScaleValue/10.0);dst2=cvCreateImage(dst2_cvsize,rsc->depth,rsc->nChannels);cvResize(rsc,dst2,CV_INTER_LINEAR);cvShowImage("缩放图窗口",dst2);}。

相关主题