基于opencv对图像的预处理.docx
《基于opencv对图像的预处理.docx》由会员分享,可在线阅读,更多相关《基于opencv对图像的预处理.docx(14页珍藏版)》请在冰点文库上搜索。
基于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.详细设计
整个设计函数之间的的关系如下所示:
图二、函数关系图
利用include加载整个程序需要的库函数;定义相应的字符串变量、整形变量和指针变量并给他们赋初值;以下是整个设计中函数设计和运行的结果:
(1)main()利用imread和cvLoadImage从文件夹中加载图像,运用if判断语句看是否读入图像成功,如过读入图像没有成功,则退出程序,如果读入图像成功则利用nameWindow创建并命名为原始图、滑动控制和对比度和亮度窗口,然后将图像显示在特定的窗口上,执行滑动控制函数createTrackbar();主函数得到原始图如下所示:
(2)createTrackbar()其中括号的包括的容为(conststring&trackbarname,conststring&winname,int*value,intcount,TrackbarCallbackonChange=0,);第一个参数,conststring&类型的trackbarname,表示轨迹条的名字,用来代表我们创建的轨迹条;第二个参数,conststring&类型的winname,填窗口的名字,表示这个轨迹条会依附到哪个窗口上,即对应namedWindow()创建窗口时填的某一个窗口名;第三个参数,int*类型的value,一个指向整型的指针,表示滑块的位置。
并且在创建时,滑块的初始位置就是该变量当前的值;第四个参数,int类型的count,表示滑块可以达到的最大位置的;第五个参数,TrackbarCallback类型的onChange,首先注意他有默认值0。
这是一个指向回调函数的指针,每次滑块位置改变时,这个函数都会进行回调。
并且这个函数的原型必须为voidXXXX(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]的数组,定义一个图形矩阵CvMatM,将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
#include"highgui.h"
usingnamespacecv;
staticvoidContrastAndBright(int,void*);
staticvoidRotate(int,void*);
staticvoidZoom(int,void*);
staticvoidStatiate(int,void*);
stringstrWindowName="滑动控制";
stringstrWindowName1="对比度亮度效果图窗口";
stringstrTraName="对比度";
stringstrTraName1="亮度";
stringstrTraName2="饱和度";
stringstrTraName3="缩放";
stringstrTraName4="旋转";
intg_nContraValue=0;
intg_nBrightValue=0;
intfactor=0;
intg_nScaleValue=0;
intangle=0;
IplImage*rsc=0;//源图像指针
IplImage*dst1=0;//目标图像指针
IplImage*dst2=0;
IplImage*dst3=0;
CvSizedst1cv_size;//目标图像尺寸
CvSizedst2_cvsize;//
Matg_srcImage,g_dstImage;
intmain()
{
system("color5E");
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,ContrastAndBright);
createTrackbar(strTraName1,strWindowName,&g_nBrightValue,100,ContrastAndBright);
createTrackbar(strTraName2,strWindowName,&factor,512,Statiate);
createTrackbar(strTraName3,strWindowName,&g_nScaleValue,20,Zoom);
createTrackbar(strTraName4,strWindowName,&angle,360,Rotate);
waitKey(0);
return0;
}
voidContrastAndBright(int,void*)//对比和亮度的调节
{//三个for循环,执行运算g_dstImage(i,j)=a*g_srcImage(i,j)+b
for(inty=0;y{
for(intx=0;x{
for(intc=0;c<3;c++)
{
g_dstImage.at(y,x)[c]=saturate_cast((g_nContraValue*0.01)*(g_srcImage.at(y,x)[c])+g_nBrightValue);
}
}
}
imshow(strWindowName1,g_dstImage);
}
voidStatiate(int,void*)//饱和度的调节
{
IplImage*hist_image=0;
dst3=cvCloneImage(rsc);
cvCvtColor(rsc,dst3,CV_BGR2HSV);
inthue=factor-256;
inti;
floatmax_value=0;
ucharlut[256][3];
CvMat*lut_mat;
lut_mat=cvCreateMatHeader(1,256,CV_8UC3);
cvSetData(lut_mat,lut,0);
for(i=0;i<256;i++){
intv=(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);
}
voidRotate(int,void*)//旋转的调节
{
dst1=cvCloneImage(rsc);
floatm[6];
CvMatM=cvMat(2,3,CV_32F,m);
intw=rsc->width;
inth=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);//显示目标图像
}
voidZoom(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);
}