회원 로그인
|
OpenCV 10-3. 이미지 Thresholding - Otsu's Binarization
https://blog.naver.com/samsjang OpenCV의 강좌를 공부 차원에서 재정리한 것입니다. |
Otsu's Binarization
014-1, 014-2에서 정해진 임의값을 사용하였는데, 이런 문턱값을 어떻게 얻을 수 있나?(시행 착오?)
만약 이미지 히스토그램이 두개의 봉우리를 가지는 bimodal 이미지라고 하면,
이 이미지에 대한 문턱값으로 두 봉우리 사이의 값을 취하면 가장 좋은 결과를 얻게 된다.
- Otsu Binarization은 이미지 히스토그램을 분석한 후 중간값을 취하여 thresholding 한다.
- Thresholding과 blur 필터를 활용하면 이미지 노이즈 제거에 효율적으로 적용할 수 있다.
이미지 경로가 상대 경로이면 아래와 같이 오류 - 절대 경로로 변경하면 없어지지만 다른 오류(두번째 오류)
Traceback (most recent call last): File "소스 경로/opencv_014-3.py", line 71, in File "소스 경로/opencv_014-3.py", line 59, in thresholding plt.subplot(3, 3, i*3+1), plt.imshow(images[i*3], 'gray') File "파이썬 경로\lib\site-packages\matplotlib\pyplot.py", line 2683, in imshow None else {}), **kwargs) File "파이썬 경로\lib\site-packages\matplotlib\__init__.py", line 1601, in inner return func(ax, *map(sanitize_sequence, args), **kwargs) File "파이썬 경로\lib\site-packages\matplotlib\cbook\deprecation.py", line 369, in wrapper return func(*args, **kwargs) File "파이썬 경로\lib\site-packages\matplotlib\cbook\deprecation.py", line 369, in wrapper return func(*args, **kwargs) File "파이썬 경로\lib\site-packages\matplotlib\axes\_axes.py", line 5671, in imshow im.set_data(X) File "파이썬 경로\lib\site-packages\matplotlib\image.py", line 690, in set_data .format(self._A.shape)) TypeError: Invalid shape () for image data |
위 오류 해결하면 아래 오류 - 이미지가 단일 채널이 아닌 다중 채널이여서? 파이썬 경로/python.exe 소스 경로/opencv_014-3.py Traceback (most recent call last): File "소스 경로/opencv_014-3.py", line 61, in File "소스 경로/opencv_014-3.py", line 37, in thresholding ret, thr2 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) cv2.error: OpenCV(3.4.2) C:/Miniconda3/conda-bld/opencv-suite_1534379934306/work/modules/imgproc/src/thresh.cpp:1406: error: (-215:Assertion failed) src.type() == (((0) & ((1 << 3) - 1)) + (((1)-1) << 3)) in function 'cv::threshold' https://stackoverflow.com/questions/50631195/getting-an-error-opencv3-4-1-c-projects-opencv-python-opencv-modules-imgproc/50639075 |
# -*- coding: utf-8 -*- # opencv_014-3.py # https://blog.naver.com/samsjang/220504782549 # 이미지 Thresholding import numpy as np import cv2 import matplotlib.pyplot as plt def thresholding(): img = cv2.imread('images/image-14-3.jpg') #, cv2.IMREAD_GRAYSCALE) #img = cv2.imread('D:/_cloud/owncloud/rnd/programming/python/opencv/images/image-14-3.jpg') # 채널 확인 # image-14-3.jpg는 (398, 398, 3) 출력으로, (height, width, 3) 단일 채널이 아니다. print('befor : ', img.shape) img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # BGR을 gray로 변환 print('after : ', img.shape) # 이미지 유형이 플로팅되지 않는지 확인, 출력은 uint8 print('befor : ', img.dtype) img = img.astype('uint8') # 플로팅 print('after : ', img.dtype) #img = np.asarray(img, dtype=np.uint8) """ if img.empty(): print('image was not read!') return """ # 전역 thresholding 적용 ret, thr1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) # Otsu 바이너리제이션 # Otsu Binarization을 적용하는 함수는 없고, cv2.threshold() 함수에 cv2.THRESH_OTSU 플래그 값을 # thresholding 플래그에 더하고 문턱값으로 0을 전달해주면 된다. # 이렇게 하면 cv2.threshold() 함수는 적절한 문턱값을 계산 후 이를 적용한 결과를 리턴한다. ret, thr2 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) # 위 코드가 오류 시 여러 플래그를 결합하여 사용할 때 + 보단 | 사용 # 가우시안 블러 적용 후 Otsu 바이너리제이션 blur = cv2.GaussianBlur(img, (5, 5), 0) ret, thr3 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) titles = ['Original noisy', 'Histogram', 'G-Thresholding', 'Original noisy', 'Histogram', 'Otsu Thresholding', 'Gaussian-filtered', 'Histogram', 'Otsu Thresholding'] images = [img, 0, thr1, img, 0, thr2, blur, 0, thr3] for i in range(3): # 결과를 출력하기 위해 matplotlib 사용 plt.subplot(3, 3, i*3+1), plt.imshow(images[i*3], 'gray') plt.title(titles[i*3]), plt.xticks([]), plt.yticks([]) # ravel() https://rfriend.tistory.com/349 plt.subplot(3, 3, i*3+2), plt.hist(images[i*3].ravel(), 256) plt.title(titles[i*3]), plt.xticks([]), plt.yticks([]) plt.subplot(3, 3, i*3+3), plt.imshow(images[i*3+2], 'gray') plt.title(titles[i*3+2]), plt.xticks([]), plt.yticks([]) plt.show() thresholding()
결과의 히스토그램 이미지를 보면, Gaussian blur를 적용하면, 확실한 봉우리를 만들고, 여기에 Otsu 알고리즘을 적용하여 문턱값을 구한 후 thresholding을 적용하면, 보다 나은 노이즈 제거된 것을 알 수 있다.
댓글 0개
| 엮인글 0개
285개(1/15페이지)
번호 | 제목 | 글쓴이 | 조회 | 날짜 |
---|---|---|---|---|
285 | [Python] 동적 import - 모듈을 변수로 받아오기 | 푸딩뱃살 | 405 | 2022.10.27 10:45 |
284 | [Python] 파이썬 3.7.7과 3.9.7의 os.path.expanduser() 차이 | 푸딩뱃살 | 440 | 2022.08.18 12:22 |
283 | [Python] error: Microsoft Visual C++ 9.0 is required. | 푸딩뱃살 | 659 | 2022.08.03 13:35 |
282 | [Python] pyscript | 푸딩뱃살 | 434 | 2022.06.09 11:21 |
281 | [Python] float is / float not is | 푸딩뱃살 | 583 | 2022.03.02 15:03 |
280 | [Python] 이터널 문자열 f | 푸딩뱃살 | 811 | 2022.01.27 16:35 |
279 | [Python] is와 ==의 차이 | 푸딩뱃살 | 475 | 2021.11.25 15:54 |
278 |
[Python] Error: ImportError: file |
푸딩뱃살 | 891 | 2021.11.16 11:24 |
277 | [Python] 파이썬 디컴파일 - uncompyle6 | 푸딩뱃살 | 751 | 2021.11.10 14:46 |
276 | [Python] 파이썬 확장자 설명 | 푸딩뱃살 | 538 | 2021.11.03 14:38 |
275 | [참고] 웹 fbx 뷰어 | 푸딩뱃살 | 457 | 2021.10.19 15:46 |
274 | [Python] enumerate() | 푸딩뱃살 | 487 | 2021.10.13 14:44 |
273 | [Python] 아나콘다에서 가상 환경 | 푸딩뱃살 | 696 | 2020.11.21 00:26 |
272 | [Python] pip로 설치 때 퍼미션 에러 | 푸딩뱃살 | 1247 | 2020.06.06 17:13 |
>> | [Python] OpenCV 10-3. 이미지 Thresholding - Otsu's Binarizatio | 푸딩뱃살 | 659 | 2020.06.05 14:01 |
270 | [Python] OpenCV 10-2. 이미지 Thresholding - Adaptive Threshold | 푸딩뱃살 | 678 | 2020.06.05 13:58 |
269 | [Python] OpenCV 10-1. 이미지 Thresholding | 푸딩뱃살 | 569 | 2020.06.05 13:56 |
268 | [Python] OpenCV 9-2. 색 추적 | 푸딩뱃살 | 745 | 2020.06.02 23:29 |
267 | [Python] OpenCV 9-1. 색공간 바꾸기 | 푸딩뱃살 | 630 | 2020.06.02 23:27 |
266 | [Python] OpenCV 8-3. 이미지 비트 연산 | 푸딩뱃살 | 512 | 2020.06.02 23:21 |