OpenCV——去雾


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

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

// define head function
#ifndef PS_ALGORITHM_H_INCLUDED
#define PS_ALGORITHM_H_INCLUDED

#include 
#include 
#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."<(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(0, Index);

    float value=0;
    float Temp_value;
    float r_temp, g_temp, b_temp;

    for(int i=0; i(i,j);
            if(Temp_value>T_value)
            {
                r_temp=Img.at(i,j)[0];
                g_temp=Img.at(i,j)[1];
                b_temp=Img.at(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(i,j));
            dst.at(i,j)[0]=(src.at(i,j)[0]-A)/value+A;
            dst.at(i,j)[1]=(src.at(i,j)[1]-A)/value+A;
            dst.at(i,j)[2]=(src.at(i,j)[2]-A)/value+A;
        }
    }

}

原图


效果图