machine learning, image

python opencv 기본예제.

qkqhxla1 2015. 1. 18. 16:45

다운로드 : http://docs.opencv.org/trunk/doc/py_tutorials/py_setup/py_setup_in_windows/py_setup_in_windows.html


공식 튜토리얼 : https://opencv-python-tutroals.readthedocs.org/en/latest/


다운로드 사이트의 참조할 페이지 : http://docs.opencv.org/trunk/doc/py_tutorials/py_ml/py_knn/py_knn_opencv/py_knn_opencv.html


http://stackoverflow.com/questions/9413216/simple-digit-recognition-ocr-in-opencv-python


에서 가져온 예제코드. 사진파일에서 숫자를 인식하는 예제인데 예전에 소개했던 pytesser보다


더 조직적으로 잘 인식하는거 같아서 받았다. 


#-*- coding: cp949 -*-
import sys

import numpy as np
import cv2

im = cv2.imread('digit.png')
im3 = im.copy()

gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(5,5),0)
thresh = cv2.adaptiveThreshold(blur,255,1,1,11,2)

#################      Now finding Contours         ###################

contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

samples =  np.empty((0,100))
responses = []
keys = [i for i in range(48,58)]

for cnt in contours:
    if cv2.contourArea(cnt)>50:
        [x,y,w,h] = cv2.boundingRect(cnt)

        if  h>28:
            cv2.rectangle(im,(x,y),(x+w,y+h),(0,0,255),2)
            roi = thresh[y:y+h,x:x+w]
            roismall = cv2.resize(roi,(10,10))
            cv2.imshow('norm',im)
            key = cv2.waitKey(0)

            if key == 27:  # (escape to quit)
                sys.exit()
            elif key in keys:
                responses.append(int(chr(key)))
                sample = roismall.reshape((1,100))
                samples = np.append(samples,sample,0)

responses = np.array(responses,np.float32)
responses = responses.reshape((responses.size,1))
print "training complete"

np.savetxt('generalsamples.data',samples)
np.savetxt('generalresponses.data',responses)


digit.png



위의 opencv와 관련된거 다 설치 후 위의 소스를 복붙한다.


소스를 실행하면 빨간 사각형이 생기며 멈춰있는데 빨간 사각형 내부의 숫자가 어떤 숫자인지


숫자버튼을 누른다. (끝까지 전부 다 함.) 이 과정은 해당 크기에서 이 숫자가 어떤 숫자라는걸


opencv에게 알려주는 트레이닝 과정이다. 작성자는 트레이닝할 숫자 갯수가 적다고 하지만


동일한 글자크기의 동일한 폰트라면 저정도만 해도 100%인식한다. 



아마 완료하고 나면 generalsamples.data라는 파일과 generalresponse.data 라는 파일 두개가


생겼을 것이다. 여기에 각각 숫자들의 db가 저장되는것 같다. 위의 소스의 중간에


roi라는 변수가 있는데 이 변수를 출력해보면 대충 opencv가 어떻게 숫자를 저장하는지 추측이


가능할 것 같다. 아래는 4라는 숫자를 인식했을때의 출력한 roi값이다.



2. 아래 소스와 아래의 pi.png를 받아서 파이썬 폴더에 넣고 실행시키면 제대로 인식하는걸 볼 수 있다.


import cv2
import numpy as np

#######   training part    ############### 
samples = np.loadtxt('generalsamples.data',np.float32)
responses = np.loadtxt('generalresponses.data',np.float32)
responses = responses.reshape((responses.size,1))

model = cv2.KNearest()
model.train(samples,responses)

############################# testing part  #########################

im = cv2.imread('pi.png')
out = np.zeros(im.shape,np.uint8)
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(gray,255,1,1,11,2)

contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

for cnt in contours:
    if cv2.contourArea(cnt)>50:
        [x,y,w,h] = cv2.boundingRect(cnt)
        if  h>28:
            cv2.rectangle(im,(x,y),(x+w,y+h),(0,255,0),2)
            roi = thresh[y:y+h,x:x+w]
            roismall = cv2.resize(roi,(10,10))
            roismall = roismall.reshape((1,100))
            roismall = np.float32(roismall)
            retval, results, neigh_resp, dists = model.find_nearest(roismall, k = 1)
            string = str(int((results[0][0])))
            cv2.putText(out,string,(x,y+h),0,1,(0,255,0))

cv2.imshow('im',im)
cv2.imshow('out',out)
cv2.waitKey(0)







인식한 숫자. 잘 인식한다.