λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

AI/Computer Vision

[Computer Vision] μ˜μƒμ˜ 이진화와 λͺ¨ν΄λ‘œμ§€

728x90
λ°˜μ‘ν˜•
πŸ‘€ λ³Έ μ˜ˆμ œλŠ” Window10의 VSCode, Python3.11.0둜 μž‘μ„±λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

 

이진화(Binarization)

μ˜μƒμ˜ 이진화(Binarization)λŠ” μ˜μƒμ˜ 각 픽셀을 두 개의 λΆ€λ₯˜λ‘œ λ‚˜λˆ„λŠ” μž‘μ—…μ΄λ‹€.

 

이λ₯Ό 톡해 μ˜μƒμ˜ μ£Όμš” 객체 μ˜μ—­κ³Ό λ°°κ²½ μ˜μ—­μœΌλ‘œ λ‚˜λˆ„κ±°λ‚˜ λ˜λŠ” μ˜μƒμ—μ„œ μ€‘μš”λ„κ°€ 높은 관심 μ˜μ—­κ³Ό 그렇지 μ•Šμ€ 비관심 μ˜μ—­μœΌλ‘œ κ΅¬λΆ„ν•˜λŠ” μš©λ„λ‘œ 이진화가 μ‚¬μš©λ  수 μžˆλ‹€.

 

이진화가 μ§„ν–‰λ˜λ©΄ μ˜μƒμ˜ 픽셀값은 0λ˜λŠ” 255둜 κ΅¬μ„±λ˜λ©° 흰색 λ˜λŠ” 검은색 ν”½μ…€λ‘œλ§Œ κ΅¬μ„±λœλ‹€.]

 

이진화λ₯Ό ν•˜λŠ” 방법은 νŠΉμ •κ°’μ„ κΈ°μ€€μœΌλ‘œ 크면 255, μž‘μ€ 경우 0으둜 μ„€μ •ν•œλ‹€.

import cv2

