import numpy as np
import matplotlib.pyplot as plt
import cv2 as cv
# 히스토그램 스트레칭 함수
def imadjust(src, input_range=None, output_range=None, gamma=1.0): # (원본영상, 입력범위, 출력범위, 감마)
src_dtype = src.dtype
if src_dtype == 'uint8':
src = src / 255
if input_range == None:
input_range = [0, 1]
if output_range == None:
output_range = [0, 1]
low_in, high_in = input_range
low_out, high_out = output_range
r = np.arange(0, 256) / 255.0
g = np.arange(0, 256) / 255.0 # LUT
g[g < low_in] = low_out
g[g > high_in] = high_out
g = np.where((r >= low_in) & (r <= high_in),
((r - low_in) / (high_in - low_in)) ** (gamma) * (high_out - low_out) + low_out, g)
dst = g[(src*255).astype('uint8')] # LUT를 사용하여 이미지 변환
if src_dtype == 'uint8':
dst = (dst * 255).astype('uint8')
return dst
img = cv.imread('data/lenna.tif')
#img = cv.cvtColor(img, cv.COLOR_BGR2GRAY) # 흑백 영상
img = img[..., ::-1]
img = img / 255
plt.figure('image')
plt.subplot(2, 2, 1)
plt.title('input image')
plt.axis('off')
plt.imshow(img, cmap='gray')
plt.subplot(2, 2, 2)
dst1 = imadjust(img, input_range=[0, 1], output_range=[0.3, 0.7])
plt.title(str([0, 1]) + ' -> ' + str([0.3, 0.7]))
plt.axis('off')
plt.imshow(dst1, cmap='gray')
plt.subplot(2, 2, 3)
dst2 = imadjust(img, input_range=[0.2, 0.8], output_range=[0, 1])
plt.title(str([0.2, 0.8]) + ' -> ' + str([0, 1]))
plt.axis('off')
plt.imshow(dst2, cmap='gray')
plt.subplot(2, 2, 4)
dst3 = imadjust(img, input_range=[0.4, 0.6], output_range=[0, 1])
plt.title(str([0.4, 0.6]) + ' -> ' + str([0, 1]))
plt.imshow(dst3, cmap='gray')
plt.axis('off')
plt.show()
if img.dtype == 'uint8':
bin_range = [0, 256]
else:
bin_range = [0, 1]
plt.figure('image_histogram')
plt.subplot(2, 2, 1)
plt.title('Histogram : input image')
plt.hist(img.ravel(), 256, bin_range)
plt.subplot(2, 2, 2)
plt.title('Histogram : '+ str([0, 1]) + ' -> ' + str([0.3, 0.7]))
plt.hist(dst1.ravel(), 256, bin_range)
plt.subplot(2, 2, 3)
plt.title('Histogram : ' + str([0.2, 0.8]) + ' -> ' + str([0, 1]))
plt.hist(dst2.ravel(), 256, bin_range)
plt.subplot(2, 2, 4)
plt.title('Histogram : ' + str([0.4, 0.6]) + ' -> ' + str([0, 1]))
plt.hist(dst3.ravel(), 256, bin_range)
plt.show()
org = cv.imread('data/lenna.tif')
img2 = imadjust(org, [0.4, 0.7], [0, 1], 0.3)
psnr = cv.PSNR(org, img2)
print('%.4f' % psnr)
org = cv.imread('data/lenna.tif') / 255
img2 = imadjust(org, [0, 1], [0.4, 0.7], 0.3)
sse = np.sum((org - img2) ** 2)
print('%.3e' % sse)
# imadjust(src, input_range=[0,1], output_range=[0,1], gamma=1.0)
- 히스토그램 스트레칭을 하는 함수
- 히스토그램 스트레칭은 히스토그램의 양쪽 끝단을 잡아당겨서 영상의 대조비를 강화하여 선명한 영상 얻음
- low_in, high_in 은 입력범위의 최소, 최대(디폴트는 [0,1])
- low_out, high_out 은 출력범위의 최소, 최대(디폴트는 [0,1])
- low_in 보다 작은 값은 low_out 으로 출력함
- low_out 보다 큰 값을 high_out 으로 출력함
- low_in 과 high_in 사이의 값들은 감마 변환을 하여 출력함
- np.where() 함수를 사용하여 조건에 해당하는 인덱스에 해당하는 값을 변환함
- 감마가 1보다 크면 어둡게, 1보다 작으면 밝게 변함, 1이면 원본과 동일
- 입력영상이 uint8과 float64 제한 없게 하기 위하여 uint8인 경우 255로 나누어 정규화 시 킨 뒤 스트레칭 작업을 수행한 후 다시 255를 곱하고 uint8로 변환하여 반환함
- Look Up Table를 사용하기 위하여 x축 데이터 r(0~1) 과 변환 테이블 g를 생성함
- 화소 값에 따라 스트레칭한 값을 g에 저장함
- 변환 테이블 g를 사용하여 입력영상에 적용하여 스트레칭한 결과 영상 반환 받음
# 원본영상과 히스토그램 스트레칭한 영상 출력
- 원본영상이 uint8인 경우 bin 범위를 [0, 256] 로 설정
- 원본영상이 float64인 경우 bin 범위를 [0, 1] 로 설정
- 영상을 읽어올 때cv.imread()로 읽으면 b,g,r 순이므로 역순으로 재배열함
- 2x2 형태의 창에 원본 영상과3개의 히스토그램 스트레칭한 영상 출력하고 각각에 대한 히 스토그램 출력
- 히스토그램을 출력할 때는 영상을 1차원 리스트로 변환하여 입력하여야 함
- 1차원 리스트로 변환한 영상, bin의 개수 bin 범위를 입력하여 히스토그램 출력함
# 필요한 모듈 import
- numpy, matplotlib.pyplot, cv2
# 실행 결과
1. 칼라 영상(uint8)인 경우
- 원본과 imadjust 실행한 영상 3개
- 영상들의 히스토그램
2. 칼라 영상(float64)인 경우
- 원본과 imadjust 실행한 영상 3개
- 영상들의 히스토그램
3. 흑백 영상(uint8)인 경우
- 원본과 imadjust 실행한 영상 3개
- 영상들의 히스토그램
4. 흑백 영상(float64)인 경우
- 원본과 imadjust 실행한 영상 3개
- 영상들의 히스토그램
# 느낀 점
- 실행결과를 보니 결과 영상은 얼추 맞게 나오는 것 같으나 확신하지 못함
- 자체 평가표에 주어진 문제에 대한 출력 값이 올바르게 나오지 않음
- 감마 변환에 대한 수식이 올바르지 못한 거 같음
- uint8과 float64에 대한 제한이 없다는 것을 억지로 맞춰서 되게끔 한 거 같아 올바른 방법 이 무엇인지 궁금함
'전공 공부 > 영상처리' 카테고리의 다른 글
Chroma Key Editor (0) | 2020.12.29 |
---|---|
UnsharpMasking 커널 기반 처리(나만의 생각..) (0) | 2020.12.29 |
UnsharpMasking 트랙 바로 시그마, 스케일 조정 (0) | 2020.12.29 |
히스토그램 명세화 작업 후 r,g,b 채널별 히스토그램 출력 (0) | 2020.12.29 |
시그모이드 그래프 출력 (0) | 2020.12.21 |