一、背景
图像增强作为视频后处理中画质增强技术的一部分,指的是通过调整图片和视频图像画面的饱和度特性,使得画面色彩更加丰富和逼真,提升人的视觉主观感受。由于设备摄像头的多样性,部分摄像头在视频采集时存在饱和度不足,画面发灰,色彩寡淡等问题,这些情况在拍摄室外景物和颜色丰富的场景时尤其容易出现。这些问题可以通过算法的后处理调整进行改善。色彩增强配合视频降噪,暗光增强,对比度调整,边缘增强等技术,可以对视频画质起到较大的提升作用。
二、基本概念
HSV与RGB概念介绍
HSV(Hue, Saturation, Value)和 RGB(Red, Green, Blue)是两种不同的颜色表示方法,各自有不同的特点和应用场景。
RGB(红、绿、蓝)
RGB 是一种基于光的颜色表示方法,通过红、绿、蓝三个颜色通道的不同组合来表示各种颜色。每个通道的值范围通常是 0 到 255。
特点:
- 加色模型:RGB 是一种加色模型,主要用于显示器、电视、相机等基于发光原理的设备。
- 颜色表示直观:直接表示颜色,但不容易进行颜色操作,例如调节亮度、饱和度等。
颜色表示:
- 纯红色:RGB(255, 0, 0)
- 纯绿色:RGB(0, 255, 0)
- 纯蓝色:RGB(0, 0, 255)
- 白色:RGB(255, 255, 255)
- 黑色:RGB(0, 0, 0)
三、代码实现-基础篇(OpenCV+C)
通过OpenCV我们可以实现简单的基于RGB图像的亮度、对比度的变换(增强或者减弱),代码如下:
int AdjustImgRGB() {
// 读取图像
Mat src = imread("D:\\测试视频\\1.jpg");
if (src.empty()) {
cout << "could not load image." << endl;
return -1;
}
// 调整亮度和对比度调整参数
double alphaB = 1.5; // 对比度调整系数(1.0-3.0)
double alphaG = 1.5; // 对比度调整系数(1.0-3.0)
double alphaR = 1.5; // 对比度调整系数(1.0-3.0)
int beta = 0; // 亮度偏移量(0-100)
// 新建目标图像
Mat dst = Mat::zeros(src.size(), src.type());
int rows = src.rows;
int cols = src.cols;
#if 0
for (int row = 0; row < rows - 1; row++) {
for (int col = 0; col < cols - 1; col++) {
// 获取像素
int b = src.at<Vec3b>(row, col)[0];
int g = src.at<Vec3b>(row, col)[1];
int r = src.at<Vec3b>(row, col)[2];
// 调整亮度和对比度
dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(alphaB * b + beta);
dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(alphaG * g + beta);
dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(alphaR * r + beta);
}
}
#else
src.convertTo(dst, -1, alphaB, beta);
#endif
Mat res = dst.clone(); //复制原始图片对象,作为储存变换结果的对象
cv::imwrite("D:\\测试视频\\1-adjust.jpg", res);
return 0;
}
#endif
通过以上代码我们可以实现对图像亮度和对比度的调整,但是调整的图像会有明显的图像失真(曝光过度或者曝光不足),如下图对比:
原图:
调整参数 alpha = 1.5,beta=0; 参数值只调整对比度,不调整亮度,调整后图像:
因为增强了图像对比度导致了图像变的失真,这显然不是我们想要的结果,所以,我们需要对调整后的图像进行校正,我们称之为 gamma(γ)校正,具体实现代码如下:
//γ校正
double gamma_{ 1.2 }; //确定gamma值
Mat lookUpTable(1, 256, CV_8U); //新建查询表
uchar* p = lookUpTable.ptr(); //获取查询表的指针,方便后面填充值
for (int i{ 0 }; i < 256; ++i) //填充查询表
p[i] = saturate_cast<uchar>(pow(i / 255.0, gamma_) * 255.0); //非线性转换算法
LUT(dst, lookUpTable, res); //按查询表中的值,替换原始图片中的值
如上代码所示,我们设置一个gamma值,该值为1则为不矫正,0-1则是减弱图像调整效果,大于1则增强调整效果,在上文图像调整代码不变的基础上,我们进行1.5倍的gamma矫正,具体效果如下:
对比未校正调整参数 alpha = 1.5,beta=0; 调整的图像:
我们发现亮度有所降低,失真率有所降低,而如果我们调低矫正参数,可以得到意想不到的效果,设置gamma=0.4调整后图像如下:
我们从上面调整后的图片可以看到,调整后的图像其阴影的地方变的明亮了也变得更清晰了,变相的实现了图像的黑暗变明亮的增强效果,所以我们一般就可以用他来实现图像的亮度增强,感兴趣的同学可以学习以下文章学习更多OpenCV图像处理相关的东西:https://www.w3cschool.cn/opencv/opencv-c6yv2cb1.html
当然,以上代码实现算法依然有其致命的缺陷,我们可以看到图像不管是增强和减弱亮度,图像还是会有不同层度的失真,而且亮度非常难以控制,所以,我们在下一篇文章中会进行进阶篇的讲解,如何在尽量不失真的情况下,增加图像的色彩饱和度和明度。