(原創) 如何對有Noise圖片做Median Filter? (.NET) (C/C++) (C++/CLI) (GDI+) (Image Processing)
1/*
2(C) OOMusou 2006 http://oomusou.cnblogs.com
3
4Filename : BoxFilter.cpp
5Compiler : Visual C++ 8.0 / C++/CLI
6Description : Demo how to process Median Filter
7Release : 12/20/2006 1.0
8*/
9#include "stdafx.h"
10#include "stdlib.h"
11#include <iostream>
12
13using namespace System::Drawing;
14using namespace System::Drawing::Imaging;
15using namespace std;
16
17void medianFilter(Bitmap^, Bitmap^, int, int);
18int compare(const void*, const void*);
19
20int colorToInt(Color);
21
22int main() {
23 // Read Gaussian noise image for lena.jpg
24 Bitmap^ gauImg = gcnew Bitmap("lena_gaussian.jpg");
25 // Declare Box Filter image for lena.jpg
26 Bitmap^ mfImg = gcnew Bitmap(gauImg->Width, gauImg->Height);
27 medianFilter(gauImg, mfImg, 3, 3);
28 mfImg->Save("lena_gaussian_medianfilter3x3.jpg");
29
30 return 0;
31}
32
33void medianFilter(Bitmap^ oriImg, Bitmap^ mfImg, int filterW, int filterH) {
34
35 int adjustX = (filterW % 2) ? 1 : 0;
36 int adjustY = (filterH % 2) ? 1 : 0;
37 int xBound = (int)(filterW/2);
38 int yBound = (int)(filterH/2);
39
40 int* arr = (int*)malloc(filterH * filterW * sizeof(int));
41
42 for(int y = 0; y != oriImg->Height; ++y) {
43 for (int x = 0; x != oriImg->Width; ++x) {
44 int cnt = 0;
45 for (int v = -yBound; v != yBound + adjustY; ++v) {
46 for (int u = -xBound; u != xBound + adjustX; ++u) {
47 // check boundary
48 if (x + u < 0 || y + v < 0 || x + u >= oriImg->Width || y + v >= oriImg->Height) {
49 continue;
50 }
51
52 arr[cnt++] = colorToInt(oriImg->GetPixel(x+u, y+v));
53 }
54 }
55
56 qsort((void *)arr, cnt, sizeof(arr[0]), compare);
57
58 int median;
59 if (cnt % 2) // if count is an odd number
60 median = arr[(int)(cnt/2)];
61 else
62 median = (int)((arr[(int)(cnt / 2) - 1] + arr[(int)(cnt / 2)]) / 2);
63
64 mfImg->SetPixel(x, y, Color::FromArgb(median, median, median));
65 }
66 }
67}
68
69int compare(const void* arg1, const void* arg2) {
70 return *(int**)arg1 < *(int**)arg2;
71}
72
73// Convert RGB to gray level int
74int colorToInt(Color color) {
75 return (color.R + color.G + color.B) / 3;
76}
2(C) OOMusou 2006 http://oomusou.cnblogs.com
3
4Filename : BoxFilter.cpp
5Compiler : Visual C++ 8.0 / C++/CLI
6Description : Demo how to process Median Filter
7Release : 12/20/2006 1.0
8*/
9#include "stdafx.h"
10#include "stdlib.h"
11#include <iostream>
12
13using namespace System::Drawing;
14using namespace System::Drawing::Imaging;
15using namespace std;
16
17void medianFilter(Bitmap^, Bitmap^, int, int);
18int compare(const void*, const void*);
19
20int colorToInt(Color);
21
22int main() {
23 // Read Gaussian noise image for lena.jpg
24 Bitmap^ gauImg = gcnew Bitmap("lena_gaussian.jpg");
25 // Declare Box Filter image for lena.jpg
26 Bitmap^ mfImg = gcnew Bitmap(gauImg->Width, gauImg->Height);
27 medianFilter(gauImg, mfImg, 3, 3);
28 mfImg->Save("lena_gaussian_medianfilter3x3.jpg");
29
30 return 0;
31}
32
33void medianFilter(Bitmap^ oriImg, Bitmap^ mfImg, int filterW, int filterH) {
34
35 int adjustX = (filterW % 2) ? 1 : 0;
36 int adjustY = (filterH % 2) ? 1 : 0;
37 int xBound = (int)(filterW/2);
38 int yBound = (int)(filterH/2);
39
40 int* arr = (int*)malloc(filterH * filterW * sizeof(int));
41
42 for(int y = 0; y != oriImg->Height; ++y) {
43 for (int x = 0; x != oriImg->Width; ++x) {
44 int cnt = 0;
45 for (int v = -yBound; v != yBound + adjustY; ++v) {
46 for (int u = -xBound; u != xBound + adjustX; ++u) {
47 // check boundary
48 if (x + u < 0 || y + v < 0 || x + u >= oriImg->Width || y + v >= oriImg->Height) {
49 continue;
50 }
51
52 arr[cnt++] = colorToInt(oriImg->GetPixel(x+u, y+v));
53 }
54 }
55
56 qsort((void *)arr, cnt, sizeof(arr[0]), compare);
57
58 int median;
59 if (cnt % 2) // if count is an odd number
60 median = arr[(int)(cnt/2)];
61 else
62 median = (int)((arr[(int)(cnt / 2) - 1] + arr[(int)(cnt / 2)]) / 2);
63
64 mfImg->SetPixel(x, y, Color::FromArgb(median, median, median));
65 }
66 }
67}
68
69int compare(const void* arg1, const void* arg2) {
70 return *(int**)arg1 < *(int**)arg2;
71}
72
73// Convert RGB to gray level int
74int colorToInt(Color color) {
75 return (color.R + color.G + color.B) / 3;
76}
原圖
執行結果