这是一个简化的实现算法,完整的算法请参考:

Single Image Haze Removal Using Dark Channel Prior ——CVPR 2009

// define head function
#ifndef PS_ALGORITHM_H_INCLUDED
#define PS_ALGORITHM_H_INCLUDED #include <iostream>
#include <string>
#include "cv.h"
#include "highgui.h"
#include "cxmat.hpp"
#include "cxcore.hpp" using namespace std;
using namespace cv; void Show_Image(Mat&, const string &); #endif // PS_ALGORITHM_H_INCLUDED #include "PS_Algorithm.h" void Dark_Channel(Mat& src, Mat& dst, int Block_size);
double Atmosperic_Light(Mat& J_dark, Mat& Img);
void Recove_Img(Mat& src, Mat& dst, Mat& T, float Th, float A); int main(void)
{ Mat Img;
Img=imread("5.jpg");
Mat D_Img(Img.size(), CV_32FC3);
Img.convertTo(D_Img, CV_32FC3);
Mat Dark_Img(D_Img.size(), CV_32FC1);
imshow("Img", Img); int Block_size=3;
Dark_Channel(D_Img, Dark_Img, Block_size); float A=0;
A=Atmosperic_Light(Dark_Img, D_Img); float W=0.9;
Mat T(D_Img.size(), CV_32FC1);
T=1-W/A*Dark_Img;
//imshow("Img", T); float Th=0.35;
Mat Img_out(D_Img.size(), CV_32FC3);
Recove_Img(D_Img, Img_out, T, Th, A);
Img_out/=255;
imshow("Out",Img_out); waitKey();
cvDestroyAllWindows(); cout<<"All is well."<<endl;
} void Dark_Channel(Mat& src, Mat& dst, int Block_size)
{
Mat R(src.size(), CV_32FC1);
Mat G(src.size(), CV_32FC1);
Mat B(src.size(), CV_32FC1); Mat m_array[]={R,G,B};
cv::split(src, m_array); int t=0;
t=(Block_size-1)/2; Mat a1(Block_size, Block_size, CV_32FC1);
Mat a2(Block_size, Block_size, CV_32FC1);
Mat a3(Block_size, Block_size, CV_32FC1); double min_a1=0;
double min_a2=0;
double min_a3=0; double min_value=0; for(int i=t; i<dst.rows-t; i++)
{
for(int j=t; j<dst.cols-t; j++)
{
a1=R(Range(i-t,i+t+1), Range(j-t,j+t+1));
a2=G(Range(i-t,i+t+1), Range(j-t,j+t+1));
a3=B(Range(i-t,i+t+1), Range(j-t,j+t+1)); cv::minMaxLoc(a1, &min_a1,NULL,NULL,NULL);
cv::minMaxLoc(a2, &min_a2,NULL,NULL,NULL);
cv::minMaxLoc(a3, &min_a3,NULL,NULL,NULL); min_value=min(min_a1, min_a2);
min_value=min(min_a3, min_value); dst.at<float>(i,j)=(float)min_value;
}
} dst(Range(0,t), Range::all())=dst(Range(t,2*t), Range::all());
dst(Range(dst.rows-t,dst.rows), Range::all())=
dst(Range(dst.rows-(2*t),dst.rows-t), Range::all()); dst(Range::all(), Range(0,t))=dst(Range::all(),Range(t,2*t));
dst(Range::all(),Range(dst.cols-t,dst.cols))=
dst(Range::all(), Range(dst.cols-2*t,dst.cols-t)); } double Atmosperic_Light(Mat& J_dark, Mat& Img)
{ Mat M1(J_dark.size(), CV_32FC1);
M1=J_dark;
M1.reshape(0,1);
Mat M2(1,J_dark.rows*J_dark.cols, CV_32FC1);
cv::sort(M1,M2,CV_SORT_ASCENDING); int Index=J_dark.rows*J_dark.cols*0.9999;
float T_value=M2.at<float>(0, Index); float value=0;
float Temp_value;
float r_temp, g_temp, b_temp; for(int i=0; i<Img.rows; i++)
{
for(int j=0; j<Img.cols; j++)
{
Temp_value=J_dark.at<float>(i,j);
if(Temp_value>T_value)
{
r_temp=Img.at<Vec3f>(i,j)[0];
g_temp=Img.at<Vec3f>(i,j)[1];
b_temp=Img.at<Vec3f>(i,j)[2]; Temp_value=(r_temp+g_temp+b_temp)/3.0; value=max(value, Temp_value); } }
} return value;
} void Recove_Img(Mat& src, Mat& dst, Mat& T, float Th, float A)
{ float value=0; for(int i=0; i<src.rows; i++)
{
for(int j=0; j<src.cols; j++)
{
value=max(Th, T.at<float>(i,j));
dst.at<Vec3f>(i,j)[0]=(src.at<Vec3f>(i,j)[0]-A)/value+A;
dst.at<Vec3f>(i,j)[1]=(src.at<Vec3f>(i,j)[1]-A)/value+A;
dst.at<Vec3f>(i,j)[2]=(src.at<Vec3f>(i,j)[2]-A)/value+A;
}
} }

