中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python怎么實現識別手寫數字

發布時間:2021-03-23 09:42:10 來源:億速云 閱讀:136 作者:小新 欄目:開發技術

這篇文章給大家分享的是有關python怎么實現識別手寫數字的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

寫在前面

這一段的內容可以說是最難的一部分之一了,因為是識別圖像,所以涉及到的算法會相比之前的來說比較困難,所以我盡量會講得清楚一點。

而且因為在編寫的過程中,把前面的一些邏輯也修改了一些,將其變得更完善了,所以一切以本篇的為準。當然,如果想要直接看代碼,代碼全部放在我的GitHub中,所以這篇文章主要負責講解,如需代碼請自行前往GitHub。

本次大綱

上一次寫到了數據庫的建立,我們能夠實時的將更新的訓練圖片存入CSV文件中。所以這次繼續往下走,該輪到識別圖片的內容了。

首先我們需要從文件夾中提取出需要被識別的圖片test.png,并且把它經過與訓練圖片相同的處理得到1x10000大小的向量。因為兩者之間存在微小的差異,我也不是很想再往源代碼之中增加邏輯了,所以我就直接把增加待識別圖片的函數重新寫一個命名為GetTestPicture,內容與GetTrainPicture類似,只不過少了“增加圖片名稱”這一個部分。

之后我們就可以開始進行正式圖片識別內容了。

主要是計算待識別圖片與所有訓練圖片的距離。當兩個圖片距離越近的時候,說明他們越相似,那么他們很有可能寫的就是同一個數。所以利用這個原理,我們可以找出距離待識別圖像最近的幾個訓練圖片,并輸出他們的數字分別是幾。比如說我想輸出前三個,前三個分別是3,3,9,那就說明這個待識別圖片很有可能是3.

之后還可以對每一個位置加個權重,具體的就放在下一次再講,本節內容已經夠多了。

(第一篇文章之中我說過利用圖片洞數檢測。我嘗試了一下,認為有些不妥,具體原因放在本文末。)

MAIN代碼

所以直接把主要代碼放上來,邏輯相對來說還是比較清晰的

import os
import OperatePicture as OP
import OperateDatabase as OD
import PictureAlgorithm as PA
import csv

##Essential vavriable 基礎變量
#Standard size 標準大小
N = 100
#Gray threshold 灰度閾值
color = 200/255

n = 10

#讀取原CSV文件
reader = list(csv.reader(open('Database.csv', encoding = 'utf-8')))
#清除讀取后的第一個空行
del reader[0]
#讀取num目錄下的所有文件名
fileNames = os.listdir(r"./num/")
#對比fileNames與reader,得到新增的圖片newFileNames
newFileNames = OD.NewFiles(fileNames, reader)
print('New pictures are: ', newFileNames)
#得到newFilesNames對應的矩陣
pic = OP.GetTrainPicture(newFileNames)
#將新增圖片矩陣存入CSV中
OD.SaveToCSV(pic, newFileNames)
#將原數據庫矩陣與新數據庫矩陣合并
pic = OD.Combination(reader, pic)

#得到待識別圖片
testFiles = os.listdir(r"./test/")
testPic = OP.GetTestPicture(testFiles)

#計算每一個待識別圖片的可能分類
result = PA.CalculateResult(testPic, pic)
for item in result:
 for i in range(n):
  print('第'+str(i+1)+'個向量為'+str(item[i+n])+',距離為'+str(item[i]))

相比上一篇文章的內容,本篇文章里只增加了下面的的一段代碼,即得到待識別圖片名稱、得到待識別圖片向量、計算分類。

下面我們將著重講解CalculateResult函數的內容,即識別圖片的算法。

算法內容

算法大致講解

我們在大綱之中已經簡單介紹過了,所以我就直接把復制過來,并且再添加一些內容。

假設我們在二維平面上有兩個點A=(1,1)和B=(5,5),我現在再放一個點C=(2,2),那么請問,C點離哪一個更近?

學過初中數學的都會知道肯定是離A點更近。所以我們換一種說法,我們現在有兩個類A和B,A類中包括了點(1,1),B類中包括了點(5,5),所以對于點(2,2),它可能屬于哪一類?

因為這個點離A類的點更近一點,所以它可能屬于A類。這就是結論。那么對于3維空間,A類是點(1,1,1)和B類是(5,5,5),那么對于點(2,2,2)肯定也是屬于A類。

可以看出,我們這里是將兩個點的距離來作為判斷屬于哪一類的標準。那么對于我們將圖片拉成的1xn維向量,他實際上投影到n維空間上就是一個點,所以我們將訓練向量分成10類,分別代表十個數字,那么被識別數字靠近哪一個類,那說明它有可能屬于這一個類。

那么我們這里可以假設對于被識別向量,列出距離他最近的前十個向量分別屬于哪一類別,然后根據名次加上一個權重,并計算出一個值。該值代表了可能是屬于哪一個類,因此這就是我們得出的最終的一個結果——被識別手寫數字圖片的值。

以上是第一篇文章中的內容,下面我著重講一下數學方面的內容。

考慮到某些地方不能夠輸入數學公式(或不方便輸入),我還是把這一段內容貼成圖片出來。

python怎么實現識別手寫數字

