I’ll try to implement your solution, and I guess the algo was written by developer himself.
Here’s complete source code.
int dehaze(Mat& image, Mat& result, double twBlue = 0.5, double twGreen = 0.5, double twRed = 0.1) {
// MinMax function input placeholders
double minVal;
double maxVal;
Point minLoc;
Point maxLoc;
// Image size placeholders
int W;
int H;
// tresholding/rounding/clipping loop placeholders
double valueBlue;
double valueGreen;
double valueRed;
// intemediate array structure placehodlders
Mat blurredImage;
Mat A;
Mat t;
Mat dehazed;
Mat dehazedSplit[3];
Mat ABGR[3];
Mat tBGR[3];
Mat imageBGR[3];
Mat blurredImageBGR[3];
// Normalize, blur image and extract dimensions
W = image.cols;
H = image.rows;
image.convertTo(image, CV_64FC3);
image = image / Scalar(255, 255, 255);
GaussianBlur(image, blurredImage, Size(41, 41), 30, 30);
split(blurredImage, blurredImageBGR);
// Estimate the A matrix
A = Mat(H, W, CV_64FC3, Scalar(1, 1, 1));
split(A, ABGR);
minMaxLoc(blurredImageBGR[0], &minVal, &maxVal, &minLoc, &maxLoc);
ABGR[0] = Scalar(maxVal);
minMaxLoc(blurredImageBGR[1], &minVal, &maxVal, &minLoc, &maxLoc);
ABGR[1] = Scalar(maxVal);
minMaxLoc(blurredImageBGR[2], &minVal, &maxVal, &minLoc, &maxLoc);
ABGR[2] = Scalar(maxVal);
// Estimate the t matrix
t = Mat(H, W, CV_64FC3, Scalar(0, 0, 0));
split(t, tBGR);
tBGR[0] = (Scalar(1) - blurredImageBGR[0].mul(Scalar(twBlue)) / ABGR[0]);
tBGR[1] = (Scalar(1) - blurredImageBGR[1].mul(Scalar(twGreen)) / ABGR[1]);
tBGR[2] = (Scalar(1) - blurredImageBGR[2].mul(Scalar(twRed)) / ABGR[2]);
merge(tBGR, 3, t);
merge(ABGR, 3, A);
t.setTo(0.1, t < 0);
// Estimate deahazed image
dehazed = (image - A) / t + A;
dehazed = dehazed.mul(Scalar(255, 255, 255));
split(dehazed, dehazedSplit);
split(image, imageBGR);
// Clip and normalize image values
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
valueBlue = abs(dehazedSplit[0].at<double>(i, j));
valueGreen = abs(dehazedSplit[1].at<double>(i, j));
valueRed = abs(dehazedSplit[2].at<double>(i, j));
if (valueBlue > 255)
valueBlue = 255;
if (valueGreen > 255)
valueGreen = 255;
if (valueRed > 255)
valueRed = 255;
dehazedSplit[0].at<double>(i, j) = round(valueBlue);
dehazedSplit[1].at<double>(i, j) = round(valueGreen);
dehazedSplit[2].at<double>(i, j) = round(valueRed);
}
}
merge(dehazedSplit, 3, dehazed);
dehazed.convertTo(dehazed, CV_8UC3);
result = dehazed;
return 0;
}