반응형



threshold 함수와 adaptiveThreshold함수를 사용한 영상 이진화를 다루고 있습니다.



마지막 업데이트 - 2018. 10. 5




다음 OpenCV Python 튜토리얼을 참고하여 강좌를 비정기적로 포스팅하고 있습니다.


https://docs.opencv.org/3.4.3/d6/d00/tutorial_py_root.html






보실때 HD 화질로 해야 합니다.







Simple Thresholding

threshold 함수를 사용한 이진화입니다. 전체 이미지에 하나의 임계값을 적용합니다.



첫번째 아규먼트는 원본 이미지, 두번째 아규먼트는 임계값, 세번째 아규먼트는 임계값 이상일 경우 바꿀 최대값(보통 흰색인 255로 지정)을 지정합니다.

네번째 아규먼트로 THRESH_BINARY를 사용하면 픽셀값이 임계값보다 클 경우 최대값으로 하고 픽셀값이 임계값보다 작은 경우 0(검은색)으로 이진화를 합니다.


ret,img_result1 = cv2.threshold(img_source, 127, 255, cv2.THRESH_BINARY)



THRESH_BINARY를 사용하면 실행 결과 물체가 검은색으로 검출되었습니다.


 




네번째 아규먼트로 THRESH_BINARY_INV를 사용하면 반전된 결과를 내놓습니다.


ret,img_result2 = cv2.threshold(img_source, 127, 255, cv2.THRESH_BINARY_INV)



실행결과 물체가 흰색으로 검출되었습니다.


 




테스트에 사용한 원본 이미지와 전체 소스 코드입니다.



import cv2


img_source = cv2.imread('test6.png',0)

ret,img_result1 = cv2.threshold(img_source, 127, 255, cv2.THRESH_BINARY)
ret,img_result2 = cv2.threshold(img_source, 127, 255, cv2.THRESH_BINARY_INV)



cv2.imshow("SOURCE", img_source)
cv2.imshow("THRESH_BINARY", img_result1)
cv2.imshow("THRESH_BINARY_INV", img_result2)

cv2.waitKey(0)
cv2.destroyAllWindows()




Adaptive Thresholding

adaptiveThreshold 함수를 사용한 이진화입니다. 하나의 이미지에 다수의 조명 상태가 존재하는 경우 적용하면 좋은 결과를 얻을 수 있습니다.


이미지 출처 - https://docs.opencv.org/3.4.3/d7/d4d/tutorial_py_thresholding.html  




앞에서 살펴본 threshold함수를 사용하여 전체 이미지에 단일 임계값인 127을 적용해보면 이진화 결과가 만족스럽지 않습니다.


ret,img_result1 = cv2.threshold(img_source, 127, 255, cv2.THRESH_BINARY)





ADAPTIVE_THRESH_MEAN_C와 함께 adaptiveThreshold 함수를 사용하면 앞에서 검은색으로 검출된 부분의 글씨가 검출됩니다.


첫번째 아규먼트는 원본 이미지, 두번째 아규먼트는 임계값 이상일 경우 픽셀값, 세번째 아규먼트는 적응형 이진화 타입, 네번째 아규먼트는 이진화 타입, 다섯째 아규먼트는 임계값 계산시 함께 볼 주변 픽셀의 범위를 블럭 크기로 지정,  여섯번째 아규먼트는 평균 또는 가중평균에서 뺄 값입니다.


img_result2 = cv2.adaptiveThreshold(img_source, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 21, 5)




ADAPTIVE_THRESH_GAUSSIAN_C와 함께 adaptiveThreshold  함수를 사용해도 좋은 결과를 얻을 수 있습니다.


img_result3 = cv2.adaptiveThreshold(img_source, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 21, 5)





앞서 단일 값 임계값을 적용시에는 좋은 결과를 얻었던 입력 이미지에 adaptiveThreshold 함수를 사용해보면 원하는 결과를 얻을 수 없습니다.

입력으로 사용하는 이미지에 따라, 함수에 사용하는 파라미터 값에 따라 다른 결과를 가져올 수 있기때문에 상황에 따라 맞는 알고리즘을 사용하도록 노력해야 할 듯합니다.





테스트에 사용한 원본 이미지와 전체 소스 코드입니다.

(이미지 출처 - https://blogs.mathworks.com/steve/2016/07/25/adaptive-thresholding-for-binarization/ )


import cv2


img_source = cv2.imread('test7.png', 0)

ret,img_result1 = cv2.threshold(img_source, 127, 255, cv2.THRESH_BINARY)
img_result2 = cv2.adaptiveThreshold(img_source, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 21, 5)
img_result3 = cv2.adaptiveThreshold(img_source, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 21, 5)



cv2.imshow("SOURCE", img_source)
cv2.imshow("THRESH_BINARY", img_result1)
cv2.imshow("ADAPTIVE_THRESH_MEAN_C", img_result2)
cv2.imshow("ADAPTIVE_THRESH_GAUSSIAN_C", img_result3)

cv2.waitKey(0)
cv2.destroyAllWindows()




Otsu’s Binarization

THRESH_OTSU와 함께 threshold함수를 사용한 이진화합니다.  이미지에 대한 히스토그램에서 임계값을 자동으로 계산해줍니다.



전체 이미지에 단일 임계값인 127을 적용해보면 노이즈까지 같이 검출되어 버립니다.


ret,img_result1 = cv2.threshold(img_source, 127, 255, cv2.THRESH_BINARY)





THRESH_OTSU만 적용해도 노이즈까지 그대로 검출됩니다. . 앞에서 임계값을 적어주었던 두번째 아규먼트는 0으로 해야 합니다.


ret, img_result2 = cv2.threshold(img_source, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)




가우시안 필터를 적용하여 노이지를 줄인 후, THRESH_OTSU를 적용해보면 노이즈 없이 물체만 검출됩니다.


img_blur = cv2.GaussianBlur(img_source, (5,5), 0)
ret, img_result3 = cv2.threshold(img_blur, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)





테스트에 사용한 원본 이미지와 전체 소스 코드입니다.



import cv2


img_source = cv2.imread('test10.png', 0)

ret,img_result1 = cv2.threshold(img_source, 127, 255, cv2.THRESH_BINARY)

ret, img_result2 = cv2.threshold(img_source, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

img_blur = cv2.GaussianBlur(img_source, (5,5), 0)
ret, img_result3 = cv2.threshold(img_blur, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)



cv2.imshow("SOURCE", img_source)
cv2.imshow("THRESH_BINARY", img_result1)
cv2.imshow("THRESH_OTSU", img_result2)
cv2.imshow("THRESH_OTSU + Gaussian filtering", img_result3)

cv2.waitKey(0)
cv2.destroyAllWindows()






반응형

문제 발생시 지나치지 마시고 댓글 남겨주시면 가능한 빨리 답장드립니다.

도움이 되셨다면 토스아이디로 후원해주세요.
https://toss.me/momo2024


제가 쓴 책도 한번 검토해보세요 ^^

+ Recent posts