《OpenCV图像处理》
---上机实验报告 1
1.实验题目:改变图像的对比度和亮度
2.实验目的:
(1)访问像素值;
(2)用0初始化矩阵;
(3)saturate cast是做什么用的,以及它为什么有用。
3.实验原理:
(1)图像处理:一般来说,图像处理算子是带有一幅或多幅输入图像、产生一幅输出图像的函数。图像变换可分为以下两种:点算子(像素变换)、领域(基于区域的)算子;
(2)像素变换:在这一类图像处理变换中,仅仅根据输入像素值(有时可加上某些全局信息或参数)计算相应的输出像素值。这类算子包括亮度和对比度调整,以及颜色校正和变换;
(3)亮度和对比度调整:两种常用的点过程(即点算子),是用常数对点进行乘法和加法运算g(x)=αf(x)+ß;
(4)两个参数>0和一般称作增益和偏置参数。我们往往用这两个参数来控制对比度和亮度;
(5)你可以把看成源图像像素,把g(x)看成输出图像像素。这样一来,上面的式子就能写的更清楚些g(i,j)=α*f(i,j)+β,其中i,j表示像素位于第i行和第j列。
4.实验步骤:
(1)建立两个变量,以便存储用户输入的α和β:
(2)用imread载入图像,并将其存入一个Mat对象:
(3)此时,因为要对图像进行变换,所以我们需要一个新的Mat对象,以存储变换后的图像,我们希望这个Mat对象具有如下性质:
1)像素值初始化为0;
2)与原图像有相同的大小和类型。
注意到:Mat::Zeros采用Matlab风格的初始化方式,用image.size()和image.type()来对Mat对象进行0初始化。
(4)现在为了执行运算g(i,j)=α*f(i,j)+β,我们要访问图像的每一个像素,因为是对RGB图像进行运算,每个像素有三个值(R,G,B),所以要分别访问他们,下面是访问像素的代码片段:
注意:为了访问图像的每一个像素,我们使用如下语法image.at (5)最后,用传统方法创建窗口并显示图像: 5.实验结果: 6.源程序: #include #include #include #include #include #include using namespace std; using namespace cv; Mat src,erosion_dst,dilation_dst; int erosion_elem=0; int erosion_size=0; int dilation_elem=0; int dilation_size=0; int const max_elem=2; int const max_kernel_size=21; void Erosion(int ,void*); void Dilation(int ,void*); int main(int argc,char** argv) { src=imread(); if(!src.data) {return -1;} namedWindow("Erosion Demo", CV_WINDOW_AUTOSIZE ); namedWindow("Dilation Demo", CV_WINDOW_AUTOSIZE ); cvMoveWindow("Dilation Demo",src.cols,0); createTrackbar("Element:\\n0:Rect\\n1:Cross\\n2:Ellipse","Erosion Demo", &erosion_elem,max_elem, Erosion); createTrackbar("Kernel size:\\n 2n +1","Erosion Demo", &erosion_size,max_kernel_size, Erosion); createTrackbar("Element:\\n0:Rect\\n1:Cross\\n2:Ellipse","Dilation Demo",&dilation_elem,max_elem,Dilation); createTrackbar("Kernel size:\\n 2n +1","Dilation Demo",&dilation_size,max_kernel_size,Dilation); Erosion(0,0); Dilation(0,0); waitKey(0); return 0; } void Erosion(int,void*) { int erosion_type; if(erosion_elem==0){erosion_type=MORPH_RECT;} else if(erosion_elem==1){erosion_type=MORPH_CROSS;} else if(erosion_elem==2){erosion_type=MORPH_ELLIPSE;} Mat element=getStructuringElement(erosion_type,Size(2*erosion_size+1,2*erosion_size+1), Point(erosion_size,erosion_size)); erode(src,erosion_dst,element); imshow("Eerosion Demo",erosion_dst); } void Dilation(int,void*) { int dilation_type; if(dilation_elem==0){dilation_type=MORPH_RECT;} else if(dilation_elem==1){dilation_type=MORPH_CROSS;} else if(dilation_elem==2){dilation_type=MORPH_ELLIPSE;} Mat element=getStructuringElement(dilation_type,Size(2*dilation_size+1,2*dilation_size+1), Point(dilation_size,dilation_size)); erode(src,dilation_dst,element); imshow("Dilation Demo",dilation_dst); }