OpenCV 중앙값 필터

Salman Mehmood 2022년6월13일
OpenCV 중앙값 필터

이 데모에서는 중앙값 필터가 무엇인지 배우고 OpenCV에서 두 가지 유형의 중앙값 필터에 대해 설명합니다. 그런 다음 이러한 중앙값 필터를 사용하여 이미지에서 소금과 후추 노이즈를 제거하는 방법도 배우게 됩니다.

OpenCV의 중앙값 필터를 사용하여 이미지에서 소금과 후추 노이즈 제거

노이즈 제거, 특히 소금과 후추 유형의 노이즈에 탁월한 중간 필터를 살펴보겠습니다. 중앙값에 대한 간단한 강의를 시작하기 전에, 우리 모두는 평균이 모든 숫자의 평균과 사람들이 사용하는 전형적인 예에 ​​불과하다는 것을 알고 있습니다.

예를 들어, 귀하의 집이 350,000, 425,000 등의 범위에 있는 동네에 살고 있습니다. 언덕 위 어딘가에 있는 이웃에 두 명의 부자가 살고 있을 것입니다. 그 집의 가치는 220만, 320만, 등.

이 모든 것의 평균을 보고 931 500을 보고 놀랐다고 가정해 보겠습니다. 아마도 931 500이 평균 집값이라고 생각할 것입니다. 그래서 항상 집값의 중간값을 봅니다.

이 값의 중앙값을 보십시오. 평균보다 스프레드를 더 잘 나타내는 512 500이 됩니다. 이것은 5학년이나 6학년 때 배웠을 통계이며, 이것을 언급하는 이유는 이 이미지에서 보여주기 때문입니다.

opencv 중앙값 필터 예 1

아래 이미지는 인위적으로 소금 후추 노이즈가 많이 추가되어 어둡고 밝은 픽셀이 많이 보입니다. 확대하면 균일하게 회색으로 표시되는 이 영역을 볼 수 있습니다.

이러한 소금과 후추 소리가 나타나는 이유는 무엇입니까? 여러 가지 이유로, 특히 아날로그에서 디지털로의 변환에 문제가 있는 이미지를 캡처하는 데 사용했던 구형 전자 장치에서 소금과 후추 노이즈의 주요 원인이 있습니다.

opencv 중앙값 필터 예제 2

가우시안 블러는 괜찮지만 이러한 유형의 노이즈를 제거하는 데는 좋지 않으며 기술적으로 중앙값 필터가 더 잘 작동해야 합니다. 자세히 보면 밝은 픽셀로 나타나는 이 한 픽셀을 제외하고는 모두 거의 균일한 회색입니다.

3x3 커널을 적용하고 중앙값을 보면 이 중앙 픽셀을 둘러싼 모든 것을 보고 있습니다. 이 빨간 상자 안에 있는 모든 숫자의 중앙값은 140입니다.

255를 140으로 교체하면 매우 균일하고 균일한 이미지를 얻을 수 있습니다.

opencv 중앙값 필터 예 3

이것은 빠른 그림, 그래픽 표현이므로 Python 코드로 이동해 보겠습니다. 먼저 skimage.filters에서 cv2median을 가져와서 두 패키지 모두에서 중앙값을 사용하는 방법을 보여드리겠습니다.

우리는 두 개의 이미지를 가져오고 있습니다. 하나는 소금과 후추와 크기 조정을 위한 것입니다. medianBlur() 메서드를 사용하여 이미지를 전달하고 커널 크기를 3으로 설정해야 합니다.

import cv2
from skimage.filters import median

SP_IMG = cv2.imread("inp.tif", 0)
IMG = cv2.resize(SP_IMG, (720, 600))

IMG = IMG

Opencv_Median = cv2.medianBlur(IMG, 3)

지금 우리는 같은 용어를 사용하고 있습니다. skimage는 커널을 정의하고 우리가 디스크라고 부르는 것을 사용한다는 점을 제외하면 매우 유사합니다.

skimage 패키지에서 median() 메서드를 호출하고 이미지를 전달해야 합니다. 커널 크기 대신 디스크 크기를 생성합니다.

디스크를 인쇄할 때 0픽셀에 0을 곱한 행렬이 생성되고 이미지 위에서 이동할 때 이 1픽셀에 1이 곱해집니다.

opencv 중앙값 필터 예 4

이제 mode 인수를 전달합니다. 아무것도 아니지만 이 커널이 이미지 끝에 도달했을 때 끝 픽셀을 어떻게 처리합니까?

오른쪽에 아무 것도 없기 때문에 상수 값으로 일부 픽셀을 추가합니다.

예제 코드:

from skimage.morphology import disk
import cv2
from skimage.filters import median

SP_IMG = cv2.imread("inp.tif", 0)
IMG = cv2.resize(SP_IMG, (720, 600))

IMG = IMG

Opencv_Median = cv2.medianBlur(IMG, 3)


print(disk(3))

SK_Median = median(IMG, disk(3), mode="constant", cval=0.0)

cv2.imshow("Original", IMG)
cv2.imshow("cv2 median", Opencv_Median)
cv2.imshow("Using skimage median", SK_Median)

cv2.waitKey(0)
cv2.destroyAllWindows()

3개의 출력이 있고 하나는 가우스 노이즈가 있는 원본 이미지입니다.

opencv 중앙값 필터 출력 1

두 번째 출력은 OpenCV를 사용한 중앙값 이미지입니다. 이 출력에서 ​​결과는 원본 이미지보다 좋습니다.

opencv 중앙값 필터 출력 2

skimage 중앙값을 사용하여 다음 출력을 보면 배경에 아무 것도 없이 매우 깨끗해 보입니다.

opencv 중간 필터 출력 3

우리는 skimage 중앙값이 OpenCV 중앙값보다 훨씬 더 좋아 보인다는 것을 관찰할 수 있습니다. 왜냐하면 커널 크기가 이 중앙값에 대해 약간 더 작고 원본 이미지에 비해 그다지 깨끗하지 않기 때문입니다. skimage와 OpenCV 중간 출력 이미지가 동일하게 보이지 않는 이유는 무엇입니까?

skimage 중앙값에서 디스크 크기를 정의하고 OpenCV 중앙값에서 커널 크기를 정의합니다.

커널 크기가 다릅니다. 따라서 출력이 약간 다르게 보입니다. 동일한 커널 크기를 얻는다면 수학은 동일할 것입니다.

Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn

관련 문장 - Python OpenCV