(原創) 如何對有Noise圖片做Median Filter? (.NET) (C/C++) (C++/CLI) (GDI+) (Image Processing)
1
/*
2
(C) OOMusou 2006 http://oomusou.cnblogs.com
3
4
Filename : BoxFilter.cpp
5
Compiler : Visual C++ 8.0 / C++/CLI
6
Description : Demo how to process Median Filter
7
Release : 12/20/2006 1.0
8
*/
9
#include "stdafx.h"
10
#include "stdlib.h"
11
#include <iostream>
12
13
using namespace System::Drawing;
14
using namespace System::Drawing::Imaging;
15
using namespace std;
16
17
void medianFilter(Bitmap^, Bitmap^, int, int);
18
int compare(const void*, const void*);
19
20
int colorToInt(Color);
21
22
int 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
33
void 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
69
int compare(const void* arg1, const void* arg2) {
70
return *(int**)arg1 < *(int**)arg2;
71
}
72
73
// Convert RGB to gray level int
74
int colorToInt(Color color) {
75
return (color.R + color.G + color.B) / 3;
76
}

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

原圖

執行結果
