Python提取数字图片特征向量
引言
在機(jī)器學(xué)習(xí)中有一種學(xué)習(xí)叫做手寫數(shù)字識(shí)別,其主要功能就是讓機(jī)器識(shí)別出圖片中的數(shù)字,其步驟主要包括:圖片特征提取、將特征值點(diǎn)陣轉(zhuǎn)化為特征向量、進(jìn)行模型訓(xùn)練。第一步便是提取圖片中的特征提取。數(shù)據(jù)的預(yù)處理關(guān)系著后面模型的構(gòu)建情況,所以,數(shù)據(jù)的處理也是機(jī)器學(xué)習(xí)中非常重要的一部分。下面我就說(shuō)一下如何提取圖片中的特征向量。
圖片灰度化
?=>
當(dāng)我們拿到一種圖片的時(shí)候,這張圖片可能是多種顏色集合在一起的,而我們?yōu)榱朔奖闾幚磉@張圖片,我們首先會(huì)將這張圖片灰度化(左圖灰度化之前,右圖灰度化之后)。如果該圖片已經(jīng)是黑白兩色的就可以省略此步驟。
from PIL import Image import numpy as np#打開(kāi)一張圖片 img = Image.open("image/77.jpg") #圖片灰度化 img = img.convert("L") #顯示圖片 img.show() #將圖片轉(zhuǎn)換為數(shù)組形式,元素為其像素的亮度值 print np.asarray(img)在圖片灰度化之前這張圖片的數(shù)組值應(yīng)該是一個(gè)三維的,灰度化之后將變?yōu)槎S數(shù)組。數(shù)組行列數(shù)就是圖片的像素寬度和高度。
打印的數(shù)組形式如下:
圖片的二值化
圖片的二值化就是將上面的數(shù)組化為0和1的形式,轉(zhuǎn)化之前我們要設(shè)定一個(gè)閾值,大于這個(gè)閾值的像素點(diǎn)我們將其設(shè)置為1,小于這個(gè)閾值的像素點(diǎn)我們將其設(shè)置為0。下面我找了一張數(shù)字的圖片,這張圖片已經(jīng)灰度化過(guò)了。我們就直接將它二值化。圖片如下:
圖片的像素是32x32的。如果不是要化為此值,這一步我們叫做尺寸歸一化。
#打開(kāi)一張圖片 img = Image.open("numImage/3.jpg") #將圖片化為32*21的 img = img.resize((32, 32)) #二值化 img = img.point(lambda x:1 if x > 120 else 0) #將圖片轉(zhuǎn)換為數(shù)組形式,元素為其像素的亮度值 img_array = np.asarray(img) print img_array解釋一下上面的代碼,resize方法里的參數(shù)是一個(gè)元組,元素分別是寬和高;point函數(shù)是用來(lái)二值化圖片的,其參數(shù)是一個(gè)lambda函數(shù),函數(shù)體就是判斷其元素值是否大于120,這里的120就是上面提到的閾值。
二值化后的數(shù)組:
在數(shù)組中我們可以大似的看到,數(shù)字1大似組成了一個(gè)3的形狀。
獲取網(wǎng)格特征數(shù)字統(tǒng)計(jì)圖
在圖片二值化之后,我們通常需要獲取到網(wǎng)格統(tǒng)計(jì)圖,這里我們的圖片尺寸是32*32的,所以我們將其化為8*8的點(diǎn)陣圖,步驟如下:
1、將二值化后的點(diǎn)陣水平平均劃線分成8份,豎直平均劃線分成8份。
2、分別統(tǒng)計(jì)每一份中像素點(diǎn)為1的個(gè)數(shù)。
3、將每一個(gè)份統(tǒng)計(jì)值組合在一起,構(gòu)成8*8的點(diǎn)陣統(tǒng)計(jì)圖。
下面我寫了個(gè)函數(shù)來(lái)將32*32的數(shù)組轉(zhuǎn)化成8*8的網(wǎng)格特征數(shù)字統(tǒng)計(jì)圖:
#將二值化后的數(shù)組轉(zhuǎn)化成網(wǎng)格特征統(tǒng)計(jì)圖def?get_features(array):#拿到數(shù)組的高度和寬度h,?w?=?array.shapedata?=?[]for?x?in?range(0,?w/4):offset_y?=?x?*?4temp?=?[]for?y?in?range(0,h/4):offset_x?=?y?*?4#統(tǒng)計(jì)每個(gè)區(qū)域的1的值temp.append(sum(sum(array[0+offset_y:4+offset_y,0+offset_x:4+offset_x])))data.append(temp)return?np.asarray(data)轉(zhuǎn)化之后我們的到的數(shù)組點(diǎn)陣是這樣的:
將二維的統(tǒng)計(jì)圖轉(zhuǎn)化為一維的特征向量
這一步就比較簡(jiǎn)單了,只需要將矩陣全部放到一行即可,直接使用np的reshape()方法即可:
features_vector =features_array.reshape(features_array.shape[0]*features_array.shape[1]) print features_vector輸出結(jié)果:
有些同學(xué)可能要問(wèn),為什么要將二維的點(diǎn)陣轉(zhuǎn)化成一維的特征向量? 這是因?yàn)樵跈C(jī)器學(xué)習(xí)中,數(shù)據(jù)集的格式就是這樣的,數(shù)據(jù)集的一個(gè)樣例就是一個(gè)特征向量,對(duì)個(gè)樣例組成一個(gè)訓(xùn)練集。轉(zhuǎn)化為以為的特征向量是便于我們的使用。
全部代碼(省略灰度化):
from PIL import Imageimport numpy as np#將二值化后的數(shù)組轉(zhuǎn)化成網(wǎng)格特征統(tǒng)計(jì)圖def get_features(array):#拿到數(shù)組的高度和寬度h, w = array.shapedata = []for x in range(0, w/4):offset_y = x * 4temp = []for y in range(0,h/4):offset_x = y * 4#統(tǒng)計(jì)每個(gè)區(qū)域的1的值temp.append(sum(sum(array[0+offset_y:4+offset_y,0+offset_x:4+offset_x])))data.append(temp)return np.asarray(data)#打開(kāi)一張圖片 img = Image.open("numImage/3.jpg") #將圖片化為32*32的 img = img.resize((32, 32))#二值化 img = img.point(lambda x:1 if x > 120 else 0) #將圖片轉(zhuǎn)換為數(shù)組形式,元素為其像素的亮度值 img_array = np.asarray(img) print img_array #得到網(wǎng)格特征統(tǒng)計(jì)圖 features_array = get_features(img_array) print features_array features_vector =features_array.reshape(features_array.shape[0]*features_array.shape[1]) print features_vector原文:http://www.k2zone.cn/?p=977
總結(jié)
以上是生活随笔為你收集整理的Python提取数字图片特征向量的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: windows下的使用别人编译好的库文件
- 下一篇: websocket python爬虫_p