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

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. 使用Java正则表达式去掉Double类型的数据后面多余的0

    方法 /** * 使用java正则表达式去掉多余的.与0 * @param s * @return */ public static String subZeroAndDot(String s){ i ...

  2. memcached实战系列(四)memcached stats命令 memcached优化

    memcached提供一系列的命令进行优化的查看,方便我们调整我们的存储策略,查看我们的使用率,内存的使用率以及浪费情况.常用的命令有stats.stats settings.stats items. ...

  3. 基于CAS实现单点登录(SSO):工作原理

    工作中使用到了SSO,网上看到了这个博客的一系列文章感觉不错,转载收藏 源地址http://blog.csdn.net/tch918/article/details/19930037 系列文章的第一篇 ...

  4. 13 获取外部数据库 以及数据库游标适配器(SimpleCursorAdapter)

    获取外部数据库 API SQLiteDatabase db = SQLiteDatabase.openDatabase(path, factory, flags); 参数详解: path:数据库路径 ...

  5. UITableView如何撤销移动操作

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我们知道使用UITableView的委托方法canMoveRo ...

  6. java wait和notify及 synchronized sleep 总结

    java 中线程我一直弄不清线程锁等 所以写了一些例子验证看法: 在这之前先看下API中wait中的解释: wait:方法来之java.lang.Objetc 方法翻译:在其他线程调用此对象的 not ...

  7. Salt: Master server cannot see any Minion

    Issue: When you set up a Salt Master server and several Minions, you may find that none of minions c ...

  8. Mybatis源码之Statement处理器CallableStatementHandler(六)

    CallableStatementHandler实际就是使用CallableStatement来执行SQL语句,当然它执行的是存储过程. 源码如下: /** * @author Clinton Beg ...

  9. javascript之BOM事件注册和案例

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. android 屏幕保持唤醒 不锁屏 android.permission.WAKE_LOCK

     In AndroidManifest.xml 加上权限: <uses-permission android:name="android.permission.WAKE_LOCK& ...