本博文参考和引用:https://www.cnblogs.com/herenzhiming/articles/5280759.html

介绍

图像增强与图像修复二者之间有一定交叉,尽管它们一个强调客观标准,一个强调主观标准,但毕竟最终的结果都改善了图像的质量。图像去雾就是这两种技术彼此交叉领域中最典型的代表。如果将雾霾看作是一种噪声,那么去除雾霾的标准显然是非常客观的,也就是要将图像恢复至没有雾霾下所获取的情况。但是如果将在雾霾环境下拍摄的照片就看作是一种图像本来的面貌,那么去雾显然就是人们为了改善主观视觉质量而对图像所进行的一种增强。早期图像去雾的研究并没有得到应有的重视,很多人认为它的实际意义不大,甚至觉得所谓的去雾算法多是些华而不实的花拳绣腿,缺乏学术上的价值。然而,斗转星移,时易世变。一方面随着大气污染的日益严重,设法改善自动获取的图像质量其意义不言而喻。另一方面,随着数码设备的普及,消费类电子产品的市场也催生出许多新的需求,其中人们对所拍照片质量的修正和优化就是一个显而易见的需求。说到图像去雾,就不得不提到由何恺明博士等人提出的基于暗通道的图像去雾算法。这个算法因其新颖的思路和理想的效果而广受关注,相关论文也曾于2009年荣获CVPR最佳论文奖,同时也是该奖设立以来,首次由亚洲学者获颁此殊荣。

暗通道的概念和意义





C++实现源代码

main.cpp:

#include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
#include"function.h"
#include<algorithm>
#include<set>
#include<map>using namespace std;
using namespace cv;
//导向滤波器int main()
{Mat src = imread("C:/Users/18301/Desktop/1.png");Mat dst;cvtColor(src, dst, CV_BGR2GRAY);Mat dark_channel_mat = dark_channel(src);//输出的是暗通道图像int A = calculate_A(src, dark_channel_mat);Mat tx = calculate_tx(src, A, dark_channel_mat);Mat tx_ = guidedfilter(dst, tx, 30, 0.001);//导向滤波后的tx,dst为引导图像Mat haze_removal_image;haze_removal_image= haze_removal_img(src, A, tx_);namedWindow("去雾后的图像", 0);namedWindow("原始图像", 0);imshow("原始图像", src);imshow("去雾后的图像", haze_removal_image);waitKey(0);return 0;
}

function.h

