이번 포스팅은 제가 OpenCV를 사용하면서 cv2.imread에서 type을 gray로 주는 것과
cv2.cvtColor에서 cv2.COLOR_BGR2GRAY를 주어 grayscale을 만드는 이미지의 차이를 알기 위해 정리해보았습니다.
목표
1) imread(img, 0)와 cvtColor(img, cv2.COLOR_BGR2GRAY)의 픽셀 차이 확인
2) 연산 처리 속도 차이 확인
실험
- OpenCV를 사용하다 보면 grayscale을 많이 사용합니다. 노이즈를 없애고 연산 속도를 올리면서 정확도를 향상하기 위함인데 imread(img, 0)으로 받아오는 grayscale과 cvtColor(img, cv2.COLOR_BGR2GRAY)로 얻는 grayscale의 차이를 확인하기 위해 여러 가지로 해보았습니다.
코드)
import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('./images/lena.jpg')
gray1 = cv2.imread('./images/lena.jpg', 0)
gray2 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
diff = cv2.subtract(gray1, gray2)
_, th = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
images = [gray1, gray2, th]
titles = ['imread_gray',
'cvtColor_gray',
'sub_threshold']
for i in range(3):
plt.subplot(1, 3, i+1)
plt.imshow(images[i], cmap = 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
결과)
- imread의 처리 속도
- cvtColor의 처리 속도
- 결과를 보시면 각각 함수의 처리속도의 차이는 크게 없지만 grayscale의 픽셀 차이가 발생한 것을 볼 수 있었습니다.
미세한 차이가 발생했는데 결과값에 큰 영향을 주진 않지만 정밀한 작업을 요구하는 모델에서는 원하지 않는 결과 값이 나올 것 같습니다.
결론
- 종합해보면 연산 속도에서는 큰 차이가 발생하지 않지만 픽셀 값이 조금 다른 것을 확인할 수 있었다.
- grayscale을 만드는 함수라고 해서 다 같은 픽셀 값을 가지고 있는 것은 아니다!
추가 내용(2023-11-10) : 어떤 함수가 정교한 그레이스케일 이미지를 만드는가?
- 어떤 분이 댓글로 남겨주셔서 추가 내용을 작성하였습니다.
우선 정리하자면 그레이스케일 변환의 정교함에 대해 말하자면, 'cv2.cvtColor' 함수를 사용하는 방법이 더 정교한 결과를 가져올 수 있습니다.
'cv2.cvtColor' 함수를 사용하면 이미지를 다양한 색공간으로 변환할 수 있습니다. 특히 BGR에서 그레이스케일로 변환할 때, 이 함수는 각 색상 채널에 대해 다음과 같은 가중치를 적용합니다.
gray = 0.299Red + 0.587Green + 0.114*Blue
이는 인간의 시각 시스템이 녹색에 가장 민감하고, 빨간색에는 중간 정도로, 파란색에는 가장 덜 민감하다는 사실을 반영한 것입니다. 따라서 이 방법은 인간의 시각에 가까운 그레이스케일 이미지를 생성할 수 있습니다.
반면에, 'cv2.imread' 함수를 사용하는 방법은 이러한 가중치를 적용하지 않습니다. 이 함수는 이미지를 불러올 때 그레이스케일로 변환하지만, 각 색상 채널에 동일한 가중치를 적용합니다. 이 방법은 처리 속도는 빠를 수 있지만, 인간의 시각을 반영하지 않는다는 점에서 'cv2.cvtColor' 방법보다 덜 정교하다고 볼 수 있습니다.
따라서 더 정교한 그레이스케일 변환을 원한다면, 'cv2.cvtColor' 함수를 사용하는 것이 좋습니다.
혹시나 틀린 점이나 질문이 있으시면 댓글로 남겨주세요!
감사합니다 :)
'영상처리' 카테고리의 다른 글
Python - OpenCV (13) : SVM(Support Vector Machines) (0) | 2021.07.20 |
---|---|
Python - OpenCV (12) : Segmentation with Watershed (0) | 2021.07.19 |
Python - OpenCV (10) : Otsu's Binarization (0) | 2021.07.15 |
Python - OpenCV (9) : Image Thresholding (0) | 2021.07.14 |
Python - OpenCV (8) : k-means Clustering (0) | 2021.07.13 |