http://blog.sina.com.cn/s/blog_4ca086fc0100jn6u.html根据 何凯明的论文实现 中间还没有使用soft matting(这个还没弄清楚),不过有点效果,效果不太好,先记一下,弄清楚以后再来编辑
// DarkChannelPiror.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
#include "cvaux.h"
#include "math.h"
#ifdef _DEBUG
#pragma comment(lib,"cv200d.lib")
#pragma comment(lib,"cvaux200d.lib")
#pragma comment(lib,"cxcore200d.lib")
#pragma comment(lib,"highgui200d.lib")
#else
#pragma comment(lib,"cv200.lib")
#pragma comment(lib,"cvaux200.lib")
#pragma comment(lib,"cxcore200.lib")
#pragma comment(lib,"highgui200.lib")
#endif
#define BLOCK_SIZE 15
int _tmain(int argc, _TCHAR* argv[])
{
IplImage* src;
IplImage* darkimage;
IplImage* darkchannelimage;
IplImage* newimage;
src = cvLoadImage("201062083849954.jpg");
cvNamedWindow( "原图", 1 );
cvMoveWindow("原图", 0, 0);
cvNamedWindow( "min RGB", 1 );
cvMoveWindow("min RGB", 500, 0);
cvNamedWindow( "Dark Channel图像", 1 );
cvMoveWindow("Dark Channel图像", 0,400);
cvNamedWindow( "去雾后", 1 );
cvMoveWindow("去雾后", 500, 400);
int A = 215; //大气光强度值
float omega = 0.9;
darkchannelimage = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
darkimage = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
newimage = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 3);
uchar * channelptr = (uchar *)darkchannelimage->imageData;
uchar * ptr = (uchar *)darkimage->imageData;
uchar * sptr = (uchar *)src->imageData;
uchar * newptr = (uchar *)newimage->imageData;
memset(channelptr,255,darkchannelimage->width*darkchannelimage->height);
//计算dark rgb图像
for(int i=0;i<src->height;i++)
{
for(int j=0;j<src->width;j++)
{
int c = 0;
if(sptr[i*src->widthStep+3*j]>sptr[i*src->widthStep+3*j+1])
{
c = sptr[i*src->widthStep+3*j+1];
}
else
{
c = sptr[i*src->widthStep+3*j];
}
if(c>sptr[i*src->widthStep+3*j+2])
{
c = sptr[i*src->widthStep+3*j+2];
}
ptr[i*darkimage->widthStep+j]=c;
}
}
//计算dark channel图像
int offset = BLOCK_SIZE/2;
int ltx=0;
int lty=0; //左上
int rbx=0;
int rby=0; //右下
for(int i=0;i<darkimage->height;i++)
{
for(int j=0;j<darkimage->width;j++)
{
ltx = j-offset>0?j-offset:0;
lty = i-offset>0?i-offset:0;
rbx = j+offset<darkimage->width-1?j+offset:darkimage->width-1;
rby = i+offset<darkimage->height-1?i+offset:darkimage->height-1;
for(int m=lty;m<=rby;m++)
{
for(int n=ltx;n<=rbx;n++)
{
if(ptr[i*darkimage->widthStep+j]<channelptr[m*darkimage->widthStep+n])
{
channelptr[m*darkimage->widthStep+n]=ptr[i*darkimage->widthStep+j];
}
}
}
}
}
for(int i=0;i<newimage->height;i++)
{
for(int j=0;j<newimage->width;j++)
{
float tran = 0.0;
tran = 1-omega*channelptr[i*darkimage->widthStep+j]/A;
if(tran<0.1)
{
tran = 0.1;
}
newptr[i*newimage->widthStep+3*j] = (sptr[i*src->widthStep+3*j]-A)/tran+A;
newptr[i*newimage->widthStep+3*j+1] = (sptr[i*src->widthStep+3*j+1]-A)/tran+A;
newptr[i*newimage->widthStep+3*j+2] = (sptr[i*src->widthStep+3*j+2]-A)/tran+A;
}
}
cvShowImage("原图",src);
cvShowImage("min RGB",darkimage);
cvShowImage("Dark Channel图像",darkchannelimage);
cvShowImage("去雾后",newimage);
//cvSaveImage("1.jpg",newimage);
cvWaitKey(-1);
return 0;
}