영상처리에서 한 픽셀의 수정을 위해서 주변 픽셀의 정보를 요구하는 윈도 기반 필터들은 일반적 연산 비용이 큰 편이다. 한 변의 길이가
윈도가 움직이면서 윈도 내 모든 픽셀이 다 바뀌는 것이 아니라 움직이는 방향에 수직인 가장자리 픽셀만 바뀐다는 사실을 이용하면 각 픽셀의 윈도에서 median을 찾는 작업을 할 필요가 없다. 예를 들면 scanline 방향(
// boundary region도 처리할 수 있게 수정함; 2021-04-18;
// window size = wx * wy;
// median = argmin(hist[i] >= halfArea)
int RunningMedianFilter(BYTE* image, int w, int h, int wx, int wy, BYTE* out) {
int hist[256], x;
int wxhalf = wx >> 1;
int wyhalf = wy >> 1;
wx = (wxhalf << 1) + 1; // size of window = odd number;
wy = (wyhalf << 1) + 1;
for (int y = 0, yw = 0; y < h; ++y, yw += w) {
// calc available area;
int wystart = max(0, y - wyhalf);
int wystop = min(h, y + wyhalf);
int wysize = wystop - wystart + 1;
int wxstart = 0;
int wxstop = wxhalf;
int halfArea = (wxstop * wysize + 1) >> 1;
// to avoid *w multiplication in y-step;
wystart *= w;
wystop *= w;
// initial histogram of topleft window;
memset(hist, 0, 256 * sizeof(int));
for (int iy = wystart; iy <= wystop; iy += w)
for (int ix = wxstart; ix <= wxstop; ++ix) hist[image[iy + ix]]++;
// find initial median;
int ltmed = hist[0]; // less_than_median;
int med = 0;
while (ltmed < halfArea) ltmed += hist[++med];
out[yw + 0] = med;
// left edge rgn;
for (x = 1; wxstop < wx; ++x) {
++wxstop;
halfArea = (wxstop * wysize + 1) >> 1;
for (int iy = wystart; iy <= wystop; iy += w) {
int v = image[iy + wxstop]; // (x=wxstop) strip enters;
++hist[v];
if (v <= med) ++ltmed;
}
while (ltmed >= halfArea) ltmed -= hist[med--];
while (ltmed < halfArea) ltmed += hist[++med];
out[yw + x] = med;
}
// central rgn;
for ( ; wxstop < w; ++x) {
++wxstop;
for (int iy = wystart; iy <= wystop; iy += w) {
int v = image[iy + wxstart]; // (x=wxstart) strip leaves;
--hist[v];
if (v <= med) --ltmed;
v = image[iy + wxstop]; // (x=wxstop) strip enters;
++hist[v];
if (v <= med) ++ltmed;
}
++wxstart;
while (ltmed >= halfArea) ltmed -= hist[med--];
while (ltmed < halfArea) ltmed += hist[++med];
out[yw + x] = med;
}
// right edge rgn;
for ( ; x <= w; ++x) {
for (int iy = wystart; iy <= wystop; iy += w) {
int v = image[iy + wxstart]; // (x=wxstart) strip leaves;
--hist[v];
if (v <= med) --ltmed;
}
++wxstart;
halfArea = ((wxstop - wxstart + 1) * wysize + 1) >> 1;
while (ltmed >= halfArea) ltmed -= hist[med--];
while (ltmed < halfArea) ltmed += hist[++med];
out[yw + x] = med;
}
}
return 1;
};
wx=wy=7;

'Image Recognition > Fundamental' 카테고리의 다른 글
Bicubic Interpolation (1) | 2010.01.14 |
---|---|
Bezier Curve을 이용한 Histogram Smoothing (0) | 2010.01.10 |
Fant's Resampling (0) | 2008.12.17 |
Bright Preserving Histogram Equalization with Maximum Entropy (0) | 2008.07.31 |
Adaptive Binarization (2) | 2008.07.14 |