#ifndef FUNCTION_H
#define FUNCTION_H   #include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
#include<map>using namespace std;
using namespace cv;
//导向滤波,用来优化t(x),针对单通道
Mat guidedfilter(Mat &srcImage, Mat &srcClone, int r, double eps)
{//转换源图像信息srcImage.convertTo(srcImage, CV_32FC1,1/255.0);srcClone.convertTo(srcClone, CV_32FC1);int nRows = srcImage.rows;int nCols = srcImage.cols;Mat boxResult;//步骤一:计算均值boxFilter(Mat::ones(nRows, nCols, srcImage.type()),boxResult, CV_32FC1, Size(r, r));//生成导向均值mean_IMat mean_I;boxFilter(srcImage, mean_I, CV_32FC1, Size(r, r));//生成原始均值mean_pMat mean_p;boxFilter(srcClone, mean_p, CV_32FC1, Size(r, r));//生成互相关均值mean_IpMat mean_Ip;boxFilter(srcImage.mul(srcClone), mean_Ip,CV_32FC1, Size(r, r));Mat cov_Ip = mean_Ip - mean_I.mul(mean_p);//生成自相关均值mean_IIMat mean_II;//应用盒滤波器计算相关的值boxFilter(srcImage.mul(srcImage), mean_II,CV_32FC1, Size(r, r));//步骤二:计算相关系数Mat var_I = mean_II - mean_I.mul(mean_I);Mat var_Ip = mean_Ip - mean_I.mul(mean_p);//步骤三:计算参数系数a,bMat a = cov_Ip / (var_I + eps);Mat b = mean_p - a.mul(mean_I);//步骤四:计算系数a\b的均值Mat mean_a;boxFilter(a, mean_a, CV_32FC1, Size(r, r));mean_a = mean_a / boxResult;Mat mean_b;boxFilter(b, mean_b, CV_32FC1, Size(r, r));mean_b = mean_b / boxResult;//步骤五:生成输出矩阵Mat resultMat = mean_a.mul(srcImage) + mean_b;return resultMat;
}//计算暗通道图像矩阵,针对三通道彩色图像
Mat dark_channel(Mat src)
{int border = 7;std::vector<cv::Mat> rgbChannels(3);Mat min_mat(src.size(), CV_8UC1, Scalar(0)), min_mat_expansion;Mat dark_channel_mat(src.size(), CV_8UC1, Scalar(0));split(src, rgbChannels);for (int i = 0; i < src.rows; i++){for (int j = 0; j < src.cols; j++){int min_val = 0;int val_1, val_2, val_3;val_1 = rgbChannels[0].at<uchar>(i, j);val_2 = rgbChannels[1].at<uchar>(i, j);val_3 = rgbChannels[2].at<uchar>(i, j);min_val = std::min(val_1, val_2);min_val = std::min(min_val, val_3);min_mat.at<uchar>(i, j) = min_val;}}copyMakeBorder(min_mat, min_mat_expansion, border, border, border, border, BORDER_REPLICATE);for (int m = border; m < min_mat_expansion.rows - border; m++){for (int n = border; n < min_mat_expansion.cols - border; n++){Mat imageROI;int min_num = 256;imageROI = min_mat_expansion(Rect(n - border, m - border, 2*border+1, 2*border+1));for (int i = 0; i < imageROI.rows; i++){for (int j = 0; j < imageROI.cols; j++){int val_roi = imageROI.at<uchar>(i, j);min_num = std::min(min_num, val_roi);}}dark_channel_mat.at<uchar>(m - border, n - border) = min_num;}}return dark_channel_mat;
}int calculate_A(Mat src,Mat dark_channel_mat)
{std::vector<cv::Mat> rgbChannels(3);split(src, rgbChannels);map<int, Point> pair_data;map<int, Point>::iterator iter;vector<Point> cord;int max_val = 0;//cout << dark_channel_mat.rows << " " << dark_channel_mat.cols << endl;for (int i = 0; i < dark_channel_mat.rows; i++){for (int j = 0; j < dark_channel_mat.cols; j++){int val = dark_channel_mat.at<uchar>(i, j);Point pt;pt.x = j;pt.y = i;pair_data.insert(make_pair(val, pt));}}for (iter = pair_data.begin(); iter != pair_data.end(); iter++){//cout << iter->first << endl;cord.push_back(iter->second);}for (int m = 0; m < cord.size(); m++){Point tmp = cord[m];int val_1, val_2, val_3;val_1 = rgbChannels[0].at<uchar>(tmp.y, tmp.x);val_2 = rgbChannels[1].at<uchar>(tmp.y, tmp.x);val_3 = rgbChannels[2].at<uchar>(tmp.y, tmp.x);max_val = std::max(val_1, val_2);max_val = std::max(max_val, val_3);}return max_val;
}Mat calculate_tx(Mat &src, int A, Mat &dark_channel_mat)
{Mat dst;//是用来计算t(x)Mat tx;float dark_channel_num;dark_channel_num = A / 255.0;dark_channel_mat.convertTo(dst, CV_32FC3, 1 / 255.0);//用来计算t(x)dst = dst / dark_channel_num;tx = 1 - 0.95*dst;//最终的tx图return tx;
}Mat haze_removal_img(Mat &src, int A, Mat &tx)
{Mat result_img(src.rows, src.cols, CV_8UC3);vector<Mat> srcChannels(3), resChannels(3);split(src, srcChannels);split(result_img, resChannels);for (int i = 0; i < src.rows; i++){for (int j = 0; j < src.cols; j++){for (int m = 0; m < 3; m++){int value_num = srcChannels[m].at<uchar>(i, j);float max_t = tx.at<float>(i, j);if (max_t < 0.1){max_t = 0.1;}resChannels[m].at<uchar>(i, j) = (value_num - A) / max_t + A;}}}merge(resChannels, result_img);return result_img;
}
#endif

实现结果:

原图像

暗通道图像

t(x)图像

去雾之后的图像

从结果上来看,结果图像仍有一些边缘存在未去的雾,这里是因为t(x)在计算的时候比较粗糙,何凯明在2013年提出了一篇导向滤波可以很好的解决这个问题,关于导向滤波具体算法请参考:导向滤波算法解析

在function.h中已经实现导向滤波,主要针对tx,guidedfilter(Mat &srcImage, Mat &srcClone, int r, double eps)函数,实现结果如下所示:

导向滤波之后的tx

基于导向滤波后的去雾图像

相对于上述未进行导向滤波的结果图像,导向滤波后的结果效果有很大改善。

