好迷。。选中了开放评论,审核后还是显示禁止评论。。
本篇是在学习【OpenCV入门教程之六】 创建Trackbar & 图像对比度、亮度值调整一文时的总结所得,希望对读者有所帮助。
一、回调函数 static void on_trackbar(int, void*)
根据createTrackbar函数的要求,它的回调函数的形式必须为void XXX(int, void*),在源程序中,我们将回调函数定义为static(静态函数)类型,有如下几点好处。
1.静态函数只能在声明它的文件中调用,避免了被其他文件误调用。
2.其他文件可以声明相同名字的函数,不会发生冲突。
3.静态函数有相应的存储区,避免压栈出栈,提高了代码的运行速度。
二、回调函数 static void ContrastAndBright(int, void *)
static void ContrastAndBright(int, void *)
{
//创建窗口
namedWindow("【原始图窗口】", 1);
//三个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_nContrastValue*0.01)*(g_srcImage.at<Vec3b>(y,x)[c] ) + g_nBrightValue );
}
}
}
//显示图像
imshow("【原始图窗口】", g_srcImage);
imshow("【效果图窗口】", g_dstImage);
}
对于彩色图像,Image.at<Vec3b>(i,j)[c]可以获取图像在i行j列处的像素在c通道(c=0,G通道;c=1,B通道,c=2,R通道)上的值。
对于灰度图,Image.at<uchar>(i,j)可以获取图像在i行j列处的像素的灰度值。
注:uchar数据类型在存储整数时可以保存[0,255]的值。
saturate_cast函数是图像处理中非常常见的数据溢出保护函数,saturate_cast<uchar>(x)的含义为
if(x<0)
x=0;
else if(x>255)
x=255;
根据官方文档
创建全零图像:C++: static MatExpr Mat::zeros(int rows, int cols, int type)
C++: static MatExpr Mat::zeros(Size size, int type)
C++: static MatExpr Mat::zeros(int ndims, const int* sz, int type)
三、图像对比度、亮度值调整示例程序分析
调节图像的对比度和亮度,需要对图像上各点的像素值进行线性变换g,由于处理的图像为彩色图像,则问题转换为对图像上各点的RGB三个通道上的值分别做线性变换g再进行叠加。因此,一共需要3层for循环,2层用于锁定图片上一点的位置(i,j),1层用于确定当前像素的RGB通道。
我们创建了对比度和亮度两个进度条,一般而言,也应该需要两个回调函数,在这里,作者为了简洁代码,将两个回调函数归一到一个函数中。注意到轨迹条创建函数中的&引用和回调函数static void ContrastAndBright(int, void *)中的参数名,我们可以推断出相应的实现机制。