이미지에 노이즈 추가 및 제거와 대조 향상을 위한 히스토그램 평활화

김성빈·2024년 5월 22일
0

Modern Computer Vision

목록 보기
41/117

노이즈(Noise)란?
노이즈란 이미지나 오디오 등에서 발생하는 임의의 불규칙한 신호를 말한다.

노이즈는 주로 디지털 카메라 센서나 스캐너 등에서 발생하는데, 이는 빛이 부족한 상황에서 카메라 센서가 받아들이는 신호의 무작위한 변동으로 인해 발생한다.

위의 이미지도 카메라의 민감도(ISO)를 높이니까 노이즈가 많아지는것을 확인 할 수 있다.

백색 노이즈 추가

백색 노이즈 함수 선언

import random
import numpy as np

def addWhiteNoise(image):
    # 무작위 확률에 대한 범위 설정
    # 높은 확률은 더 많은 노이즈를 의미합니다.
    prob = random.uniform(0.05, 0.1)

    # 입력 이미지의 모양과 같은 형태의 무작위 행렬 생성
    rnd = np.random.rand(image.shape[0], image.shape[1])

    # rnd 행렬의 무작위 값이 무작위 확률보다 작으면
    # 입력 이미지의 해당 픽셀을 지정된 범위 내의 값으로 무작위로 변경합니다.
    image[rnd < prob] = np.random.randint(50,230)
    return image

백색 노이즈 적용

# Load our image
image = cv2.imread('images/londonxmas.jpeg')
imshow("Input Image", image)

# Apply our white noise function to our input image 
noise_1 = addWhiteNoise(image)
imshow("Noise Added", noise_1)


위 원본 이미지에서 백색 노이즈를 추가했다.

그냥 봤을땐 눈치 못채지만,

밤 하늘에 별같은 것들이 많이 생긴것을 인지하고 건물을

확인하면 그제서야 보인다.

노이즈 제거

# cv2.fastNlMeansDenoisingColored(input, None, h, hForColorComponents, templateWindowSize, searchWindowSize)
# None are - the filter strength 'h' (5-12 is a good range)
# Next is hForColorComponents, set as same value as h again
# templateWindowSize (odd numbers only) rec. 7
# searchWindowSize (odd numbers only) rec. 21

dst = cv2.fastNlMeansDenoisingColored(noise_1, None, 11, 6, 7, 21)

imshow("Noise Removed", dst)

함수를 이용해서 노이즈를 제거했는데,

대체로 많은 노이즈가 남아있지만, 그래도 전 사진보다는

줄은것을 확인 할 수 있다.

히스토그램 균등화(Histogram Equalization)

# Load our image
img = cv2.imread('soaps.jpeg')
imshow("Original", img)

gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Create our histogram distribution
hist,bins = np.histogram(gray_image.flatten(),256,[0,256])

# Get the Cumulative Sum 
cdf = hist.cumsum()

# Get a normalize cumulative distribution
cdf_normalized = cdf * float(hist.max()) / cdf.max()

# Plot our CDF overlaid onto our Histogram
plt.plot(cdf_normalized, color = 'b')
plt.hist(gray_image.flatten(),256,[0,256], color = 'r')
plt.xlim([0,256])
plt.legend(('cdf','histogram'), loc = 'upper left')
plt.show()
imshow("gray_image", gray_image)

위의 이미지를 그레이스케일 한 후 histogram과 cdf를 계산했다.

cdf는 픽셀의 누적빈도를 나타내며 해당 픽셀(histogram)이 많은 부분에서는 급격하게 증가한다.

히스토그램 균등화를 적용

img = cv2.imread('soaps.jpeg')

# Convert to grayscale
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Equalize our Histogram
gray_image = cv2.equalizeHist(gray_image)
imshow("equalizeHist", gray_image)

# Create our histogram distribution
hist,bins = np.histogram(gray_image.flatten(),256,[0,256])

# Get the Cumulative Sum 
cdf = hist.cumsum()

# Get a normalize cumulative distribution
cdf_normalized = cdf * float(hist.max()) / cdf.max()

# Plot our CDF overlaid onto our Histogram
plt.plot(cdf_normalized, color = 'b')
plt.hist(gray_image.flatten(),256,[0,256], color = 'r')
plt.xlim([0,256])
plt.legend(('cdf','histogram'), loc = 'upper left')
plt.show()

균등화한 이미지를 확인해보면, 색이 진해졌고,

사물인식이 잘된다.

히스토그램 균등화를 한 목적중

이미지의 세부 정보가 더 잘 드러나게 된다는 것이 입증됐다.

cdf와 histogram이 균등화 처리를 한 뒤 말 그대로 균등하게 분포 된 모습이다.

연습문제

이미지의 모든 RGB(BGR) 채널을 등화한 다음 이를 병합하여 등화된 컬러 이미지를 얻어라

# 이미지 불러오기
img = cv2.imread('soaps.jpeg')

# 이미지를 BGR 채널로 분리합니다.
b, g, r = cv2.split(img)

# 각 채널을 개별적으로 평활화합니다.
eq_b = cv2.equalizeHist(b)
eq_g = cv2.equalizeHist(g)
eq_r = cv2.equalizeHist(r)

# 평활화된 채널을 다시 합쳐서 컬러 이미지를 생성합니다.
equalized_img = cv2.merge((eq_b, eq_g, eq_r))

# 평활화된 컬러 이미지를 표시합니다.
imshow("평활화된 컬러 이미지", equalized_img)
profile
감사합니다. https://www.youtube.com/channel/UCxlkiu9_aWijoD7BannNM7w

0개의 댓글