adaptive Median Filter

jh Seo·2023년 11월 11일
0

openCV공부

목록 보기
5/5

개요

구현한 순서는
현재 픽셀좌표(x,y) 주위의 window(크기는 kernelsize로 받아온다.)의 픽셀값을 전부 벡터에 넣고 정렬을 한다.
현재 픽셀값이 정렬된 벡터의 범위에 포함되는 지 확인을 한다.
포함이 된다면 현재 픽셀값을 정렬된 벡터에서 중간값으로 할당해주고
포함이 안된다면 window사이즈를 키워나간다.
window사이즈가 maxWindowSize가 될때까지 키워나가며 반복한다.

여기서 실수 했던건 반복문을
windowSize를 처음에 3이아니라 1로 해버리고,
nx, ny가 x,y 인지를 체크도 안해서
벡터에 현재좌표의 값이 계속 들어가게 되었다.

따라서 모든 window에서 자신의 좌표값이 계속 들어가버리고
window도 1부터 시작하므로 벡터에는 현재 픽셀 값만 들어오고,
최대값 최소값 중간값이 현재 픽셀값이니 filter과정을 안 거치게 되며
입력영상을 그대로 내뱉었다...

수정

void adaptiveMedianFilter(Mat& src, Mat& outImg, int maxWindowSize) {
		outImg = src.clone();

	int height = src.rows;
	int width = src.cols;

	for (int k = 0; k < src.channels(); k++) {
		for (int y = 0; y < height; ++y) {
			for (int x = 0; x < width; ++x) {
				int windowSize = 3;
				int currentValue;

				do {
					int edge = windowSize / 2;
					int minPixelValue = 255;
					int maxPixelValue = 0;
					int medianPixelValue;

					std::vector<unsigned char> pixels;
					for (int dy = -edge; dy <= edge; ++dy) {
						for (int dx = -edge; dx <= edge; ++dx) {
							int nx = x + dx;
							int ny = y + dy;
							if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
								pixels.push_back(src.data[ny*width*src.channels()+ nx*src.channels()+k]);
							}
						}
					}

					currentValue = src.data[y*src.cols * src.channels()+ x*src.channels() + k];
					std::sort(pixels.begin(), pixels.end());
					minPixelValue = pixels.front();
					maxPixelValue = pixels.back();
					medianPixelValue = pixels[pixels.size() / 2];

					if (currentValue < minPixelValue || currentValue > maxPixelValue) {
						windowSize += 2;
						if (windowSize > maxWindowSize) {
							windowSize = maxWindowSize;
							break;
						}
					}
					else {
						outImg.data[y*src.cols*src.channels()+ x * src.channels()+k] = medianPixelValue;
						break;
					}
				} while (true);
			}
		}
	}
}
profile
코딩 창고!

0개의 댓글