The recent "Digital Image processing" class needs to do the work of image fog, and then we Baidu a bit, find the following links (the Main method has image enhancement and image restoration two major categories):
Http://www.cspmag.cn/jscx/spjk/201406/1336.html
In the end, my teammates and I chose to use the Dark Channel prior method, we refer to the following code:
Http://blog.sina.com.cn/s/blog_4d8730df0100m8lz.html
The code above is an implementation of Dr He Chaiming's single Image Haze removal using Dark Channel Prior, but without the soft matting, there are some discrepancies between the minimum filter and the "a", and we ran directly The general effect is OK, but the style of the code is OpenCV1.0 style, using the iplimage, we decided to change it to OpenCV2.0 style code, we modify the code as follows, the specific ideas have not changed:
The environment we use is vs2013+opencv3.1
--------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------- ---------
#include <iostream>
#include <opencv2\opencv.hpp>
using namespace Std;
using namespace CV;
String tbarname1 = "Block:";
Defines two slider bars for adjusting parameters
String tbarname2 = "W:";
W is to keep part of the fog
int block = 5;
int w1 = 95;
Double w = (double) w1/100;
Mat src;
Mat DST;
Define the fog function as follows
Mat haze_removal (Mat src, int block, double W)
{
Images have three color channels, respectively
VECTOR<CV::MAT>DST (Src.channels ());
Mat imgROI1;
ROI of Dst[0]
Mat imgROI2;
ROI of Dst[1]
Mat imgROI3;
ROI of Dst[2]
Mat Darkroi;
ROI of Dark Channel
Mat Darkchannel;
Dark Primary color transcendental
Mat imgtransmissivity;
Transmission rate
Three channels after the fog algorithm operation
Mat RemovalDst1;
Mat RemovalDst2;
Mat RemovalDst3;
To the image after the fog, three channels merged into
Mat Dst3d;
Source image ROI Location and size
Rect Roi_rect;
Allocating memory for each ROI
imgROI1 = Mat (blocks, blocks, CV_8UC1);
imgROI2 = Mat (blocks, blocks, CV_8UC1);
ImgROI3 = Mat (blocks, blocks, CV_8UC1);
Darkroi = Mat (blocks, blocks, CV_8UC1);
Allocate size for RemovalDst1 removalDst2 removalDst3
RemovalDst1 = Mat (Src.rows, Src.cols, CV_8UC1);
RemovalDst2 = Mat (Src.rows, Src.cols, CV_8UC1);
RemovalDst3 = Mat (Src.rows, Src.cols, CV_8UC1);
For dark primary color prior allocation size
Darkchannel = Mat (Src.rows, Src.cols, CV_8UC1);
Allocate size for transmission rate
imgtransmissivity = Mat (Src.rows, Src.cols, CV_8UC1);
Dst3d Allocation size
Dst3d = Mat (Src.rows, Src.cols, CV_8UC3);
Separate the original color image into three channels
Split (SRC, DST);
Seek Dark Primary Colors
Roi_rect.width = Block;
Roi_rect.height = Block;
roi_rect.x = 0;
Roi_rect.y = 0;
int i;
Int J;
Double min1 = 0;
Double max1 = 0;
Double min2 = 0;
Double max2 = 0;
Double min3 = 0;
Double max3 = 0;
Double min = 0;
for (i = 0; i<src.cols/block; i++)
{
for (j = 0; j<src.rows/block; j + +)
{
Calculates the minimum ROI in three channels, respectively
ImgROI1 = dst[0] (roi_rect);
Minmaxidx (imgROI1, &min1, &MAX1);
ImgROI2 = dst[1] (roi_rect);
Minmaxidx (imgROI2, &min2, &MAX2);
ImgROI3 = dst[2] (roi_rect);
Minmaxidx (ImgROI3, &min3, &max3);
Find the minimum value for the minimum value in three channels
if (min1<min2)
min = min1;
Else
min = min2;
if (min>min3)
Min = min3;//min for this ROI in dark primary colors
Min gives the corresponding ROI in Darkchannel
Darkroi = Darkchannel (Roi_rect);
Mat tmp = Mat (blocks, blocks, CV_8UC1, Scalar (min));
Tmp.copyto (Darkroi);
Transfer to next ROI
Roi_rect.x = Block*i;
Roi_rect.y = Block*j;
}
}
Preserving a priori image of the dark color
Imwrite ("F:\\my_desktop\\haze_removal\\darkchannel.jpg", Darkchannel);
Using the obtained dark primary color transcendental dark_channel_prior.jpg to seek the atmospheric light intensity
Double MindArk;
Double Maxdark;
int minloc[2] = {255, 255};
int maxloc[2] = {255, 255};//maxloc is the original coordinates of the lightest of the darker primaries
Minmaxidx (Darkchannel, &mindark, &maxdark, Minloc, Maxloc);
cout << maxloc[1] << "" << maxloc[0] << Endl;
Roi_rect.x = maxloc[1];
Roi_rect.y = maxloc[0];
Double dst1a;//defines the estimated value of atmospheric light composition
Double MinDst1;
Double DST2A;
Double MinDst2;
Double dst3a;
Double minDst3;
Estimating the intensity of atmospheric light according to the method of paper
ImgROI1 = dst[0] (roi_rect);
Minmaxidx (imgROI1, &mindst1, &DST1A);
ImgROI2 = dst[1] (roi_rect);
Minmaxidx (imgROI2, &mindst2, &DST2A);
ImgROI3 = dst[2] (roi_rect);
Minmaxidx (ImgROI3, &mindst3, &dst3a);
cout << dst1a << "" << dst2a << "" << dst3a << endl;//These three values are atmospheric light intensity estimates
To find the transmission rate
int k;
int l;
Uchar m;
Uchar n;//The value of the prior elements of dark primaries
for (k = 0; k<src.rows; k++)
{
for (l = 0; l<src.cols; l++)
{
m = darkchannel.at<uchar> (k, L);
n = 255-w * m;
W purpose is to keep part of the fog so that the image looks real
Imgtransmissivity.at<uchar> (k, l) = n;
}
}
Imwrite ("F:\\my_desktop\\haze_removal\\imgtransmissivity.jpg", imgtransmissivity);
To find a fog-free image
int p, q;
Double TX;
Uchar SRCB, SRCG, SRCR;
Cvscalar IX, JX;
for (p = 0; p<src.rows; p++)
{
for (q = 0; q<src.cols; q++)
{
tx = Imgtransmissivity.at<uchar> (p, q);
tx = tx/255;
if (tx<0.1)
tx = 0.1;
SRCB = (src.at<vec3b> (p, Q) [0]-DST1A)/TX + dst1a;//A model operation based on fog to restore a fog-free image
SRCG = (src.at<vec3b> (p, q) [1]-DST2A)/TX + DST2A;
SRCR = (src.at<vec3b> (p, Q) [2]-dst3a)/TX + dst3a;
Dst3d.at<vec3b> (P, Q) [0] = SRCB;
Dst3d.at<vec3b> (P, q) [1] = SRCG;
Dst3d.at<vec3b> (P, Q) [2] = SRCR;
}
}
Imwrite ("F:\\my_desktop\\haze_removal\\removed_haze.jpg", Dst3d);
return Dst3d;
}
void on_trackbar1 (int h,void *pt)
{
DST = Haze_removal (SRC, block, W);
Imshow ("Destination image", DST);
}
void on_trackbar2 (int h,void *pt)
{
W = (double) w1/100;
DST = Haze_removal (SRC, block, W);
Imshow ("Destination image", DST);
}
The main function is as follows
void Main ()
{
Open image
src = imread ("f:\\my_desktop\\haze_removal\\wu-035.jpg");
Create window
Namedwindow ("Foggy Image", cv_window_autosize);
Imshow ("Foggy image", SRC);
Namedwindow ("Destination image", cv_window_autosize);
Createtrackbar (tbarname1, "Destination image", &block, ON_TRACKBAR1);
Createtrackbar (tbarname2, "Destination image", &W1, ON_TRACKBAR2);
Waitkey (0);
}