暗通道先验的去雾算法实现

来源:互联网 发布:域名和空间价格 编辑:程序博客网 时间:2024/04/29 10:10

目前比较公认效果较好的去雾方法的编程实现,基本原理是参考何凯明的一篇会议论文,网上已经有比较成熟的代码了。这里也就是仿写一下,这里只写到求透射率的部分,导向滤波的部分写出来有些问题就没有贴出来,机子出了点问题,先mark下等剩下的部分改完了然后在一起整理吧。参考了很多博客这里贴出来:

Single Image Haze Removal(图像去雾)-CVPR’09 Best Paper
http://blog.csdn.net/abcjennifer/article/details/6662706

暗通道优先的图像去雾算法
http://blog.csdn.net/baimafujinji/article/details/30060161

高级图像去雾算法的快速实现
http://blog.csdn.net/huixingshao/article/details/42834939

基于暗通道优先算法的去雾应用
http://www.cnblogs.com/changkaizhao/p/3266798.html

void main(){    Mat src_img;    src_img = imread("F:\\object\\vs\\fog.jpg");    if (!src_img.data)        cout << "读取图像错误";    //完成暗通道的计算    Mat dark_ch_mat;    dark_ch_mat.create(src_img.rows, src_img.cols, CV_8U);    uchar min;    for (int i = 0; i < src_img.rows; i++)        for (int j = 0; j < src_img.cols; j++)        {            min = src_img.at<cv::Vec3b>(i, j)[0];            if (src_img.at<cv::Vec3b>(i, j)[1] < min)                min = src_img.at<cv::Vec3b>(i, j)[1];            if (src_img.at<cv::Vec3b>(i, j)[2] < min)                min = src_img.at<cv::Vec3b>(i, j)[2];            dark_ch_mat.at<uchar>(i, j) = min;        }    //对暗通道图像做最小滤波器滤波    int masksize = 15;    int ilow, ihigh, jlow, jhigh;    Mat MinFilterImg;    MinFilterImg.create(dark_ch_mat.size(), dark_ch_mat.type());    for (int i = 0; i < src_img.rows; i++)        for (int j = 0; j < src_img.cols; j++)        {            min = 255;            ilow = i - masksize;            ihigh = i + masksize;            jlow = j - masksize;            jhigh = j + masksize;            if (ilow < 0)                ilow = 0;            if (ihigh >= src_img.rows)                ihigh = src_img.rows - 1;            if (jlow < 0)                jlow = 0;            if (jhigh >= src_img.cols)                jhigh = src_img.cols - 1;            for (int m = ilow; m <= ihigh; m++)                for (int n = jlow; n < jhigh; n++)                {                    if (min > dark_ch_mat.at<uchar>(m, n))                        min = dark_ch_mat.at<uchar>(m, n);                }            MinFilterImg.at<uchar>(i, j) = min;        }    //求大气光学光照Ac    int ThousDarkNumber;    ThousDarkNumber = src_img.rows*src_img.cols / 1000;    Point2i *ThousDarkPoint = new Point2i[ThousDarkNumber];    Mat AirMask;    AirMask = Mat::ones(src_img.rows, src_img.cols, CV_8U)*255;    for (int i = 0; i < ThousDarkNumber; i++)    {        minMaxLoc(dark_ch_mat, NULL, NULL, NULL, &ThousDarkPoint[i], AirMask);        //cout << ThousDarkPoint[i];        AirMask.at<uchar>(ThousDarkPoint[i])=0;    }    float sumb=0,sumg=0,sumr=0;    for (int i = 0; i < ThousDarkNumber; i++)    {        sumb += src_img.at<Vec3b>(ThousDarkPoint[i])[0];        sumg += src_img.at<Vec3b>(ThousDarkPoint[i])[1];        sumr += src_img.at<Vec3b>(ThousDarkPoint[i])[2];    }    delete[] ThousDarkPoint;    float AirEstimate[3];    AirEstimate[0] = (uchar)(sumb / ThousDarkNumber);    AirEstimate[1] = (uchar)(sumg / ThousDarkNumber);    AirEstimate[2] = (uchar)(sumr / ThousDarkNumber);    cout << AirEstimate[0] << endl << AirEstimate[1] << endl << AirEstimate[2] << endl;    //cout << "end";    //求粗透射率    Mat CrudeTransmission;    float omega;    omega = 95e-2;    float a, b, c;    src_img.copyTo(CrudeTransmission);    CrudeTransmission.convertTo(CrudeTransmission, CV_32FC3);    cout << "type" << CrudeTransmission.type() << endl;    cout << "type" << src_img.type() << endl;    /*    a = CrudeTransmission.at<Vec3f>(400, 300)[0];    b = CrudeTransmission.at<Vec3f>(400, 300)[1];    c = CrudeTransmission.at<Vec3f>(400, 300)[2];    cout << a << endl;    cout << b << endl;    cout << c << endl;    */    for (int i = 0; i < src_img.rows; i++)        for (int j = 0; j < src_img.cols; j++)        {                       CrudeTransmission.at<Vec3f>(i, j)[0] = (CrudeTransmission.at<Vec3f>(i, j)[0] / AirEstimate[0]);            CrudeTransmission.at<Vec3f>(i, j)[1] = (CrudeTransmission.at<Vec3f>(i, j)[1] / AirEstimate[1]);            CrudeTransmission.at<Vec3f>(i, j)[2] = (CrudeTransmission.at<Vec3f>(i, j)[2] / AirEstimate[2]);        }    a = CrudeTransmission.at<Vec3f>(400, 300)[0];    b = CrudeTransmission.at<Vec3f>(400, 300)[1];    c = CrudeTransmission.at<Vec3f>(400, 300)[2];    cout << a << endl;    cout << b << endl;    cout << c << endl;    Mat AirEstimateDarkCh;    float AirMin;    AirEstimateDarkCh.create(src_img.rows, src_img.cols, CV_32F);    for (int i = 0; i < src_img.rows; i++)        for (int j = 0; j < src_img.cols; j++)        {            AirMin = CrudeTransmission.at<cv::Vec3f>(i, j)[0];            if (CrudeTransmission.at<cv::Vec3f>(i, j)[1] < AirMin)                min = CrudeTransmission.at<cv::Vec3f>(i, j)[1];            if (CrudeTransmission.at<cv::Vec3f>(i, j)[2] < AirMin)                min = CrudeTransmission.at<cv::Vec3f>(i, j)[2];            AirEstimateDarkCh.at<float>(i, j) = AirMin;        }    int AirMaskSize = 15;    Mat AirMinFilterImg;    AirMinFilterImg.create(AirEstimateDarkCh.size(), CV_32F);    for (int i = 0; i < src_img.rows; i++)        for (int j = 0; j < src_img.cols; j++)        {            ilow = i - AirMaskSize;            ihigh = i + AirMaskSize;            jlow = j - AirMaskSize;            jhigh = j + AirMaskSize;            if (ilow < 0)                ilow = 0;            if (ihigh >= src_img.rows)                ihigh = src_img.rows - 1;            if (jlow < 0)                jlow = 0;            if (jhigh >= src_img.cols)                jhigh = src_img.cols - 1;            AirMin = AirEstimateDarkCh.at<float>(ilow, jlow);            for (int m = ilow; m <= ihigh; m++)                for (int n = jlow; n < jhigh; n++)                {                    if (AirMin > AirEstimateDarkCh.at<float>(m, n))                        AirMin = AirEstimateDarkCh.at<float>(m, n);                }            AirMinFilterImg.at<float>(i, j) = (1 - omega* AirMin)*255;        }    a = AirMinFilterImg.at<float>(200, 300);    cout << a << endl;
1 0
原创粉丝点击