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 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); }
|