| 12
 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
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 
 | #include "opencv2/opencv.hpp"#include <iostream>
 
 using namespace cv;
 using namespace std;
 
 #define CLAMP(x, a, b) (MAX(a, MIN(x, b)))
 
 void flat_gradient_cpu(Mat &src, Mat &dst, const float flatGradientThresh, bool ones = false) {
 int width  = src.cols;
 int height = src.rows;
 int one    = (ones) ? 1 : 0;
 
 float *data_src = (float *) src.data;
 float *data_dst = (float *) dst.data;
 
 for (int i = 0; i < height; i++) {
 for (int j = 0; j < width; j++) {
 
 int x   = j;
 int y   = i;
 int pos = y * width + x;
 
 data_dst[pos] = 1.0f;
 if (0 == x || 0 == y || (width - 1) == x || (height - 1) == y) {
 continue;
 }
 
 float lrGrad   = (fabs(data_src[pos + 1] - data_src[pos - 1]));
 float tbGrad   = (fabs(data_src[(y + 1) * width + x] - data_src[(y - 1) * width + x]));
 float trblGrad = (fabs(data_src[(y - 1) * width + x + 1] - data_src[(y + 1) * width + x - 1]));
 float tlbrGrad = (fabs(data_src[(y - 1) * width + x - 1] - data_src[(y + 1) * width + x + 1]));
 
 float minGradClip = (min(tbGrad, min(trblGrad, tlbrGrad)));
 float minGrad     = (min(lrGrad, minGradClip));
 
 if (minGrad > flatGradientThresh) {
 float invGrad = 1.0f / (minGrad - flatGradientThresh);
 data_dst[pos] = CLAMP(invGrad, 0.0f, 1.0f);
 }
 }
 }
 }
 
 void flat_3dark_thresh(Mat &src, Mat &src2, Mat &src3, Mat &net, const float dark_thresh) {
 
 int width  = src.cols;
 int height = src.rows;
 
 float *data_src  = (float *) src.data;
 float *data_src2 = (float *) src2.data;
 float *data_src3 = (float *) src3.data;
 float *data_Net  = (float *) net.data;
 
 for (int i = 0; i < height; i++) {
 for (int j = 0; j < width; j++) {
 int pos = i * width + j;
 
 float elem1 = (1.0f - data_src[pos]);
 float elem2 = (1.0f - data_src2[pos]);
 float elem3 = (1.0f - data_src3[pos]);
 
 elem1 = (elem1 + elem2 + elem3);
 elem1 = 1.0f - (CLAMP(elem1, 0.0f, 1.0f));
 
 data_src[pos] = (data_Net[pos] < dark_thresh) ? 1.0f : elem1;
 }
 }
 }
 
 void flat_denoise_mask(Mat &netDst, Mat &flat_mask) {
 
 float flat_grad_thresh = 0.5;
 
 Mat netDownX2  = Mat(netDst.size() / 2, netDst.type());
 Mat maskDownX2 = Mat(flat_mask.size() / 2, flat_mask.type());
 Mat netDownX4  = Mat(netDownX2.size() / 2, netDownX2.type());
 Mat maskDownX4 = Mat(maskDownX2.size() / 2, maskDownX2.type());
 
 Mat flatMaskUpBy2 = Mat(flat_mask.size(), flat_mask.type());
 Mat flatMaskUpBy4 = Mat(flat_mask.size(), flat_mask.type());
 
 flat_gradient_cpu(netDst, flat_mask, flat_grad_thresh, true);
 resize(netDst, netDownX2, netDownX2.size(), 0, 0, INTER_NEAREST);
 flat_gradient_cpu(netDownX2, maskDownX2, flat_grad_thresh, true);
 resize(netDownX2, netDownX4, netDownX4.size(), 0, 0, INTER_NEAREST);
 flat_gradient_cpu(netDownX4, maskDownX4, flat_grad_thresh, true);
 resize(maskDownX2, flatMaskUpBy2, flatMaskUpBy2.size(), 0, 0, INTER_NEAREST);
 resize(maskDownX4, flatMaskUpBy4, flatMaskUpBy4.size(), 0, 0, INTER_NEAREST);
 flat_3dark_thresh(flat_mask, flatMaskUpBy2, flatMaskUpBy4, netDst, flat_grad_thresh);
 }
 
 int main() {
 Mat img = imread("/Users/huziliang/Documents/C++/funny/flat_area.png", IMREAD_GRAYSCALE);
 Mat img_f, dst_f;
 img.convertTo(img_f, CV_32FC1);
 boxFilter(img_f, img_f, -1, Size(3, 3));
 dst_f = Mat::zeros(img_f.size(), img_f.type());
 flat_denoise_mask(img_f, dst_f);
 imwrite("/Users/huziliang/Documents/C++/funny/flat_area_result.png", dst_f * 255.0f);
 }
 
 |