原标题:专栏 | OpenCV图像处理专栏十 | 利用中值滤波进行去雾
前言
这是OpenCV图像处理专栏的第十篇文章,介绍一种利用中值滤波来实现去雾的算法。这个方法发表于国内的一篇论文,链接我放附录了。
算法原理
这个算法和之前He Kaiming的暗通道去雾都基于大气散射模型即: 其中 就是输入图像,需要求去雾后的输出图像 ,所以我们只要计算出全局大气光值 和透射率 就可以了。其他的一些介绍和背景交代可以去看原文,这里我直接给出论文的算法核心步骤。
1、定义 ,焦作大气光幕或者雾浓度。
2、计算,即是求暗通道,这一点在 OpenCV图像处理专栏六 | 来自何凯明博士的暗通道去雾算法(CVPR 2009最佳论文) 我已经详细说明了。
3、计算,即对 进行中值滤波得到 。
4、计算,注意式子中取了绝对值。
5、计算,式子中 是控制去雾浓度的系数,取值为 。
6、通过式子获得去雾后的图像,这个式子就是把原始子移项变形得到的。
7、自此,算法结束,得到了利用中值滤波实现的去雾后的结果。
int rows, cols;
//获取最小值矩阵
int **getMinChannel(cv::Mat img) {
rows = img.rows;
cols = img.cols;
if (img.channels != 3) {
fprintf(stderr, "Input Error!");
exit(-1);
}
int **imgGray;
imgGray = new int *[rows];
for (int i = 0; i < rows; i++) {
imgGray[i] = new int[cols];
}
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
int loacalMin = 255;
for (int k = 0; k < 3; k++) {
if (img.at(i, j)[k] < loacalMin) {
loacalMin = img.at(i, j)[k];
}
}
imgGray[i][j] = loacalMin;
}
}
return imgGray;
}
//求暗通道
int **getDarkChannel(int **img, int blockSize = 3) {
if (blockSize % 2 == 0 || blockSize < 3) {
fprintf(stderr, "blockSize is not odd or too small!");
exit(-1);
}
//计算pool Size
int poolSize = (blockSize - 1) / 2;
int newHeight = rows +