1
+ #include " opencv2/opencv.hpp"
2
+ #include " iostream"
3
+ #include " algorithm"
4
+ #include " vector"
5
+ #include " stdio.h"
6
+ using namespace std ;
7
+ using namespace cv ;
8
+
9
+ void separateGaussianFilter (const Mat &src, Mat &dst, int ksize, double sigma){
10
+ CV_Assert (src.channels ()==1 || src.channels () == 3 ); // 只处理单通道或者三通道图像
11
+ // 生成一维的
12
+ double *matrix = new double [ksize];
13
+ double sum = 0 ;
14
+ int origin = ksize / 2 ;
15
+ for (int i = 0 ; i < ksize; i++){
16
+ double g = exp (-(i-origin) * (i-origin) / (2 * sigma * sigma));
17
+ sum += g;
18
+ matrix[i] = g;
19
+ }
20
+ for (int i = 0 ; i < ksize; i++) matrix[i] /= sum;
21
+ int border = ksize / 2 ;
22
+ copyMakeBorder (src, dst, border, border, border, border, BORDER_CONSTANT);
23
+ int channels = dst.channels ();
24
+ int rows = dst.rows - border;
25
+ int cols = dst.cols - border;
26
+ // 水平方向
27
+ for (int i = border; i < rows; i++){
28
+ for (int j = border; j < cols; j++){
29
+ double sum[3 ] = {0 };
30
+ for (int k = -border; k<=border; k++){
31
+ if (channels == 1 ){
32
+ sum[0 ] += matrix[border + k] * dst.at <uchar>(i, j+k);
33
+ }else if (channels == 3 ){
34
+ Vec3b rgb = dst.at <Vec3b>(i, j+k);
35
+ sum[0 ] += matrix[border+k] * rgb[0 ];
36
+ sum[1 ] += matrix[border+k] * rgb[1 ];
37
+ sum[2 ] += matrix[border+k] * rgb[2 ];
38
+ }
39
+ }
40
+ for (int k = 0 ; k < channels; k++){
41
+ if (sum[k] < 0 ) sum[k] = 0 ;
42
+ else if (sum[k] > 255 ) sum[k] = 255 ;
43
+ }
44
+ if (channels == 1 )
45
+ dst.at <Vec3b>(i, j) = static_cast <uchar>(sum[0 ]);
46
+ else if (channels == 3 ){
47
+ Vec3b rgb = {static_cast <uchar>(sum[0 ]), static_cast <uchar>(sum[1 ]), static_cast <uchar>(sum[2 ])};
48
+ dst.at <Vec3b>(i, j) = rgb;
49
+ }
50
+ }
51
+ }
52
+ // 竖直方向
53
+ for (int i = border; i < rows; i++){
54
+ for (int j = border; j < cols; j++){
55
+ double sum[3 ] = {0 };
56
+ for (int k = -border; k<=border; k++){
57
+ if (channels == 1 ){
58
+ sum[0 ] += matrix[border + k] * dst.at <uchar>(i+k, j);
59
+ }else if (channels == 3 ){
60
+ Vec3b rgb = dst.at <Vec3b>(i+k, j);
61
+ sum[0 ] += matrix[border+k] * rgb[0 ];
62
+ sum[1 ] += matrix[border+k] * rgb[1 ];
63
+ sum[2 ] += matrix[border+k] * rgb[2 ];
64
+ }
65
+ }
66
+ for (int k = 0 ; k < channels; k++){
67
+ if (sum[k] < 0 ) sum[k] = 0 ;
68
+ else if (sum[k] > 255 ) sum[k] = 255 ;
69
+ }
70
+ if (channels == 1 )
71
+ dst.at <Vec3b>(i, j) = static_cast <uchar>(sum[0 ]);
72
+ else if (channels == 3 ){
73
+ Vec3b rgb = {static_cast <uchar>(sum[0 ]), static_cast <uchar>(sum[1 ]), static_cast <uchar>(sum[2 ])};
74
+ dst.at <Vec3b>(i, j) = rgb;
75
+ }
76
+ }
77
+ }
78
+ delete [] matrix;
79
+ }
80
+
81
+ Mat MultiScaleDetailBoosting (Mat src, int Radius){
82
+ int rows = src.rows ;
83
+ int cols = src.cols ;
84
+ Mat B1, B2, B3;
85
+ separateGaussianFilter (src, B1, Radius, 1.0 );
86
+ separateGaussianFilter (src, B2, Radius*2 -1 , 2.0 );
87
+ separateGaussianFilter (src, B3, Radius*4 -1 , 4.0 );
88
+ float w1 = 0.5 , w2 = 0.5 , w3 = 0.25 ;
89
+ Mat dst (rows, cols, CV_8UC3);
90
+ for (int i = 0 ; i < rows; i++){
91
+ for (int j = 0 ; j < cols; j++){
92
+ for (int k = 0 ; k < 3 ; k++){
93
+ int D1 = src.at <Vec3b>(i, j)[k] - B1.at <Vec3b>(i, j)[k];
94
+ int D2 = B1.at <Vec3b>(i, j)[k] - B2.at <Vec3b>(i, j)[k];
95
+ int D3 = B2.at <Vec3b>(i, j)[k] - B3.at <Vec3b>(i, j)[k];
96
+ int sign = D1 > 0 ? 1 : -1 ;
97
+ dst.at <Vec3b>(i, j)[k] = saturate_cast<uchar>((1 - w1*sign) * D1 - w2 * D2 + w3 * D3 + src.at <Vec3b>(i, j)[k]);
98
+ }
99
+ }
100
+ }
101
+ return dst;
102
+ }
103
+
104
+ int main (){
105
+ Mat src = imread (" ../tmp.png" );
106
+ Mat dst = MultiScaleDetailBoosting (src, 5 );
107
+ imshow (" origin" , src);
108
+ imshow (" result" , dst);
109
+ waitKey (0 );
110
+ imwrite (" ../result.jpg" , dst);
111
+ return 0 ;
112
+ }
0 commit comments