In [1]:
#from google.colab import drive
#drive.mount('/content/drive')
In [2]:
#%cd /content/drive/MyDrive/Colab Notebooks/opencv
Gray와 Binary 이미지
- 시각은 색상정보에 대해 잘못된 정보를 보내주는 경우가 많음
- 밤에 색상을 볼때 정확한 색상을 보여주지 못함 - 명도 (검정색이 섞이는 것)
- 색상에 빛을 강하게 비추는 경우 정확한 색상을 보여주지 못함 - 채도 (흰색이 섞이는 것)
- 칼라는 너무 많은 정보를 가지고 있기때문에 연산량이 많음
- 실시간 처리가 어려움
- 따라서 gray 이미지나 binary 이미지로 변환해서 처리하는 것이 일반적
- gray 이미지 : 0-255로 된 픽섹로만 구성된 흑백이미지
- binary(이진) 이미지 : 0(검정색)과 255(흰색)으로만 구성된 이미지 (마스크 패턴, 필터링)
- 칼라 → gray 이미지 변환 방법 2가지
- imread()로 이미지를 읽을 때 변환해서 읽는 방법
- img = cv2.imread(파일명, cv2.IMREAD_GRAYSCALE)
- 칼라 이미지로 읽어서 cvtColor() 변환하는 방법 → 칼라 이미지가 필요한 경우 (출력)
- img_gray = cv2.cvtColor(이미지객체, cv2.COLOR_BGR2GRAY)
- img_gray = cv2.cvtColor(이미지객체, cv2.COLOR_BGR2GRAY)
- imread()로 이미지를 읽을 때 변환해서 읽는 방법
- matplotlib 라이브러리의 colormap
- 기본값 : viridis
gray 이미지 만들기
imread()를 사용해서 gray 이미지로 변환해서 읽는 방법
In [3]:
import cv2
import matplotlib.pyplot as plt
img_gray = cv2.imread("./images/image.jpg", cv2.IMREAD_GRAYSCALE)
plt.imshow(img_gray, cmap="gray")
plt.xticks([])
plt.yticks([])
plt.show()
칼라이미지로 읽어서 gray 이미지로 변환하는 방법
In [4]:
import cv2
import matplotlib.pyplot as plt
img = cv2.imread("./images/image.jpg")
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
plt.imshow(img_gray, cmap="gray")
plt.xticks([])
plt.yticks([])
plt.show()
이진 (Binary) 이미지 만들기
- 이진 이미지는 픽셀값이 0과 1(255)로만 구성
- 이진 이미지의 필요 : 배경과 객체의 구분, 관심영역과 비관심 영역의 구분, 마스크 생성 등
- _, thr = cv2.threshold(img, threshold_value, value, flag)
- img : Grayscale 이미지
- threshold_value : 픽셀 문턱값 (0과 1로 나누기 위한 기준값)
- value : 문턱값보다 클 때 적용되는 값
- flag : 문턱값 적용 방법
- flag : 문턱값 적용 방법
- cv2.THRESH_BINARY : 픽셀값이 문턱값보다 크면 value, 아니면 0을 할당
- cv2.THRESH_BINARY_INV : 픽셀값이 문턱값보다 크면 0, 아니면 value를 할당
- cv2.THRESH_TRUNC : 픽셀값이 문턱값보다 크면 문턱값, 아니면 픽셀값을 그대로 할당
- cv2.THRESH_TOZERO : 픽셀값이 문턱값보다 크면 픽셀값, 아니면 0을 할당
- cv2.THRESH_TOZERO_INV : 픽셀값이 문턱값보다 크면 0, 아니면 픽셀값을 할당
In [5]:
# 128 보다 작으면 검정색(0), 크면 흰색(255)로 변환
# 반환 : 기준값과 변환된 이미지
_, th_img = cv2.threshold(img_gray, 128,255, cv2.THRESH_BINARY)
plt.imshow(th_img, cmap="gray")
plt.xticks([])
plt.yticks([])
plt.show()
In [6]:
# 실습
- threshold_value는 영상의 히스토그램에서 픽셀값들을 구분할 수 있는 값을 설정
- 예를들어 아래와 같이 픽셀값들이 100과 150에 몰려 있으므로 130정도가 적당
실습문제 ○ threshold() 함수를 이용하여 다른 이미지를 아래와 같이 변환해보자. |
임계값 결정하기 1 : OTSU 알고리즘
- 이진 이미지를 만들때 가장 중요한 요소 : 임계값 설정
- OTSU의 이진화 알고리즘
- 임계값을 임의로 정하고 픽셀을 두 분류로 나눔
- 두 분류의 명암 분포를 구하는 작업을 반복
- 두 분류의 명암 분포가 가장 균일할 때의 임계값을 선택
- OTSU의 이진화 알고리즘 적용하기
- 임계값을 -1로하고 옵션을 THRESH_OTSU로 설정하여 이진화
- 단점 : 모든 경우의 수를 조사해야 하므로 속도가 느림
In [7]:
# th : otsu로 결정된 threshold_value 값
th, th_img = cv2.threshold(img_gray, -1, 255,
cv2.THRESH_BINARY | cv2.THRESH_OTSU)
plt.imshow(th_img, cmap="gray")
plt.title(th)
plt.xticks([])
plt.yticks([])
plt.show()
임계값 결정하기 2 : 적응형 thresholding
- 전체 이미지를 이용하면 일정하지 않는 조명, 배경색이 여러개인 경우 하나의 임계값으로 선명한 이진 이미지를 만들기 어려움
- 적응형 thresholding
- 이미지를 여러 영역으로 나눔
- 해당 영역의 픽셀 값만 활용하여 임계값을 계산
- 각 영역별로 이진화를 진행
- </td></tr>
- cv2.adaptiveThreshold(img, value, method, type_flag, block_size, C)
- img : 입력영상
- value : 임계값을 만족하는 픽셀에 적용할 값
- method : 임계값 결정 방법
- cv2.ADAPTIVE_THRESH_MEAN_C : 이웃 픽셀의 평균으로 결정
- cv2.ADAPTIVE_THRESH_GAUSSIAN_C : 가우시안 분포에 따른 가중치의 합으로 결정
- type_flag : 스레시홀딩 적용 방법 (cv2.threshod()와 동일)
- block_size : 영역으로 나눌 블록의 크기(n x n), 홀수
- C : 계산된 임계값 결과에서 가감할 상수(음수 가능)
In [8]:
block_size = 9
c = 5
th_img1 = cv2.adaptiveThreshold(img_gray, 255,
cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY, block_size, c)
th_img2 = cv2.adaptiveThreshold(img_gray, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, block_size, c)
plt.figure(figsize=(8, 8))
plt.subplot(1, 2, 1)
plt.title("mean")
plt.imshow(th_img1, cmap="gray")
plt.xticks([])
plt.yticks([])
plt.subplot(1, 2, 2)
plt.title("gaussian")
plt.imshow(th_img2, cmap="gray")
plt.xticks([])
plt.yticks([])
Out[8]:
([], [])
- 실행 결과
- THRESH_OTSU : 분류가 잘 되지 않음
- ADAPTIVE_THRESH_MEAN_C : 선명하지만 잡음이 많음
- ADAPTIVE_THRESH_GAUSSIAN_C : 잡음은 적지만 선명도가 떨어짐
요약 |
○ 칼라이미지를 gray 이미지로 변환하는 방법 - imread() 함수로 직접 변환하는 방법 - 칼라이미지로 읽은 후에 cvtColor() 함수로 변환하는 방법 ○ gray 이미지를 binary로 변환하는 방법 - threshold() 함수를 사용하는 방법 - OTSU 이진화 알고리즘을 사용하는 방법 - adaptiveThreshold() 함수를 사용하는 방법 |
'Study > Python' 카테고리의 다른 글
[Python] OpenCV - 4 Flask (0) | 2023.10.24 |
---|---|
[OpenCV] - 3 동영상 로드 및 저장 (1) | 2023.10.23 |
[Python] OpenCV - 1 이미지 로드 및 저장 (1) | 2023.10.19 |
[Python] Train Data 실습 (0) | 2023.10.18 |
[Python] Numpy 배열 (1) | 2023.10.17 |