if __name__ == "__main__":
    im = cv2.imread("test.png")
    shape = (int(im.shape[1] * 0.5), int(im.shape[0] * 0.5))
    im = cv2.resize(im,shape)
    cv2.imshow("Origin",im)
    gim = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
    # κ³ μ • μž„κ³„κ°’
    _, b_fix = cv2.threshold(gim,120,255,cv2.THRESH_BINARY)
    cv2.imshow("Fix Binary",b_fix)
    # Otsuλ₯Ό μ‚¬μš©ν•˜μ—¬ μžλ™μœΌλ‘œ 졜적의 μž„κ³„κ°’ 계싼
    _, b_otsu = cv2.threshold(gim,0,255,cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    cv2.imshow("Otsu Binary",b_otsu)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

 

 

ThresholdType μ—΄κ±°ν˜• μƒμˆ˜ μ„€λͺ…
cv2.THRESH_BINARY 주어진 μž„κ³„κ°’λ³΄λ‹€ 큰 픽셀은 μ΅œλŒ€κ°’μœΌλ‘œ μ„€μ •ν•˜κ³ , μž‘μ€ 픽셀은 0으둜 μ„€μ •ν•œλ‹€. (흑백 이진화)
cv2.THRESH_BINARY_INV THRESH_BINARY와 λ°˜λŒ€λ‘œ λ™μž‘ν•©λ‹ˆλ‹€. 주어진 μž„κ³„κ°’λ³΄λ‹€ 큰 픽셀은 0으둜, μž‘μ€ 픽셀은 μ΅œλŒ€κ°’μœΌλ‘œ μ„€μ •ν•œλ‹€.
cv2.THRESH_TRUNC 주어진 μž„κ³„κ°’λ³΄λ‹€ 큰 픽셀은 μž„κ³„κ°’μœΌλ‘œ μ„€μ •ν•˜κ³ , μž‘μ€ 픽셀은 κ·ΈλŒ€λ‘œ μœ μ§€ν•œλ‹€.
cv2.THRESH_TOZERO 주어진 μž„κ³„κ°’λ³΄λ‹€ 큰 픽셀은 κ·ΈλŒ€λ‘œ μœ μ§€ν•˜κ³ , μž‘μ€ 픽셀은 0으둜 μ„€μ •ν•œλ‹€.
cv2.THRESH_TOZERO_INV THRESH_TOZERO와 λ°˜λŒ€λ‘œ λ™μž‘ν•©λ‹ˆλ‹€. 주어진 μž„κ³„κ°’λ³΄λ‹€ 큰 픽셀은 0으둜, μž‘μ€ 픽셀은 κ·ΈλŒ€λ‘œ μœ μ§€ν•œλ‹€.
cv2.THRESH_OTSU μžλ™μœΌλ‘œ 졜적의 μž„κ³„κ°’μ„ κ²°μ •ν•˜λŠ” Otsu의 방법을 μ‚¬μš©ν•œλ‹€. 이 방법은 μ΄λ―Έμ§€μ˜ νžˆμŠ€ν† κ·Έλž¨μ„ λΆ„μ„ν•˜μ—¬ 졜적의 μž„κ³„κ°’μ„ μ°ΎμŠ΅λ‹ˆλ‹€. λ‹€λ₯Έ μž„κ³„κ°’ 방식과 ν•¨κ»˜ μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.
cv2.THRESH_TRIANGLE 또 λ‹€λ₯Έ μžλ™ μž„κ³„κ°’ κ²°μ • λ°©λ²•μœΌλ‘œ, μ‚Όκ°ν˜• 방법을 μ‚¬μš©ν•˜μ—¬ 졜적의 μž„κ³„κ°’μ„ μ°ΎλŠ”λ‹€.

 

λΆˆκ· μΌν•œ μ‘°λͺ…ν™˜κ²½μ˜ 경우 ν•˜λ‚˜μ˜ μž„κ³„κ°’μœΌλ‘œ 객체와 배경을 μ œλŒ€λ‘œ κ΅¬λΆ„ν•˜κΈ° μ–΄λ ΅κΈ° λ•Œλ¬Έμ— 각 ν”½μ…€λ§ˆλ‹€ μ„œλ‘œ λ‹€λ₯Έ μž„κ³„κ°’μ„ μ‚¬μš©ν•˜λŠ” μ μ‘ν˜• 이진화(Adaptive Binarization) 기법을 μ‚¬μš©ν•˜λŠ” 것이 νš¨κ³Όμ μ΄λ‹€.

 

import cv2

if __name__ == "__main__":
    im = cv2.imread("test.png")
    shape = (int(im.shape[1] * 0.5), int(im.shape[0] * 0.5))
    im = cv2.resize(im,shape)
    cv2.imshow("Origin",im)
    gim = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
    # μ μ‘ν˜• 이진화
    adp = cv2.adaptiveThreshold(gim,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
    cv2.imshow("AdaptiveThreshold",adp)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()

 

 

 

λͺ¨ν΄λ‘œμ§€(Morphology)

μ˜μƒ λ‚΄λΆ€ 객체의 ν˜•νƒœμ˜ ꡬ쑰λ₯Ό λΆ„μ„ν•˜κ³  μ²˜λ¦¬ν•˜λŠ” 기법이닀.

 

주둜 μ΄μ§„ν™”λœ μ˜μƒμ—μ„œ 객체의 λͺ¨μ–‘을 λ³€ν˜•ν•˜λŠ” μš©λ„λ‘œ μ‚¬μš©λœλ‹€.

 

기본이 λ˜λŠ” 연산은 침식(erosion)κ³Ό 팽창(dilation)이닀.

 

λͺ¨ν΄λ‘œμ§€ 연산을 μœ„ν•œ λ‹€μ–‘ν•œ ꡬ쑰가 μžˆλ‹€.

 

 

μ΄λŸ¬ν•œ μ—°μ‚° ꡬ쑰λ₯Ό 톡해 침식과 팽창 연산을 ν•œλ‹€.

import cv2

if __name__ == "__main__":
    im = cv2.imread("test.png")
    shape = (int(im.shape[1] * 0.5), int(im.shape[0] * 0.5))
    im = cv2.resize(im,shape)
    cv2.imshow("Origin",im)
    gim = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
    
    # 침식
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5)) # (5x5)
    eroded = cv2.erode(gim,kernel=kernel,iterations=1)
    cv2.imshow("Eroded",eroded)
    # 팽창
    dilated = cv2.dilate(gim,kernel=kernel,iterations=1)
    cv2.imshow("Dilated",dilated)

    cv2.waitKey(0)
    cv2.destroyAllWindows()

 

728x90
λ°˜μ‘ν˜•