|
| 1 | +#include <stdio.h> |
| 2 | +#include <iostream> |
| 3 | +#include <immintrin.h> |
| 4 | +#include <opencv2/opencv.hpp> |
| 5 | +using namespace cv; |
| 6 | +using namespace std; |
1 | 7 | //针对灰度图的均值滤波+CVPR 2019的SideWindowFilter |
2 | 8 | //其他种类的滤波直接换核即可 |
3 | 9 |
|
| 10 | +int cnt[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
| 11 | +vector <int> filter[8]; |
| 12 | + |
| 13 | +void InitFilter(int radius) { |
| 14 | + int n = radius * 2 + 1; |
| 15 | + for (int i = 0; i < 8; i++) { |
| 16 | + cnt[i] = 0; |
| 17 | + filter[i].clear(); |
| 18 | + } |
| 19 | + for (int i = 0; i < 8; i++) { |
| 20 | + for (int x = 0; x < n; x++) { |
| 21 | + for (int y = 0; y < n; y++) { |
| 22 | + if (i == 0 && x <= radius && y <= radius) { |
| 23 | + filter[i].push_back(1); |
| 24 | + } |
| 25 | + else if (i == 1 && x <= radius && y >= radius) { |
| 26 | + filter[i].push_back(1); |
| 27 | + } |
| 28 | + else if (i == 2 && x >= radius && y <= radius) { |
| 29 | + filter[i].push_back(1); |
| 30 | + } |
| 31 | + else if (i == 3 && x >= radius && y >= radius) { |
| 32 | + filter[i].push_back(1); |
| 33 | + } |
| 34 | + else if (i == 4 && x <= radius) { |
| 35 | + filter[i].push_back(1); |
| 36 | + } |
| 37 | + else if (i == 5 && x >= radius) { |
| 38 | + filter[i].push_back(1); |
| 39 | + } |
| 40 | + else if (i == 6 && y >= radius) { |
| 41 | + filter[i].push_back(1); |
| 42 | + } |
| 43 | + else if (i == 7 && y <= radius) { |
| 44 | + filter[i].push_back(1); |
| 45 | + } |
| 46 | + else { |
| 47 | + filter[i].push_back(0); |
| 48 | + } |
| 49 | + } |
| 50 | + } |
| 51 | + } |
| 52 | + for (int i = 0; i < 8; i++) { |
| 53 | + int sum = 0; |
| 54 | + for (int j = 0; j < filter[i].size(); j++) sum += filter[i][j] == 1; |
| 55 | + cnt[i] = sum; |
| 56 | + } |
| 57 | +} |
| 58 | + |
4 | 59 | Mat SideWindowFilter(Mat src, int radius = 1) { |
5 | 60 | int row = src.rows; |
6 | 61 | int col = src.cols; |
7 | | - int cnt[8] = { 4, 4, 4, 4, 6, 6, 6, 6 }; |
8 | | - //3*3 的模板,如果半径不为1,那么需要修改 |
9 | | - int filter[8][9] = { { 1, 1, 0, 1, 1, 0, 0, 0, 0 }, |
10 | | - { 0, 1, 1, 0, 1, 1, 0, 0, 0 }, |
11 | | - { 0 ,0, 0, 1, 1, 0, 1, 1, 0 }, |
12 | | - { 0, 0, 0, 0, 1, 1, 0, 1, 1 }, |
13 | | - { 1, 1, 1, 1, 1, 1, 0, 0, 0 }, |
14 | | - { 0, 0, 0, 1, 1, 1, 1, 1, 1 }, |
15 | | - { 0, 1, 1, 0, 1, 1, 0, 1, 1 }, |
16 | | - { 1, 1, 0, 1, 1, 0, 1, 1, 0 } }; |
17 | | - Mat dst(row, col, CV_8UC1); |
18 | | - for (int i = 0; i < row; i++) { |
19 | | - for (int j = 0; j < col; j++) { |
20 | | - if (i < radius || i + radius >= row || j < radius || j + radius >= col) { |
21 | | - dst.at<uchar>(i, j) = src.at<uchar>(i, j); |
22 | | - continue; |
23 | | - } |
24 | | - int minn = 256; |
25 | | - int pos = 0; |
26 | | - for (int k = 0; k < 8; k++) { |
| 62 | + int channels = src.channels(); |
| 63 | + InitFilter(radius); |
| 64 | + for (int i = 0; i < 8; i++) { |
| 65 | + printf("%d ", cnt[i]); |
| 66 | + } |
| 67 | + printf("\n"); |
| 68 | + if (channels == 1) { |
| 69 | + Mat dst(row, col, CV_8UC1); |
| 70 | + for (int i = 0; i < row; i++) { |
| 71 | + for (int j = 0; j < col; j++) { |
| 72 | + if (i < radius || i + radius >= row || j < radius || j + radius >= col) { |
| 73 | + dst.at<uchar>(i, j) = src.at<uchar>(i, j); |
| 74 | + continue; |
| 75 | + } |
| 76 | + int minn = 256; |
| 77 | + int pos = 0; |
| 78 | + for (int k = 0; k < 8; k++) { |
| 79 | + int val = 0; |
| 80 | + int id = 0; |
| 81 | + for (int x = -radius; x <= radius; x++) { |
| 82 | + for (int y = -radius; y <= radius; y++) { |
| 83 | + //if (x == 0 && y == 0) continue; |
| 84 | + val += src.at<uchar>(i + x, j + y) * filter[k][id++]; |
| 85 | + } |
| 86 | + } |
| 87 | + val /= cnt[k]; |
| 88 | + if (abs(val - src.at<uchar>(i, j)) < minn) { |
| 89 | + minn = abs(val - src.at<uchar>(i, j)); |
| 90 | + pos = k; |
| 91 | + } |
| 92 | + } |
27 | 93 | int val = 0; |
28 | 94 | int id = 0; |
29 | 95 | for (int x = -radius; x <= radius; x++) { |
30 | 96 | for (int y = -radius; y <= radius; y++) { |
31 | 97 | //if (x == 0 && y == 0) continue; |
32 | | - val += src.at<uchar>(i + x, j + y) * filter[k][id++]; |
| 98 | + val += src.at<uchar>(i + x, j + y) * filter[pos][id++]; |
33 | 99 | } |
34 | 100 | } |
35 | | - val /= cnt[k]; |
36 | | - if (abs(val - src.at<uchar>(i, j)) < minn) { |
37 | | - minn = abs(val - src.at<uchar>(i, j)); |
38 | | - pos = k; |
39 | | - } |
| 101 | + dst.at<uchar>(i, j) = val / cnt[pos]; |
40 | 102 | } |
41 | | - int val = 0; |
42 | | - int id = 0; |
43 | | - for (int x = -radius; x <= radius; x++) { |
44 | | - for (int y = -radius; y <= radius; y++) { |
45 | | - //if (x == 0 && y == 0) continue; |
46 | | - val += src.at<uchar>(i + x, j + y) * filter[pos][id++]; |
| 103 | + } |
| 104 | + return dst; |
| 105 | + } |
| 106 | + Mat dst(row, col, CV_8UC3); |
| 107 | + for (int c = 0; c < 3; c++) { |
| 108 | + for (int i = 0; i < row; i++) { |
| 109 | + for (int j = 0; j < col; j++) { |
| 110 | + if (i < radius || i + radius >= row || j < radius || j + radius >= col) { |
| 111 | + dst.at<Vec3b>(i, j)[c] = src.at<Vec3b>(i, j)[c]; |
| 112 | + continue; |
| 113 | + } |
| 114 | + int minn = 256; |
| 115 | + int pos = 0; |
| 116 | + for (int k = 0; k < 8; k++) { |
| 117 | + int val = 0; |
| 118 | + int id = 0; |
| 119 | + for (int x = -radius; x <= radius; x++) { |
| 120 | + for (int y = -radius; y <= radius; y++) { |
| 121 | + //if (x == 0 && y == 0) continue; |
| 122 | + val += src.at<Vec3b>(i + x, j + y)[c] * filter[k][id++]; |
| 123 | + } |
| 124 | + } |
| 125 | + val /= cnt[k]; |
| 126 | + if (abs(val - src.at<Vec3b>(i, j)[c]) < minn) { |
| 127 | + minn = abs(val - src.at<Vec3b>(i, j)[c]); |
| 128 | + pos = k; |
| 129 | + } |
47 | 130 | } |
| 131 | + int val = 0; |
| 132 | + int id = 0; |
| 133 | + for (int x = -radius; x <= radius; x++) { |
| 134 | + for (int y = -radius; y <= radius; y++) { |
| 135 | + //if (x == 0 && y == 0) continue; |
| 136 | + val += src.at<Vec3b>(i + x, j + y)[c] * filter[pos][id++]; |
| 137 | + } |
| 138 | + } |
| 139 | + dst.at<Vec3b>(i, j)[c] = val / cnt[pos]; |
48 | 140 | } |
49 | | - dst.at<uchar>(i, j) = val / cnt[pos]; |
50 | 141 | } |
51 | 142 | } |
52 | 143 | return dst; |
53 | 144 | } |
54 | 145 |
|
55 | 146 | int main() { |
56 | | - Mat src = imread("F:\\cat.jpg", 0); |
57 | | - for (int i = 0; i < 18; i++) { |
58 | | - src = SideWindowFilter(src, 1); |
| 147 | + Mat src = imread("F:\\panda.jpg"); |
| 148 | + cv::imshow("origin", src); |
| 149 | + |
| 150 | + for (int i = 0; i < 9; i++) { |
| 151 | + src = SideWindowFilter(src, 3); |
59 | 152 | //medianBlur(src, src, 3); |
60 | 153 | } |
61 | 154 | //Mat dst; |
62 | 155 | //medianBlur(src, dst, 3); |
63 | | - Mat dst = SideWindowFilter(src, 1); |
| 156 | + Mat dst = SideWindowFilter(src, 3); |
64 | 157 | imshow("result", dst); |
65 | 158 | imwrite("F:\\res.jpg", dst); |
66 | 159 | waitKey(0); |
|
0 commit comments