Computer Vision/opencv(python)

[51] 4) 템플릿 매칭 (2): 인쇄체 숫자 인식

jwjwvison 2021. 3. 24. 11:14
  • 인식(Recognition) 이란?
    • classifying a detected object into differernt categories
    • 여러 개의 클래스 중에서 가장 유사한 클래스를 선택

 

  • 숫자 템플릿 영상 생성

 

  • 인쇄체 숫자 인식 방법

 

  • 인쇄체 숫자 인식 예제 실행 결과
import sys
import cv2
import numpy as np

def load_digits():
    img_digits=[]

    for i in range(10):
        filename='./digits/digit{}.bmp'.format(i)
        img_digits.append(cv2.imread(filename,cv2.IMREAD_GRAYSCALE))

        if img_digits[i] is None:
            return None

    return img_digits

def find_digit(img,img_digits):
    max_idx=-1
    max_ccoeff=-1

    #최대 NCC 찾기
    for i in range(10):
        img=cv2.resize(img,(100,150))
        res=cv2.matchTemplate(img,img_digits[i],cv2.TM_CCOEFF_NORMED)  # 1x1 행렬

        if res[0,0]>max_ccoeff:
            max_idx=i
            max_ccoeff=res[0,0]

    return max_idx

def main():
    #입력 영상 불러오기
    src=cv2.imread('digits_print.bmp')
    
    if src is None:
        print('Image load failed!')
        return

    #100x150 숫자 영상 불러오기
    img_digits=load_digits()  #list of ndarray

    if img_digits is None:
        print('Digit image laod failed!')
        return
    
    # 입력 영상 이진화 & 레이블링
    src_gray=cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)
    _,src_bin=cv2.threshold(src_gray,0,255,cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
    cnt,_,stats,_=cv2.connectedComponentsWithStats(src_bin)

    # 숫자 인식 결과 영상 생성
    dst=src.copy()
    for i in range(1,cnt):           #0은 배경이기 때문에
        (x,y,w,h,s)=stats[i]

        if s<1000:
            continue
        
        # 가장 유사한 숫자 이미지를 선택
        digit = find_digit(src_gray[y:y+h, x:x+w], img_digits)
        cv2.rectangle(dst, (x, y, w, h), (0, 255, 255))
        cv2.putText(dst, str(digit), (x, y -10), cv2.FONT_HERSHEY_SIMPLEX,
                    1, (0, 255, 255), 2, cv2.LINE_AA)

    cv2.imshow('dst', dst)
    cv2.waitKey()
    cv2.destroyAllWindows()


if __name__ == '__main__':
    main()