OpenCV实践(3)- 改变图像的对比度和亮度



1 目标

(1)访问像素值;
(2)初始化矩阵为0;
(3)学习saturate_cast做什么和它为什么有用?
(4)Get some cool info about pixel transformations

2 理论

可以参考[计算机视觉:算法和应用](http://szeliski.org/Book/)一文。

3 图像处理

(1)图像处理运算就是一个函数把输入的一个或多个图像,转换为输出图像的过程;
(2)图像变换可以被看成:
a) 像素点的转换;
b) 邻域的操作(基于域的概念);

4 像素变换

在这类转换中,每一个输出像素点仅仅依赖于相对应的输入像素点(潜在地附加一些收集的全面信息和参数)。
这类操作的例子有:亮度和对比度的调整,以及色彩校正和转换。

4.1 亮度和对比度调整

(1) 理论公式为
这里写图片描述
(2) 在这里,这里写图片描述这里写图片描述 被称为增益和偏差参数,有时候,也被认为分别控制对比度和亮度。
(3)你可以认为f(x)是输入图像的像素值,g(x)是输出图像的像素值。那么为了方便我们就可以把上面的公式写为:
这里写图片描述
在这里,i和j分别代表像素点在行和列的位置。

4.2 代码实现

#include 
#include 
#include 

using namespace cv;

double alpha; /**< Simple contrast control */
int beta;  /**< Simple brightness control */

int main( int argc, char** argv )
{
    /// Read image given by user
    Mat image = imread( argv[1] );
    Mat new_image = Mat::zeros( image.size(), image.type() );

    /// Initialize values
    std::cout<<" Basic Linear Transforms "<<std::endl;
    std::cout<<"-------------------------"<<std::endl;
    std::cout<<"* Enter the alpha value [1.0-3.0]: ";std::cin>>alpha;
    std::cout<<"* Enter the beta value [0-100]: "; std::cin>>beta;

    /// Do the operation new_image(i,j) = alpha*image(i,j) + beta
    for( int y = 0; y < image.rows; y++ )
    { for( int x = 0; x < image.cols; x++ )
        { for( int c = 0; c < 3; c++ )
            {
                new_image.at(y,x)[c] = saturate_cast( alpha*( image.at(y,x)[c] ) + beta );
            }
        }
    }

    /// Create Windows
    namedWindow("Original Image", 1);
    namedWindow("New Image", 1);

    /// Show stuff
    imshow("Original Image", image);
    imshow("New Image", new_image);

    /// Wait until user press some key
    waitKey();
    return 0;
}

需要注意的是:
在上面的代码中我们使用for循环访问像素点的原因是,我们想展示每一个像素被应用上面的公式。其实,可以使用Mat.convertTo()函数,语法如下:

image.convertTo(new_image, -1, alpha, beta);

convertTo就会对输入的数据和参数应用上面的公式。

5 结论

将上面的代码编译运行。命令执行过程如下:

./image_contrast_lightness_adjust lyc.jpg 
 Basic Linear Transforms 
-------------------------
* Enter the alpha value [1.0-3.0]: 1   
* Enter the beta value [0-100]: 100
init done 
opengl support available 

(1)alpha = 1,beta = 0;结果如下:
这里写图片描述
我们可以看出两幅图片基本没有什么变化。
(2)alpha = 1,beta = 50;结果如下:
这里写图片描述
(3)alpha = 1,beta = 100;结果如下:
这里写图片描述
结论:beta参数对图像有着显著的影响。
(4)下图是alpha = 1,2,3,beta = 0;结果如下:
这里写图片描述
结果,alpha值越大,与周围的对比度越低。