改变图片的对比度和亮度可直接使用opencv库中的像素转换函数convertTo()。
Mat imgProc(Mat myImg,float contrast, int brightness)
{
Mat imgSrc = myImg;
Mat imgDst = Mat::zeros (imgSrc.size(),imgSrc.type ());//生成零像素矩阵
imgSrc.convertTo (imgDst,-1,contrast,brightness);
return imgDst;
}
函数原型:
void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;
@brief Converts an array to another data type with optional scaling.
The method converts source pixel values to the target data type. saturate_cast\<\> is applied at
the end to avoid possible overflows:\f[m(x,y) = saturate \_ cast<rType>( \alpha (*this)(x,y) + \beta )\f]
@param m output matrix; if it does not have a proper size or type before the operation, it is
reallocated. m为输出的矩阵
@param rtype desired output matrix type or, rather, the depth since the number of channels are the
same as the input has; if rtype is negative, the output matrix will have the same type as the input.为负数时,输入输出为相同类型
@param alpha optional scale factor.增益参数,控制图片对比度
@param beta optional delta added to the scaled values.β是偏置参数,控制图片亮度
convertTo(imgDst, -1, con, bri);OpenCV增强图像使用的是点算子,即用常数对每个像素点执行乘法和加法的复合运算,公式如下:
式中,f (i, j)代表一个原图像像素点;a是增益参数,控制图像对比度;b是偏置参数,控制图片亮度;而g (i, j)则表示经处理后的对应像素点。
知道了原理之后可以将convertTo()改成自己的实现方法:
Mat imgProc(Mat myImg,float contrast, int brightness)
{
Mat imgSrc = myImg;
Mat imgDst = Mat::zeros (imgSrc.size(),imgSrc.type ());//生成零像素矩阵
//执行运算 imgDst(i,j) = contrast * imgSrc(i,j) + brightness;
for(int i=0; i<imgSrc.rows; i++)
{
for(int j=0; j<imgSrc.cols; j++)
{
for(int c=0; c<3; c++)
{
imgDst.at<Vec3b>(i,j)[c] = saturate_cast<uchar>(contrast *(imgSrc.at<Vec3b>(i,j)[c] +brightness));
}
}
}
return imgDst;
}
imgDst.at<Vec3b>(i,j)[c]:
为了能够直接访问图片中的每个像素,我们使用 imgDst.at<Vec3b>(i,j)[c],其中i表示像素所在的行,j表示像素所在的列,c是RGB标准像素三个彩色通道之一。由于算法的结果可能超出像素标准的取值范围,也可能是非整数,所以要使用saturate_cast对结果进行一次转换,以确保它为有效值。
注释:
saturate_cast<uchar>主要是为了防止颜色溢出操作,在图像处理方面,无论是加是减,乘除,都会超出一个像素灰度值的范围(0~255),saturate_cast函数的作用即是:当运算完之后,结果为负,则转为0,结果超出255,则为255。
原理大致如下
if(data<0)
data=0;
elseif(data>255)
data=255;