Opencv图像增强算法实现(直方图均衡化、Laplace、Log、Gamma) | Chuan·Yen
一、简介
图像增强的算法是一个让图像失真的过程,是为了突出响应的一些特征,方便我们对感兴趣区域进行处理,一般有四种方法 直方图均衡化、Laplace、Log、Gamma
二、直方图均衡化
图像对比度增强的方法可以分成两类:一类是直接对比度增强方法;另一类是间接对比度增强方法。
直方图拉伸和直方图均衡化是两种最常见的间接对比度增强方法。
直方图拉伸是通过对比度拉伸对直方图进行调整,从而“扩大”前景和背景灰度的差别,以达到增强对比度的目的,这种方法可以利用线性或非线性的方法来实现。
直方图均衡化则通过使用累积函数对灰度值进行“调整”以实现对比度的增强。
- 优点:这种方法对于背景和前景都太亮或者太暗的图像非常有用,这种方法尤其是可以带来X光图像中更好的骨骼结构显示以及曝光过度或者曝光不足照片中更好的细节。这种方法的一个主要优势是它是一个相当直观的技术并且是可逆操作,如果已知均衡化函数,那么就可以恢复原始的直方图,并且计算量也不大。
- 缺点:缺点是它对处理的数据不加选择,它可能会增加背景杂讯的对比度并且降低有用信号的对比度;变换后图像的灰度级减少,某些细节消失;某些图像,如直方图有高峰,经处理后对比度不自然的过分增强。
彩色图像的直方图均衡化实现:
#if 1 // 图像增强算法 --直方图均衡化图像增强
int main(int args, char* arg)
{
Mat src = imread("C:\\Users\\19473\\Desktop\\opencv_images\\88.jpg");
if (!src.data)
{
printf("could not load image....\n");
}
imshow("input_demo", src);
Mat stc_bgr[3];
Mat dst;// 增强后的图像
split(src, stc_bgr); //
for (int i=0;i<3;i++)
{
equalizeHist(stc_bgr[i], stc_bgr[i]);
}
merge(stc_bgr,3,dst); // 合并
imshow("增强后的图像", dst);
waitKey(0);
return -1;
}
#endif
三、Laplace图像增强
拉普拉斯算子可以增强局部的图像对比度。
Laplace 8邻域卷积核:
0 -1 0
-1 5 -1
0 -1 0
采用filter2D函数实现对图像的卷积:
#if 1 // 图像增强算法 --拉普拉斯利用卷积核增强
int main(int args, char* arg)
{
Mat src = imread("C:\\Users\\19473\\Desktop\\opencv_images\\88.jpg");
if (!src.data)
{
printf("could not load image....\n");
}
imshow("input_demo", src);
Mat dst;
Mat kernel = (Mat_<int>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D(src, dst, src.depth(), kernel);
imshow("增强后的图像", dst);
waitKey(0);
return -1;
}
#endif
四、对数Log变换图像增强
对数变换可以将图像的低灰度值部分扩展,显示出低灰度部分更多的细节,将其高灰度值部分压缩,减少高灰度值部分的细节,从而达到强调图像低灰度部分的目的。变换方法:
对于不同的底数,底数越大,对低灰度部分的扩展就越强,对高灰度部分的压缩也就越强。
#if 1 // 图像增强算法 --log 变换增强
int main(int args, char* arg)
{
Mat src = imread("C:\\Users\\19473\\Desktop\\opencv_images\\613.png");
if (!src.data)
{
printf("could not load image....\n");
}
imshow("原图像", src);
// 注意点 : CV_32FC3
Mat dst(src.size(), CV_32FC3);
for (int i = 0; i < src.rows; i++)
{
for (int j = 0; j < src.cols; j++)
{
// 对bgr 的每个通道都进行计算
dst.at<Vec3f>(i, j)[0] = log(1 + src.at<Vec3b>(i, j)[0]);
dst.at<Vec3f>(i, j)[1] = log(1 + src.at<Vec3b>(i, j)[1]);
dst.at<Vec3f>(i, j)[2] = log(1 + src.at<Vec3b>(i, j)[2]);
}
}
// 归一化
normalize(dst, dst, 0, 255, CV_MINMAX);
convertScaleAbs(dst, dst);
imshow("增强后的图像", dst);
waitKey(0);
return -1;
}
#endif
五、 伽马变换的图像增强
伽马变换主要用于图像的校正,将灰度过高或者灰度过低的图片进行修正,增强对比度。变换公式就是对原图像上每一个像素值做乘积运算:
伽马变换对于图像对比度偏低,并且整体亮度值偏高(对于于相机过曝)情况下的图像增强效果明显。
#if 1 // 图像增强算法 --gamma
int Gamma = 2;
int main(int args, char* arg)
{
Mat src = imread("C:\\Users\\19473\\Desktop\\opencv_images\\88.jpg");
if (!src.data)
{
printf("could not load image....\n");
}
imshow("原图像", src);
// 注意点 : CV_32FC3
Mat dst(src.size(), CV_32FC3);
for (int i = 0; i < src.rows; i++)
{
for (int j = 0; j < src.cols; j++)
{
// 对bgr 的每个通道都进行计算
dst.at<Vec3f>(i, j)[0] = pow(src.at<Vec3b>(i, j)[0], Gamma);
dst.at<Vec3f>(i, j)[1] = pow(src.at<Vec3b>(i, j)[1], Gamma);
dst.at<Vec3f>(i, j)[2] = pow(src.at<Vec3b>(i, j)[2], Gamma);
}
}
// 归一化
normalize(dst, dst, 0, 255, CV_MINMAX);
convertScaleAbs(dst, dst);
imshow("增强后的图像", dst);
waitKey(0);
return -1;
}
#endif