C-01 手寫數字識別

更新、更全的《機器學習》的更新網站,更有python、go、數據結構與算法、爬蟲、人工智能教學等着你:http://www.javashuo.com/article/p-vozphyqp-cm.htmlpython

手寫數字識別應用程序

1、導入模塊

import os
import pylab
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
from sklearn.svm import SVC
%matplotlib inline

2、圖像轉向量

def img2vector(filename):
    """將32*32的二進制圖像轉換爲1*1024向量"""
    # 構造一個一行有1024個元素的即 1*1024 的零向量
    return_vect = np.zeros((1, 1024))

    with open(filename, 'r', encoding='utf-8') as fr:
        # 讀取文件的每一行的全部元素
        for i in range(32):
            line_str = fr.readline()
            # 把文件每一行的全部元素按照順序寫入構造的 1*1024 的零矩陣
            for j in range(32):
                return_vect[0, 32 * i + j] = int(line_str[j])

        # 返回轉換後的 1*1024 向量
        return return_vect

3、訓練並測試模型

# 手寫數字集另外一種導入方式
# 直接導入不貼近工業

def hand_writing_class_test():
    """手寫數字分類測試"""
    # 對訓練集數據作處理,構造一個 m*1024 的矩陣,m 是訓練集數據的個數
    hw_labels = []
    training_file_list = os.listdir('datasets/digits/trainingDigits')  # type:list
    m = len(training_file_list)
    # 初始化訓練的Mat矩陣,測試集
    training_mat = np.zeros((m, 1024))

    for i in range(m): # 0,1,2,3,4,...,1933
        # 取出文件中包含的數字
        file_name_str = training_file_list[i]  # type:str
        file_str = file_name_str.split('.')[0]
        class_num_str = int(file_str.split('_')[0])
        # 添加標記到hw_labels中
        hw_labels.append(class_num_str)
        # 把該文件中的全部元素構形成 1*1024 的矩陣後存入以前構造的 m*1024 的矩陣中對應的行
        training_mat[i, :] = img2vector(
            'datasets/digits/trainingDigits/{}'.format(file_name_str))


    # 訓練模型
    clf = SVC(C=200, kernel='rbf', gamma='auto')
    clf.fit(training_mat, hw_labels)

    # 返回testDigits目錄下的文件列表
    test_file_list = os.listdir('digits/testDigits')
    # 錯誤檢測計數
    error_count = 0
    # 測試數據的數量
    m_test = len(test_file_list)

    # 對測試集中的單個數據作處理
    for i in range(m_test):
        # 取出文件中包含的數字
        file_name_str = test_file_list[i]
        file_str = file_name_str.split('.')[0]
        class_num_str = int(file_str.split('_')[0])

        # 把該文件中的全部元素構形成一個 1*1024 的矩陣
        vector_under_test = img2vector(
            'digits/testDigits/{}'.format(file_name_str))

        # 對剛剛構造的 1*1024 的矩陣進行分類處理判斷結果
        classifier_result = clf.predict(vector_under_test)
#         print("分類返回結果爲{}\t真實結果爲{}".format(classifier_result, class_num_str))

        # 對判斷錯誤的計數加 1
        if classifier_result != class_num_str:
            error_count += 1

    print("總共錯了{}個數據\n錯誤率爲{:.2f}".format(
        error_count, error_count/m_test * 100))

    return clf
    
clf = hand_writing_class_test()
總共錯了13個數據
錯誤率爲1.37

4、模型轉應用程序

4.1 展現圖片

img = Image.open('img/2.jpg')

plt.imshow(img) 
plt.show()

png

4.2 處理圖片

灰度矩陣圖

def img_binaryzation(img_filename):
    """處理圖片爲文本文件"""

    # 調整圖片的大小爲 32*32px
    img = Image.open(img_filename)
    out = img.resize((32, 32), Image.ANTIALIAS)
    img_filename = 'test.jpg'
    out.save(img_filename)

    # RGB 轉爲二值化圖
    img = Image.open(img_filename)
    lim = img.convert('1')
    lim.save(img_filename)

    img = Image.open(img_filename)

    # 將圖像轉化爲數組並將像素轉換到0-1之間
    img_ndarray = np.asarray(img, dtype='float64') / 256

    # 將圖像的矩陣形式轉化成一位數組保存到 data 中
    data = np.ndarray.flatten(img_ndarray)

    # 將一維數組轉化成矩陣
    a_matrix = np.array(data).reshape(32, 32)

    # 將矩陣保存到 txt 文件中轉化爲二進制0,1存儲
    img_filename_list = img_filename.split('.')  # type:list
    img_filename_list[-1] = 'jpg'
    txt_filename = '.'.join(img_filename_list)
    pylab.savetxt(txt_filename, a_matrix, fmt="%.0f", delimiter='')

    # 把 .txt 文件中的0和1調換
    with open(txt_filename, 'r') as fr:
        data = fr.read()
        data = data.replace('1', '2')
        data = data.replace('0', '1')
        data = data.replace('2', '0')

        with open(txt_filename, 'w') as fw:
            fw.write(data)

    return txt_filename

4.3 預測圖片

def hand_writing_predict(img_filename):
    # 處理圖片爲文本文件
    txt_filename = img_binaryzation(img_filename)

    # 把該文件中的全部元素構形成一個 1*1024 的矩陣
    vector_under_test = img2vector(txt_filename)

    # 對剛剛構造的 1*1024 的矩陣進行分類處理判斷結果
    classifier_result = clf.predict(vector_under_test)

    return classifier_result


print('**結果:{}**'.format(hand_writing_predict('img/2.jpg')))
os.remove('test.jpg')
**結果:[2]**
相關文章
相關標籤/搜索