Skip to content

Commit f091954

Browse files
committed
Add SideWindowFilter.cpp
1 parent ee4a5dc commit f091954

File tree

1 file changed

+130
-37
lines changed

1 file changed

+130
-37
lines changed

SideWindowFilter.cpp

Lines changed: 130 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,159 @@
1+
#include <stdio.h>
2+
#include <iostream>
3+
#include <immintrin.h>
4+
#include <opencv2/opencv.hpp>
5+
using namespace cv;
6+
using namespace std;
17
//针对灰度图的均值滤波+CVPR 2019的SideWindowFilter
28
//其他种类的滤波直接换核即可
39

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+
459
Mat SideWindowFilter(Mat src, int radius = 1) {
560
int row = src.rows;
661
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+
}
2793
int val = 0;
2894
int id = 0;
2995
for (int x = -radius; x <= radius; x++) {
3096
for (int y = -radius; y <= radius; y++) {
3197
//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++];
3399
}
34100
}
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];
40102
}
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+
}
47130
}
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];
48140
}
49-
dst.at<uchar>(i, j) = val / cnt[pos];
50141
}
51142
}
52143
return dst;
53144
}
54145

55146
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);
59152
//medianBlur(src, src, 3);
60153
}
61154
//Mat dst;
62155
//medianBlur(src, dst, 3);
63-
Mat dst = SideWindowFilter(src, 1);
156+
Mat dst = SideWindowFilter(src, 3);
64157
imshow("result", dst);
65158
imwrite("F:\\res.jpg", dst);
66159
waitKey(0);

0 commit comments

Comments
 (0)