我们首先要知道,进行图像变换主要有两种方式:
1、基于像素操作–即点操作。比如调节图像的对比度和亮度。
2、基于领域操作–区域。比如卷积,提取特征等等。
那么调节图像的亮度和对比度,是基于像素操作,属于点操作范畴。
先来看看公式。
其中f(i,j)就是原始图像某个像素点的值,而g(i,j)是新的像素点的值。
我们可以看到,
是调节图像的亮度的,为什么这么说呢,在Opencv中图像的像素值是0-255之间,越靠近255(白色),图像越量。所以
值越大,像素值越靠近255,所以图像越亮。而
则是调节对比度,你可以这样想,比如某点A像素值为2,旁边像素B点值为10,这个时候它们相差8,而如果乘上
,假如
为2。则A的像素值为4,B的像素值为20,它们的差距是不是变大了2倍。差距变大,是不是说明它们之间的对比是不是很明显。记得前面我们也讲过一个提高对比度的方式,还记得不?就是掩模。opencv中的filter2D函数。
所以这么理解的话,是不是有了一个清晰的认识。好了,接下来就是代码时间。
Mat src=imread("D:\\test1.jpg");
if(src.empty())
{
qDebug()<<"fail to load";
return;
}
int height=src.rows;
int width=src.cols;
Mat dst=Mat::zeros(src.size(),src.type());
float ala=1.2;
float beta=30;
for(int i=0;i<height;i++)
{
for(int j=0;j<width;j++)
{
if(src.channels()==3)
{
float b=src.at<Vec3b>(i,j)[0];
float g=src.at<Vec3b>(i,j)[1];
float r=src.at<Vec3b>(i,j)[2];
dst.at<Vec3b>(i,j)[0]=saturate_cast<uchar>(ala*b+beta);
dst.at<Vec3b>(i,j)[1]=saturate_cast<uchar>(ala*g+beta);
dst.at<Vec3b>(i,j)[2]=saturate_cast<uchar>(ala*r+beta);
}else
{
float b=src.at<uchar>(i,j);
dst.at<uchar>(i,j)=saturate_cast<uchar>(ala*b+beta);
}
}
}
imshow("src",src);
imshow("dst",dst);
waitKey(-1);
需要注意的是在计算像素值的时候,一定要用saturate_cast,以保证像素值在0-255之间。
运行结果如图:
我们可以看到对比度和亮度是有一定的提升了,这里还可以去调节两个参数的值,使图像变得更加合适。