1- #include < stdio.h>
2- #include < iostream>
3- #include < immintrin.h>
4- #include < opencv2/opencv.hpp>
5- using namespace cv ;
6- using namespace std ;
7-
81// 计算中值
92int getMediaValue (const int hist[], int thresh) {
103 int sum = 0 ;
@@ -17,7 +10,6 @@ int getMediaValue(const int hist[], int thresh) {
1710 return 255 ;
1811}
1912// 快速中值滤波,灰度图
20- // https://www.cnblogs.com/liulijin/p/9038230.html
2113Mat fastMedianBlur (Mat src, int diameter) {
2214 int row = src.rows ;
2315 int col = src.cols ;
@@ -31,6 +23,47 @@ Mat fastMedianBlur(Mat src, int diameter) {
3123 int right = col - radius;
3224 int bot = row - radius;
3325 for (int j = radius; j < bot; j++) {
34-
26+ for (int i = radius; i < right; i++) {
27+ // 每一行第一个待滤波元素建立直方图
28+ if (i == radius) {
29+ memset (Hist, 0 , sizeof (Hist));
30+ for (int y = j - radius; y <= min (j + radius, row); y++) {
31+ for (int x = i - radius; x <= min (i + radius, col); x++) {
32+ uchar val = srcData[y * col + x];
33+ Hist[val]++;
34+ }
35+ }
36+ }
37+ else {
38+ int L = i - radius - 1 ;
39+ int R = i + radius;
40+ for (int y = j - radius; y <= min (j + radius, row); y++) {
41+ // 更新左边一列
42+ Hist[srcData[y * col + L]]--;
43+ // 更新右边一列
44+ Hist[srcData[y * col + R]]++;
45+ }
46+ }
47+ uchar medianVal = getMediaValue (Hist, threshold);
48+ dstData[j * col + i] = medianVal;
49+ }
50+ }
51+ // 边界直接赋值
52+ for (int i = 0 ; i < col; i++) {
53+ for (int j = 0 ; j < radius; j++) {
54+ int id1 = j * col + i;
55+ int id2 = (row - j - 1 ) * col + i;
56+ dstData[id1] = srcData[id1];
57+ dstData[id2] = srcData[id2];
58+ }
59+ }
60+ for (int i = radius; i < row - radius - 1 ; i++) {
61+ for (int j = 0 ; j < radius; j++) {
62+ int id1 = i * col + j;
63+ int id2 = i * col + col - j - 1 ;
64+ dstData[id1] = srcData[id1];
65+ dstData[id2] = srcData[id2];
66+ }
3567 }
68+ return dst;
3669}
0 commit comments