이해하기 쉽게 흑백 이미지를 예로 들어서 이미지의 밝기 처리를 해본다.
opencv GRAYSCALE
흑백이미지 한 픽셀의 데이터 사이즈를 보통 uint8로 정의하는데 0 ~ 255 범위를 갖게된다.
다음은 화소값의 변화에 따른 이미지의 밝기 변화이다.
import numpy as np import cv2 image1 = np.zeros((50,512),np.uint8) image2 = np.zeros((50,512),np.uint8) rows,cols = image1.shape[:2] for i in range(rows): for j in range(cols): image1.itemset( (i, j ), j//2) image2.itemset( (i, j ), j//20*10) cv2.imshow("image1",image1) cv2.imshow("image2",image2) cv2.waitKey(0) cv2.destroyAllWindows()
관심영역의 이미지 값을 직접 확인해보면.... ( IU )
머리 부분에 관심영역이 있는데 검은 머리라서 pixel 값이 낮게 나왔다. 반면에 배경부분은 밝기 때문에 pixel값이 높게 나왔다.
opencv는 밝기를 조절하는 방법이 2가지 있다.
1. saturation ( cv2.add(), cv2.subtract() )
2. modulo ( + , - )
saturation 방식은 화소를 더해주거나 빼줬을 때 최소 0, 최대 255 값으로 변경된다.
modulo 방식은 0 보다 작아지면 255 , 255 보다 커지면 0으로 바뀌어 계산된다.import cv2 image = cv2.imread("iu2.jpg",cv2.IMREAD_GRAYSCALE) if image is None: raise Exception("이미지 x") image_shape_y,image_shape_x = image.shape[:2] image = cv2.resize(image,(image_shape_x//4,image_shape_y//4)) dst1 = cv2.add(image,100) dst2 = cv2.subtract(image,100) cv2.imshow("original",image) cv2.imshow("bright_image",dst1) cv2.imshow("dark_image",dst2) cv2.waitKey(0) cv2.destroyAllWindows()
=> saturation 방식 밝기 조절 ( 원본, cv2.subtract, cv2.add )
: 밝기에 따라 느낌이 다르다~
명암 대비란 상이한 두 가지 색이 경계에서 서로 영향을 미쳐 그 차이가 가 강조되어 나타나는 현상
낮은 명암 대비 이미지는 전체적으로 이미지가 어둡거나 밝다. ( 사물이나 배경 구분이 어렵다.)noimage = np.zeros(image.shape[:2], image.dtype) avg = cv2.mean(image)[0]/2.0 dst1 = cv2.scaleAdd(image,0.5,noimage) dst2 = cv2.scaleAdd(image,2.0,noimage) dst3 = cv2.addWeighted(image,0.5,noimage,0,avg) dst4 = cv2.addWeighted(image,2.0,noimage,0,-avg)
avg는 명암 대비 효과를 높이기 위해서 이미지의 전체 평균의 절반값을 계산한다.
dst1은 scaleAdd를 사용하여 명암대비 0.5배
dst2는 scaleAdd를 사용하여 명암대비 2배
곱셈만으로 명암대비를 조절하면 이미지가 전체적으로 어두워지거나 밝아진다. (dst2 , dst1)dst3와 dst4는 명암대비를 조절하면서 이미지의 화소값의 평균값을 추가로 이용한다.
cv2.addWeighted(이미지1,이미지1가중치,이미지2,이미지2가중치,결과에 추가적으로 더할 값)
dst3는 이미지의 명암을 0.5배 곱한 후 평균의 절반을 더해주었다.
dst4는 이미지의 명암을 2배 곱한 후 평균의 절반을 빼주었다.
그 결과 전반적으로 밝고 밝은 부분은 더 밝게 어두운 부분은 어둡게 되며 전체적으로 이미지가 또렷해졌다.