-
Notifications
You must be signed in to change notification settings - Fork 185
/
DarkChannelPriorDehaze.java
executable file
·74 lines (68 loc) · 2.5 KB
/
DarkChannelPriorDehaze.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package com.isaac.models;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.isaac.utils.Filters;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
public class DarkChannelPriorDehaze {
public static Mat enhance(Mat image, double krnlRatio, double minAtmosLight, double eps) {
image.convertTo(image, CvType.CV_32F);
// extract each color channel
List<Mat> rgb = new ArrayList<>();
Core.split(image, rgb);
Mat rChannel = rgb.get(0);
Mat gChannel = rgb.get(1);
Mat bChannel = rgb.get(2);
int rows = rChannel.rows();
int cols = rChannel.cols();
// derive the dark channel from original image
Mat dc = rChannel.clone();
for (int i = 0; i < image.rows(); i++) {
for (int j = 0; j < image.cols(); j++) {
double min = Math.min(rChannel.get(i, j)[0], Math.min(gChannel.get(i, j)[0], bChannel.get(i, j)[0]));
dc.put(i, j, min);
}
}
// minimum filter
int krnlSz = Double.valueOf(Math.max(Math.max(rows * krnlRatio, cols * krnlRatio), 3.0)).intValue();
Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(krnlSz, krnlSz), new Point(-1, -1));
Imgproc.erode(dc, dc, kernel);
// get coarse transmission map
Mat t = dc.clone();
Core.subtract(t, new Scalar(255.0), t);
Core.multiply(t, new Scalar(-1.0), t);
Core.divide(t, new Scalar(255.0), t);
// obtain gray scale image
Mat gray = new Mat();
Imgproc.cvtColor(image, gray, Imgproc.COLOR_RGB2GRAY);
Core.divide(gray, new Scalar(255.0), gray);
// refine transmission map
int r = krnlSz * 4;
t = Filters.GuidedImageFilter(gray, t, r, eps);
// get minimum atmospheric light
minAtmosLight = Math.min(minAtmosLight, Core.minMaxLoc(dc).maxVal);
// dehaze each color channel
rChannel = dehaze(rChannel, t, minAtmosLight);
gChannel = dehaze(gChannel, t, minAtmosLight);
bChannel = dehaze(bChannel, t, minAtmosLight);
// merge three color channels to a image
Mat outval = new Mat();
Core.merge(new ArrayList<>(Arrays.asList(rChannel, gChannel, bChannel)), outval);
outval.convertTo(outval, CvType.CV_8UC1);
return outval;
}
private static Mat dehaze(Mat channel, Mat t, double minAtmosLight) {
Mat t_ = new Mat();
Core.subtract(t, new Scalar(1.0), t_);
Core.multiply(t_, new Scalar(-1.0 * minAtmosLight), t_);
Core.subtract(channel, t_, channel);
Core.divide(channel, t, channel);
return channel;
}
}