Dark channel

#include<opencv2/opencv.hpp>
#include<vector>
using namespace cv;
using namespace std;
typedef struct{
    int row;
    int col;
}point;
int main(){
    vector<vector<point>> points(256);
    Mat image = imread("D:\\f.jpg");
    imshow("orig",image);
    Mat image_dark(image.size(),CV_8UC1);
    uchar min = 0;
    float kernelratio = 0.01;
    int reigon = 6;// max(int(image.cols*kernelratio), int(image.rows*kernelratio));
    float w = 0.95;
    float t0 = 0.1;
    float rate = 0.001;
    for (int i = 0; i < image.rows; ++i){
        uchar* pdata = image.ptr<uchar>(i);
        uchar* pdata_dark = image_dark.ptr<uchar>(i);
        for (int j = 0; j < image.cols; ++j){
            min = pdata[j*3 + 0];
            if (pdata[j*3 + 1] < min)
                min = pdata[j*3 + 1];
            if (pdata[j*3 + 2] < min)
                min = pdata[j*3 + 2];
            pdata_dark[j] = min;
        }
    }
    imshow("orig_min",image_dark);
    Mat image_dark_get(image.size(), CV_8UC1);
    for (int i = 0; i < image.rows; ++i){
        uchar* pdata_dark = image_dark_get.ptr<uchar>(i);
        for (int j = 0; j < image.cols; ++j){
            min = 255;
            for (int r_i = -reigon / 2; r_i < reigon / 2; ++r_i){
                uchar* pdata;
                int temp = i + r_i;
                if (i + r_i < 0)
                    temp = 0;
                else if (i + r_i >= image.rows)
                    temp = image.rows;
                pdata = image_dark.ptr<uchar>(temp);
                for (int r_j = -reigon / 2; r_j < reigon / 2; ++r_j){
                    int temp = j + r_j;
                    if (j + r_j < 0)
                        temp = 0;
                    else if (j + r_j >= image.cols)
                        temp = image.cols - 1;
                    if (pdata[temp] < min)
                        min = pdata[temp];
                }
            }
            pdata_dark[j] = min;
        }
    }
    imshow("dark",image_dark_get);
    point point_x_y;
    for (int i = 0; i < image_dark_get.rows; ++i){
        uchar* pdata = image_dark_get.ptr<uchar>(i);
        for (int j = 0; j < image_dark_get.cols; ++j){
            point_x_y.row = i;
            point_x_y.col = j;
            points[(int)(pdata[j])].push_back(point_x_y);
        }
    }
    int A[3] = { 0 ,0 , 0};
    int count = int(image_dark_get.cols * image_dark_get.rows * rate);
    int count_temp = 0;
    Mat image_mask(image.size(), CV_8UC1);
    int max_light = 0;
    for (int i = 255; i >= 0; --i){
        vector<point> temp;
        if (count_temp < count){
            temp = points[i];
            cout << temp.size() << " " << i << endl;
            for (int j = 0; j < temp.size(); ++j){
                uchar* pdata = image.ptr<uchar>(temp[j].row);
                if ((pdata[temp[j].col * 3] + pdata[temp[j].col * 3 + 1] + pdata[temp[j].col * 3 + 2]) > max_light){
                    max_light = (pdata[temp[j].col * 3] + pdata[temp[j].col * 3 + 1] + pdata[temp[j].col * 3 + 2]);
                    A[0] = (int)pdata[temp[j].col * 3 + 0];
                    A[1] = (int)pdata[temp[j].col * 3 + 1];
                    A[2] = (int)pdata[temp[j].col * 3 + 2];
                }
                /*if (pdata[temp[j].col*3 + 0] > A[0])
                    A[0] = (int)pdata[temp[j].col * 3 + 0];
                if (pdata[temp[j].col * 3 + 1] > A[1])
                    A[1] = (int)pdata[temp[j].col * 3 + 1];
                if (pdata[temp[j].col * 3 + 2] > A[2])
                    A[2] = (int)pdata[temp[j].col * 3 + 2];
                    */
                /*uchar* pdata_mask = image_mask.ptr<uchar>(temp[j].row);
                pdata_mask[temp[j].col] = 0;*/
            }
        }
        else
            break;
        count_temp += temp.size();
    }
    //imshow("mask",image_mask);
    //cout << A[0] << " " << A[1] << " " << A[2] << endl;
    float* t = new float[image.cols * image.rows];
    float* t_temp = new float[image.cols * image.rows];
    int idx;
    float min_f = 10000;
    for (int i = 0; i < image.rows; ++i){
        uchar* pdata = image.ptr<uchar>(i);
        for (int j = 0; j < image.cols; ++j){
            min_f = 10000;
            if (min_f > pdata[j * 3]*1.0 / A[0])
                min_f = pdata[j * 3]*1.0 / A[0];
            if (min_f > pdata[j * 3 + 1]*1.0 / A[1])
                min_f = pdata[j * 3 + 1]*1.0 / A[1];
            if (min_f > pdata[j * 3 + 2]*1.0 / A[2])
                min_f = pdata[j * 3 + 2]*1.0 / A[2];
            idx = i * image.cols + j;
            //cout << min_f << " ";
            t_temp[idx] = min_f;
        }
    }

    min_f = 1000;
    int row_temp,col_temp;
    for (int i = 0; i < image.rows; ++i){
        for (int j = 0; j < image.cols; ++j){
            min_f = 1000;
            for (int r_i = -reigon / 2; r_i < reigon / 2; ++r_i){
                for (int r_j = -reigon / 2; r_j < reigon / 2; ++r_j){
                    row_temp = i + r_i;
                    col_temp = j + r_j;
                    if (row_temp < 0) row_temp = 0;
                    else if (row_temp >= image.rows) row_temp = image.rows  - 1;
                    if (col_temp < 0) col_temp = 0;
                    else if (col_temp >= image.cols) col_temp = image.cols - 1;
                    idx = row_temp * image.cols + col_temp;
                    if (min_f > t_temp[idx])
                        min_f = t_temp[idx];
                }
            }
            idx = i * image.cols + j;
            t[idx] = 1 - 0.95 * min_f;
            if (t[idx] < t0)
                t[idx] = t0;
        }
    }
    cout << A[0] << A[1] << A[2] << endl;
    for (int i = 0; i < image.rows; ++i){
        uchar* pdata = image.ptr<uchar>(i);
        for (int j = 0; j < image.cols; ++j){
            idx = i * image.cols + j;
            //pdata[j * 3 + 0] = (uchar)((float)(pdata[j * 3 + 0] - A[0])/ t[idx] + (float)A[0]);
            //pdata[j * 3 + 1] = (uchar)((float)(pdata[j * 3 + 1] - A[1]) / t[idx] + (float)A[1]);
            if ((uchar)(((float)pdata[j * 3 + 0] - A[0]) / t[idx] + A[0]) < 0)
                pdata[j * 3 + 0] = 0;
            else if ((uchar)(((float)pdata[j * 3 + 0] - A[0]) / t[idx] + A[0]) > 255)
                pdata[j * 3 + 0] = 255;
            else pdata[j*3 + 0] = (uchar)(((float)pdata[j * 3 + 0] - A[0]) / t[idx] + A[0]);

            if ((uchar)(((float)pdata[j * 3 + 1] - A[1]) / t[idx] + A[1]) < 0)
                pdata[j * 3 + 1] = 0;
            else if ((uchar)(((float)pdata[j * 3 + 1] - A[1]) / t[idx] + A[1]) > 255)
                pdata[j * 3 + 1] = 255;
            else pdata[j * 3 + 1] = (uchar)(((float)pdata[j * 3 + 1] - A[1]) / t[idx] + A[1]);

            if ((uchar)(((float)pdata[j * 3 + 2] - A[2]) / t[idx] + A[2]) < 0)
                pdata[j * 3 + 2] = 0;
            else if ((uchar)(((float)pdata[j * 3 + 2] - A[2]) / t[idx] + A[2]) > 255)
                pdata[j * 3 + 2] = 255;
            else pdata[j * 3 + 2] = (uchar)(((float)pdata[j * 3 + 2] - A[2]) / t[idx] + A[2]);
        }
    }
    imshow("defog",image);
    waitKey(0);
    delete[] t;
    delete[] t_temp;
    return 1;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值