之后直接挑出前幾個離被識別圖片最近的向量數字,基本上這幾個數字就是被識別圖片的數字了。但這樣做未免有些簡單,所以下一篇文章我會再深入一下,這張先講計算距離的內容。

主代碼

下面的代碼中文件夾test用來存放待識別圖片,并通過函數GetTestPicture來得到圖片向量,之后和訓練圖片pic一起放進計算距離的函數CalculateResult中計算每一個待識別向量和其他所有圖片向量的距離。

#得到待識別圖片
testFiles = os.listdir(r"./test/")
testPic = OP.GetTestPicture(testFiles)

#計算每一個待識別圖片的可能分類
result = PA.CalculateResult(testPic, pic)
for item in result:
 for i in range(n):
  print('第'+str(i+1)+'個向量為'+str(item[i+n])+',距離為'+str(item[i]))

函數CalculateResult在文件PictureAlgorithm.py中,這個文件里面包含了兩個函數為CalculateDistance函數和CalculateResult函數,代表識別圖片所用到的算法。

函數CalculateResult

這個函數的邏輯比較簡單,也沒什么好說的,主要的聯系就是這個計算距離的CalculateDistance函數。

def CalculateResult(test, train):
 '''計算待識別圖片test的可能分類'''
 #得到每個圖片的前n相似圖片
 testDis = CalculateDistance(test[:,0:N**2], train[:,0:N**2], train[:,N**2], n)
 #將testDis變成列表
 tt = testDis.tolist()
 #輸出每一個待識別圖片的所有前n個
 for i in tt:
  for j in i:
   print(j)

函數CalculateDistance

函數中我導入了四個參數:被識別向量test,訓練向量train,與訓練向量對應的每個向量對應代表的數字num,想要導出的前n個距離最近的向量。

def CalculateDistance(test, train, num, n):
 '''計算每個圖片前n相似圖片'''
 #前n個放距離,后n個放數字
 dis = np.zeros(2*n*len(test)).reshape(len(test), 2*n)
 for i, item in enumerate(test):
  #計算出每個訓練圖片與該待識別圖片的距離
  itemDis = np.sqrt(np.sum((item-train)**2, axis=1))
  #對距離進行排序,找出前n個
  sortDis = np.sort(itemDis)
  dis[i, 0:n] = sortDis[0:n]
  for j in range(n):
   #找到前幾個在原矩陣中的位置
   maxPoint = list(itemDis).index(sortDis[j])
   #找到num對應位置的數字,存入dis中
   dis[i, j+n] = num[maxPoint]
 return dis

首先建立一個行數為test內被識別向量數量,列數為2*n的矩陣,每一行前n個放距離,后n個放數字。之后針對每一個被識別向量進行循環。

首先直接計算每個訓練圖片與該識別圖片的距離,直接可以用一行代碼表示

itemDis = np.sqrt(np.sum((item-train)**2, axis=1))

這一行代碼就是上文中的算法過程,我個人覺得還是比較復雜的,可以詳細的拆開看一下,我這里不細講了。下面的內容就是開始排序并且找到距離最近的前幾個向量。

這里的邏輯是:先排序,找到距離最小的前n個,存入矩陣。找到前n個在原矩陣中的位置,并找到對應位置上num的數字,存入dis的后n個。

這樣子就相當于完成了所有內容,返回dis即可。

實際測試

我自己動手寫了一些數字,如圖所示。所以實際上我們的數據庫還是比較小的。

python怎么實現識別手寫數字

所以我又寫了一個數字作為待識別圖像,通過程序運行以后,我們的以直接輸出前十個最相似的向量:

第1個向量為2.0,距離為33.62347223932534
第2個向量為2.0,距離為35.64182105224185
第3個向量為2.0,距離為38.69663119274146
第4個向量為2.0,距離為43.52904133387693
第5個向量為2.0,距離為43.69029199677604
第6個向量為1.0,距離為43.730883339256714
第7個向量為6.0,距離為44.94800943845918
第8個向量為2.0,距離為45.033283944455924
第9個向量為4.0,距離為45.43926712996951
第10個向量為7.0,距離為45.64893989116544

之后我又依次從1-9試了一遍,我自己手寫的數字全部識別正確,可以看出準確率還是挺高的。所以做到這一步相當于已經完成度很高了。

所以我就試了一下從網上找的圖片,發現幾乎沒有正確的了。說明我們的數據庫還是太小,只認得我的字體。不過話說這樣,也可以做一個字體識別的程序。

所以如果要提高準確率,那么擴大圖庫是必須的。這一次就到這里。

感謝各位的閱讀!關于“python怎么實現識別手寫數字”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

武山县| 桦南县| 方山县| 临高县| 海城市| 射阳县| 郓城县| 东莞市| 潜山县| 沁源县| 古浪县| 石棉县| 乌兰浩特市| 达州市| 友谊县| 壶关县| 南乐县| 江华| 黑水县| 北安市| 普安县| 隆尧县| 井研县| 龙江县| 丹棱县| 四子王旗| 香港| 雷山县| 基隆市| 和顺县| 应城市| 广宁县| 罗甸县| 玉树县| 皋兰县| 吉林市| 铁岭县| 阿尔山市| 宁城县| 辽中县| 镇巴县|