OpenCV - 기본적인 이미지 처리
OpenCV 컬러 변환
일반적으로 컴퓨터에서 컬러를 표현할 때 [r,g,b] 순으로 표현하지만 OpenCV는 [b, g, r] 순으로 표현한다. 그래서 외부에서 이미지를 가져와서 OpenCV로 출력하거나, OpenCV로 읽어들인 이미지를 matplot 등을 통해 표현하려면 색상 순서를 변환해줘야한다.
cv2.merge() 를 사용한 변환
#opencv로 읽은 이미지, 현재 [b,g,r] 순으로 되어있음
img = cv2.imread('a.jpg', cv2.IMREAD_COLOR)
#opencv로 읽은 이미지의 r,g,b순서를 뒤집어 배열
b, g, r = cv2.split(img) # img파일을 b,g,r로 분리
img2 = cv2.merge([r,g,b]) # b, g, r을 [r,g,b]로 Merge 하여 이미지 생성
cv2.cvtColor() 를 사용한 변환
img = cv2.imread('a.jpg') # 현재 [b,g,r]
img2 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) #bgr에서 rgb로 변환하여 이미지 생성
img3 = cv2.cvt.Color(img2, cv2.COLOR_RGB2BGR) #rgb에서 다시 bgr로 변환하여 이미지 생성
컬러 이미지를 그레이스케일로 변환
# 이미지 파일 불러올 때 그레이스케일로 불러오기
gray_img = cv2.imread('a.jpg', 0)
gray_img2 = cv2.imread('a.jpg', cv2.IMREAD_GRAYSCALE)
#cvtColor()로 그레이스케일로 변환
gray_img3 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
이미지 정보 확인
이미지 세로, 가로, 채널 확인 (.shape)
img = cv2.imread('a.jpg')
img.shape
>>> 427, 640, 3 # h(높이), w(너비), c(색상 채널 수) 순
h, w, c = img.shape # h, w, c 변수에 각각 높이, 너비, 채널 수 값을 입력
이미지 데이터 수 확인 (.size)
img = cv2.imread('a.jpg')
img.size
>>> 819840 # h*w*c
이미지 표현 데이터 타입 (.dtype)
img = cv2.imread('a.jpg')
img.dtype
>>> dtype('uint8')
픽셀 추출, 확인 및 변경
특정 픽셀 추출
p = img[100, 100] #(100, 100) 위치의 픽셀 한 개 추출
print(p)
>>> [134, 156, 219] # 픽셀의 값, [b, g, r]
픽셀 정보 확인 (.item)
#픽셀의 한 채널의 값
p = img[100, 100, 2] # 0:b, 1:g, 2:r
print(p)
>>> 219
#.item 사용
p2 = img.item(100, 100, 2) # 픽셀의 red 값 반환, 반드시 채널 인자까지 입력해야 함
print(p2)
>>> 219
픽셀 값 변경 (.itemset)
# (100, 100) 위치의 픽셀을 흰색으로 변경
img[100, 100] = [255, 255, 255]
# .itemset 사용, 픽셀을 검은색으로 변경
img.itemset((100, 100, 0), 0)
img.itemset((100, 100, 1), 0)
img.itemset((100, 100, 2), 0)
ROI (Region of Image)
이미지의 특정 영역을 지정하여 추출할 때 사용
# roi = 이미지[ y시작점 : y끝점, x시작점 : x끝점 ]
roi = img[100:200, 100:300]
cv2.imshow('roi', roi)
cv2.waitKey(0)
cv2.destroyAllWindows()
이미지 채널 분리
cv2.split() 을 통한 분리
b, g, r = cv2.split(img)
img = cv2.merge((r,g,b)) # bgr-to-rgb
- 간단하지만 이미치 처리 비용이 비싸기 때문에 numpy 인덱싱으로 접근하는 것이 효과적이다.
numpy 인덱싱을 통한 분리
색상채널 0:blue, 1:green, 2:red
# 이미지에서 특정 색상 추출. 이미지 전체를 roi로 지정하여 데이터 추출
img_blue = img[:, :, 0]
img_green = img[:, :, 1]
img_red = img[:, :, 2]
# 이미지에서 특정 색상 제거
img[:, :, 2] = 0 # img에서 빨간색 제거
이미지 복사
src = cv2.imread('a.jpg')
img1 = src # 얕은복사, src의 데이터 참조 주소만을 img1에 입력
img2 = src[100:200, 100:200] # 얕은복사
img3 = src.copy() # 깊은복사
img1[100:200, 100:200, 2] = 255 # img1의 특정 지역을 roi로 정하여 색상 변경
- 위 코드를 실행하고나면 img1에 복사된 참조주소의 데이터가 영향을 받으므로 img1과 함께 src의 색상도 변경된다.
- roi를 통해 일부 영역만 복사한 img2 역시 얕은 복사가 되었기 때문에 영향을 받는다.
- 하지만 img2는 깊은 복사를 하여 별도의 데이터 주소를 가졌기 때문에 영향을 받지 않는다.
댓글남기기