median filter를 사용하여 이미지의 salt and pepper noise 제거 예제 코드
본 글은 median filter를 사용하여 salt and pepper noise를 제거하는 예제 코드를
싣고 있다.
이전 “임펄스(Impluse) 노이즈 제거를 위한 median filter c source code”글에서 median filter로 신호에 발생한 임펄스 노이즈를 제거하는 예제를 본적이
있다.
이번에는 median filter를 사용하여 이미지의 slat and pepper noise를 제거해
보았다.
위키피디아(https://en.wikipedia.org/wiki/File:Noise_salt_and_pepper.png)에서 다운 받은 이미지를 사용하기로 했다. 원리는 이전 글의 median filter와
동일하다. 다만 이미지 데이터 처리를 위해 데이터 형식이 int형으로
변형되었다. 다만 다운받은 테스트 이미지에 컬러가 없어서 컬러는 데이터는
고려하지 않았다. png파일은 24bits bitmap으로 변환하여 테스트하였다.
typedef int element_type;
int compare(const void *f1, const void *f2)
{
return (*(element_type*)f1 >
*(element_type*)f2) ? 1 : -1;
}
element_type get_qsort_median(element_type*data, int n)
{
if (!data || n <= 0) return 0;
qsort(data, n, sizeof(element_type),
compare);
return data[n / 2];
}
int get_pixels(unsigned char *in, int *out, RECT *rect, int stride, int
bytesperpixel)
{
int x = 0;
int y = 0;
int n = 0;
if (!in || !out || !rect) return -1;
y = rect->top;
while (y < rect->bottom)
{
x = rect->left;
while ( x < rect->right)
{
int pos = (x*bytesperpixel) +
(y*stride);
out[n] = ((int)in[pos] & 0xff)
<< 16 | ((int)in[pos+1] & 0xff) << 8 | ((int)in[pos+2] &
0xff);
n++;
x++;
}
y++;
}
return 0;
}
int median_filter_2d(unsigned char *in, unsigned char *out, int W, int H, int BytesPerPixel)
{
#define window_size 3
int temp[window_size*window_size] = {
0, };
int x = 0;
int y = 0;
int stride = W*BytesPerPixel;
if (!in || !out || W < window_size
|| H < window_size) return -1;
y = 0;
while (y < H)
{
x = 0;
while (x < W)
{
RECT rect;
int pos = x*BytesPerPixel + y*stride;
int val = 0;
rect.left = x - window_size / 2;
rect.top = y - window_size / 2;
if (rect.left < 0) rect.left = 0;
if (rect.top < 0) rect.top = 0;
rect.right = rect.left + window_size;
rect.bottom = rect.top + window_size;
if (rect.right >= W) rect.right = W
- 1;
if (rect.bottom >= H) rect.bottom =
H - 1;
get_pixels(in, temp, &rect,
stride, BytesPerPixel);
val = get_qsort_median(temp,
(rect.right - rect.left)*(rect.bottom - rect.top));
out[pos] = (val & 0xff0000)
>> 16;
out[pos+1] = (val & 0xff00)
>> 8;
out[pos+2] = (val & 0xff);
x++;
}
y++;
}
return 0;
}
다운받은
Noise_salt_and_pepper.png파일을 위 구현한 median_fileter_2d를 사용하여 노이즈를 제거하면 아래
오른쪽 이미지를 얻을 수 있다.
왼쪽 이미지의 노이즈가 오른쪽 이미지에서는 사라진 것이 보인다.
[관련 포스트]
댓글
댓글 쓰기