#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;
}
Dark channel
最新推荐文章于 2023-03-12 00:47:29 发布