• 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 <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;
            }
        }
    
    }
    
    


    原图


    效果图


  • 相关阅读:
    python编程学习进度七
    python编程学习进度六
    SOA——2020.5.15
    代码大全001/
    Refined Architecture阶段——细化架构
    架构即未来003(摘自网络)
    我对外包公司的小小看法
    架构即未来002
    每日日报
    架构即未来阅读笔记001
  • 原文地址:https://www.cnblogs.com/muyuge/p/6152360.html
Copyright © 2020-2023  润新知