原图


效果图

OpenCV——去雾的更多相关文章

  1. OpenCV导向滤波(引导滤波)实现(Guided Filter)代码,以及使用颜色先验算法去雾

    论文下载地址:http://research.microsoft.com/en-us/um/people/jiansun/papers/GuidedFilter_ECCV10.pdf 本文主要介绍导向 ...

  2. 基于暗通道优先算法的去雾应用(Matlab/C++)

    基于暗通道优先的单幅图像去雾算法(Matlab/C++) 算法原理:             参见论文:Single Image Haze Removal Using Dark Channel Pri ...

  3. 《Single Image Haze Removal Using Dark Channel Prior》一文中图像去雾算法的原理、实现、效果(速度可实时)

    最新的效果见 :http://video.sina.com.cn/v/b/124538950-1254492273.html 可处理视频的示例:视频去雾效果 在图像去雾这个领域,几乎没有人不知道< ...

  4. paper 105: 《Single Image Haze Removal Using Dark Channel Prior》一文中图像去雾算法的原理、实现、效果及其他

    在图像去雾这个领域,几乎没有人不知道<Single Image Haze Removal Using Dark Channel Prior>这篇文章,该文是2009年CVPR最佳论文.作者 ...

  5. paper 100:何恺明经典去雾算法

    一:由简至美的最佳论文(作者:何恺明  视觉计算组) [视觉机器人:个人感觉学习他的经典算法固然很重要,但是他的解决问题的思路也是非常值得我们学习的] 那是2009年4月24日的早上,我收到了一封不同 ...

  6. 基于clahe的图像去雾

    基于clahe的图像去雾     通过阅读一些资料,我了解到clahe算法对图像去雾有所价值,正好opencv中有了实现,拿过来看一看.   但是现在实现的效果还是有所差异 #);    clahe] ...

  7. Retinex图像增强和暗通道去雾的关系及其在hdr色调恢复上的应用

    很多人都认为retinex和暗通道去雾是八杆子都打不着的增强算法.的确,二者的理论.计算方法都完全迥异,本人直接从二者的公式入手来简单说明一下,有些部分全凭臆想,不对之处大家一起讨论. 首先,为描述方 ...

  8. 暗通道去雾算法的python实现

    何凯明博士的去雾文章和算法实现已经漫天飞了,我今天也就不啰里啰唆,直接给出自己python实现的完整版本,全部才60多行代码,简单易懂,并有简要注释,去雾效果也很不错. 在这个python版本中,计算 ...

  9. 一种可实时处理 O(1)复杂度图像去雾算法的实现。

    在我博文的一系列的文章,有不少算法都于去雾有关,比如限制对比度自适应直方图均衡化算法原理.实现及效果.局部自适应自动色阶/对比度算法在图像增强上的应用这两个增强算法都有一定的去雾能力,而最直接的就是& ...

随机推荐

  1. Ejb远程调用-jboss服务器调用服务器-Bean调用Bean

    英文参考地址 https://docs.jboss.org/author/display/AS71/Remote+EJB+invocations+via+JNDI+-+EJB+client+API+o ...

  2. Effective C++ ——模板和泛型编程

    条款41:了解隐式接口和编译器多态 以public继承的类,

  3. Cocos2D:变换(transforms)在图形编程中扮演的角色

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交 ...

  4. 14 Fragment 碎片总结

    Fragment 碎片 一, Fragment是什么? Android 3.0以后出现的 Api11 以上 Activity的组成部分 Fragment(小的Activity) Fragment可以显 ...

  5. Dynamics CRM 检测访问CRM延迟及带宽的工具

    直接在浏览器中访问如下地址"http://CRMHOST/organization/tools/diagnostics/diag.aspx"(这里的CRMHOST和organiza ...

  6. Java Math的 floor,round和ceil

    floor 返回不大于的最大整数 round 则是4舍5入的计算,入的时候是到大于它的整数 round方法,它表示"四舍五入",算法为Math.floor(x+0.5),即将原来的 ...

  7. 运用 三种 原生 谷歌 阿里 解析和生成json

    三种类生成JSON数据方法 JSON(原生): 第一种 JSONStringer和JSONObject区别在于添加对象时是按顺序添加的比如说 JSONStringer 添加 a:1 b:2 c:3那么 ...

  8. java实现异步调用实例

    在JAVA平台,实现异步调用的角色有如下三个角色: 调用者 取货凭证   真实数据 一个调用者在调用耗时操作,不能立即返回数据时,先返回一个取货凭证.然后在过一断时间后凭取货凭证来获取真正的数据.  ...

  9. Android日历视图(CalendarView)讲解-android学习之旅(三十六)

    CalendarView简介 CalendarView用于显示和选择日期,如果希望监听事件的改变可以用setOnDateChangeListener()方法. CalendarView属性介绍 代码示 ...

  10. 如何彻底的删除MySQL数据库(图文教程)

    最近有个小课题数据库使用Mysql,提前写一下Mysql作为复习. 第一步当然是要看如何卸载Mysql,因为安装之前要清理掉一切与Mysql有关的数据,否则后边安装失败. 以下操作以Window7操作 ...