暗通道去雾及C++实现相关推荐

  1. Python 还能实现图片去雾?FFA 去雾算法、暗通道去雾算法用起来!(附代码)...

    授权自AI科技大本营(ID:rgznai100) 本文约3600字,建议阅读7分钟. 本文为你介绍FFA去雾算法和暗通道去雾算法搭建. 在过去的几十年中,单图像去雾作为基本的低级视觉任务已引起了计算机 ...

  2. 纯c语言实现的改进暗通道去雾算法测试程序(附赠大量测试图像),基于改进暗通道先验算法的图像去雾...

    邱清辉 摘要:针对普通暗通道先验算法去雾能力的不足,本文提出了一种改进算法,通过采用高斯平滑将原图像分为基础子图和细节子图,基础子图采用暗通道先验算法,细节子图采用gamma变换方法,再采用图像融合进 ...

  3. 半年以来的图像去雾总结-图像去雾(一)暗通道去雾

    图像去雾最好的算法原型最好的莫过于何凯明博士的论文--好好阅读,必有灵感 在接下来的博客中,我会分步介绍各个图像去雾算法的研究和对比,在这里,首先介绍最经典的何凯明博士的暗通道去雾算法了,后面的博客有 ...

  4. 暗通道去雾(何恺明的成名作):简洁与效果并存的传统图像处理算法

    本篇博客主要作用为学习代码段与快应用的使用,内容浅显,还请路过的大佬见谅>_< 暗通道去雾算法(Single image haze removal using dark channel p ...

  5. 何恺明暗通道去雾(阅读笔记)

    何恺明暗通道去雾文章阅读 刘海山,2021年6月24日 文献引文信息: He, K. M., Sun, J. & Tang, X. O. Single Image Haze Removal U ...

  6. Python 还能实现图片去雾?FFA 去雾算法、暗通道去雾算法用起来! | 附代码

    在过去的几十年中,单图像去雾作为基本的低级视觉任务已引起了计算机视觉社区和人工智能公司的越来越多的关注.其中最为典型的便是北大&北航提出FFA-Net去雾新网络和何凯明博士提出的暗通道去雾算法 ...

  7. 暗通道去雾法-对算法的理解Dark Channel Prior

    暗通道最早是由He提出的,并且也发展得很快,具体的在这里不说,这篇文章,只是谈一下暗通道去雾的实现过程 1.该方法最原始的模型是I=Jt+A(1-t),这个模型在我的其他文章中有详细介绍,这里不详细讲 ...

  8. Python实现暗通道去雾算法——清晰还原雾天景色

    Python实现暗通道去雾算法--清晰还原雾天景色 在雾天拍摄照片时,画面会变得模糊不清,影响了图片的观感和质量.为了解决这个问题,学术界提出了一种称为"暗通道先验"的方法,这种方 ...

  9. opencv-dark channel -实现暗通道去雾详解

    1.暗通道的概念和含义 暗通道算法是由何恺明在CVPR论文<Single ImageHaze Removalusing Dark Channel Prior>中提出的. 图像去雾的模型: ...

  10. 暗通道去雾算法代码实现(1) python

    文章目录 前言 一.腐蚀膨胀操作 二.何凯明去雾论文思想的简单描述 1.关于暗通道先验 2.暗通道先验的理论依据: 3.有雾图像的形成模型 4.传输率t的估计 5.大气光的估计 6.使用导向滤波对传输 ...

最新文章

  1. sharding jdbc sql路由日志
  2. vc中ASSERT()和VERIFY()区别
  3. iview-admin框架运行步骤
  4. C++ 高级数据类型(六)—— 自定义数据类型
  5. 什么是cmm3规范?什么是CMMI5 呢?
  6. $.ajax %5b%5d,数据传回后台数带有%5B%5D的问题
  7. 嵌入式Linux misc 设备驱动
  8. 教育大数据可视化研究综述笔记
  9. 直播软件搭建时如何在视频通话中加入美颜处理
  10. startx 启动过程
  11. 互联网巨头前沿科技产品一览
  12. 微信小程序图片404时显示默认图片
  13. 笔记:期权定价-无套利理论
  14. Serializable的含义
  15. 在这个阳光明媚的下午
  16. Android-接入谷歌登录
  17. linux的lib目录,Linux 目录结构:/lib 分析
  18. 只有我一个人对ChatGPT感到蕉绿吗?
  19. Flask 消息闪现
  20. qml lisrview嵌套GridView

热门文章

  1. VS2010启动总是遇到异常提示的解决
  2. 一步一步asp.net_三层构架总结
  3. Tomcat—启动时控制台显示文字的颜色
  4. Android 英文文档下载地址
  5. Jquery—重新认识Jquery中的html()方法
  6. LW_OOPC介绍(转载)
  7. 42. Understand the two meanings of typename.
  8. vba自动生成html,动态生成嵌入在VBA电子邮件生成中的HTML表
  9. canva画图 图片居中裁剪_男士秋裤,一片式补裆款裁剪图分享给大家。天凉该给家人做秋裤啦...
  10. ubuntu java apt-get_ubuntu apt-get 安装jdk7