machineLearning을 통해 이미지에 있는 글씨 확인하기

2018. 4. 18. 20:44Python-이론/python-인공지능

이미지에 있는 글씨 확인하기



이미지에 있는 글자를 인식하는 교육을 시켜서 테스트 이미지가 들어갔을 때 얼마의 정확히 파악할지 알아보겠습니다. 우선 데이터 다운로드 사이트 가서 4개의 파일을 다운받아서 압축을 풀어 저장하는 소스를 작성하겠습니다.

import os.path, gzip, os
import urllib.request as req
filename = ["train-images-idx3-ubyte.gz","train-labels-idx1-ubyte.gz","t10k-images-idx3-ubyte.gz","t10k-labels-idx1-ubyte.gz"]

baseurl = 'http://yann.lecun.com/exdb/mnist/'

savepath= './trainImages'
#폴더가 없다면 폴더를 생성하겠다
if not os.path.exists(savepath): os.mkdir(savepath)
#url은 다운 받을 url , loc는 저장될 위치
for f in filename:
    url = baseurl + f
    loc = savepath+'/'+f
    if not os.path.exists(loc): 
        req.urlentrieve(url,loc)

for f in filename:
#파일 이름
    savefile = f.replace(".gz","")
#압축해제
    with gzip.open(savepath+'/'+f,'rb') as fp:
        body = fp.read()
        with open(savepath+"/"+savefile,'wb') as w:
             w.write(body)




여기서 다운 받은 파일은 우리가 바로 이용하기에 불편하니깐 csv파일로 변환시켜서 이용해보겠다. 여기서 다운 받은 이미지는 말그대로 이미지 파일이고 lable은 이미지에 적힌 숫자를 뜻한다.



import struct 

import struct

def load_csv(fname,maxdata):
#데이터
    img_name = "./trainImages/"+fname + "-images-idx3-ubyte"
#데이터의 결과
    lable_name = "./trainImages/"+fname +"-labels-idx1-ubyte"
#데이터와 결과를 바이트로 읽는다. 
    img_file = open(img_name,'rb')
    lable_file = open(lable_name,'rb')
#쓸 csv파일 오픈
    csvf_file = open(fname+".csv",'w')
#정수로 8btye씩 2개에 1바이트
    mag, img_length = struct.unpack(">II",img_file.read(8))
    mag, lable_length = struct.unpack(">II",lable_file.read(8))
#이미지의 가로세로 픽셀
    rows, cols = struct.unpack(">II",img_file.read(8))
    pixels = rows * cols
    for idx in range(img_length):
        if idx > maxdata : break
#char형으로 읽음 제일 첫값 -> 레이블
        label = struct.unpack("B",lable_file.read(1))[0]
#이미지의 데이터 값
        bdata = img_file.read(pixels)
#문자형으로 체인지
        sdata = list (map(lambda a :str(a),bdata))
        csvf_file.write(str(label)+',')
        csvf_file.write(','.join(sdata)+"\n")
    lable_file.close()
    img_file.close()
    csvf_file.close()
load_csv('t10k',3000)
load_csv('train',500)


이젠 머신러닝을 실행해보겠다

from sklearn import svm, metrics

def load_csv(filename):
    lables = []
    images = []
    with open(filename , 'r') as f:
        for line in f:
#csv데이터 ,로 나누기
            cols = line.split(',')
            if len(cols) < 2 : continue
#리스트 중 첫번째 인자 (라벨) 값만 가져온다
            lables.append(int(cols.pop(0)))
            vals = list(map(lambda a:int(a)/256,cols))
            images.append(vals)
    return {"label":lables,"images":images}

clf = svm.SVC()

data = load_csv("./trainImages/train.csv")
test = load_csv("./trainImages/t10k.csv")

clf.fit (data["images"],data["label"])
pre = clf.predict(test["images"])
score = metrics.accuracy_score(pre,test["label"])
cl_report = metrics.classification_report(test["label"],pre)

print('정답률',score)
print('리포트',cl_report)




결과를 보면 데이터를 1000개만 써서 정확도가 68%밖에 안나옴을 알 수 있다. mnist.py의 호출할때 숫자를 더많이 해주면 더 좋은 결과를 얻을 수 있다.