本發(fā)明屬于計(jì)算機(jī)圖像識(shí)別技術(shù),具體來說涉及一種基于卷積神經(jīng)網(wǎng)絡(luò)的用于識(shí)別菜品圖像的技術(shù)方案。
背景技術(shù):
由于圖像的形成受到很多因素的影響,比如說拍攝角度、環(huán)境光線,原始圖像的矩陣數(shù)據(jù)并不能被計(jì)算機(jī)分析,所以圖像識(shí)別的第一步是特征提取,即將圖像轉(zhuǎn)化為一個(gè)固定長度的向量,該向量受外界條件影響應(yīng)當(dāng)是較小的。并且,不同于一般的圖像識(shí)別問題,比如飛機(jī)和汽車,他們在外觀上是有很大的結(jié)構(gòu)性差異的,而對于菜品,存在大量結(jié)構(gòu)相似的不同種類的菜品,比如土豆絲和豆芽。現(xiàn)有的基于局部描述子的特征提取方法無法捕捉到這種細(xì)致的差異,也無法應(yīng)對同一菜品的豐富變化,從而識(shí)別精確度偏低,魯棒性不夠好。
技術(shù)實(shí)現(xiàn)要素:
本發(fā)明提供一種菜品識(shí)別技術(shù),即給定一張圖片,若是菜品,則輸出其菜品類別。具體來說,本發(fā)明采用的技術(shù)方案如下:
一種菜品識(shí)別方法,其特征在于,所述方法包括以下步驟:1)獲得web請求,服務(wù)器相應(yīng)web請求,獲取相應(yīng)圖像;2)保存圖像,獲取輸入數(shù)據(jù)流,生成圖像文件名并保存至磁盤;3)圖像預(yù)處理,對輸入的圖像進(jìn)行尺寸調(diào)整和歸一化;4)使用預(yù)先訓(xùn)練的卷積神經(jīng)網(wǎng)絡(luò)進(jìn)行處理,對圖像上的物體進(jìn)行檢測及分類,如果沒有檢測到菜品則結(jié)束,如果檢測到菜品,則結(jié)合分類結(jié)果,輸出相應(yīng)菜品信息。
在以上方法中,步驟3)預(yù)處理的步驟包括,使用OpenCV的cv2接口,將本地圖像讀取為一個(gè)Numpy的矩陣對象,將圖像縮放和截取為224*224像素,并將圖像的RGB通道分別減去104、117、123,獲得歸一化的圖像文件。
進(jìn)一步,步驟4)包括,使用5層卷積神經(jīng)網(wǎng)絡(luò),卷積核依次為11×11、5×5、3×3、3×3、3×3,卷積核個(gè)數(shù)依次為96、256、384、384、256個(gè),第一、二、五層卷積之后分別進(jìn)行最大值池化,池化核2×2,第五層池化結(jié)果作為輸入進(jìn)行兩層全連接,結(jié)果輸出至Softmax層,輸出節(jié)點(diǎn)數(shù)量為菜品的數(shù)量,每一維對應(yīng)圖片屬于某個(gè)類別的概率。
更進(jìn)一步,以上神經(jīng)網(wǎng)絡(luò)分別用于菜品的檢測和識(shí)別,其中當(dāng)檢測時(shí)分類為菜品和背景,當(dāng)識(shí)別菜品品類時(shí)輸出概率最高的30個(gè)菜品品類,當(dāng)兩者都得到肯定結(jié)果時(shí),輸出更準(zhǔn)確的菜品類別。
采用本發(fā)明的方案,能夠?qū)崿F(xiàn)菜品的實(shí)時(shí)檢測與鑒別,輸出更為準(zhǔn)確的結(jié)果,避免在沒有菜品的情況下輸出讓人覺得奇怪的結(jié)果,在有菜品的情況下輸出更為精確的結(jié)果。
附圖說明
圖1是本發(fā)明的實(shí)現(xiàn)流程圖。
具體實(shí)施方式
本發(fā)明的目的在于在給定一張圖片的情況下,若其中包含菜品,則輸出其菜品類別,若沒有菜品則不輸出結(jié)果。
菜品拍攝獲得的圖像會(huì)受到很多因素的影響,而且菜品本身具有復(fù)雜的特征,例如顏色、紋理、空間位置、形狀等等,在不同的拍攝角度、環(huán)境光線等條件下,同樣的菜品拍攝的圖像會(huì)差異巨大。原始圖像的矩陣數(shù)據(jù)并不能被計(jì)算機(jī)分析,所以圖像識(shí)別的第一步是特征提取,即將圖像轉(zhuǎn)化為一個(gè)固定長度的向量,該向量受外界條件影響應(yīng)當(dāng)是較小的。并且,不同于一般的圖像識(shí)別問題,比如飛機(jī)和汽車,他們在外觀上是有很大的結(jié)構(gòu)性差異的,而對于菜品,存在大量結(jié)構(gòu)相似的不同種類的菜品,比如土豆絲和豆芽?,F(xiàn)有的基于局部描述子的特征提取方法無法捕捉到這種細(xì)致的差異,也無法應(yīng)對同一菜品的豐富變化,從而識(shí)別精確度偏低,魯棒性不夠好。
至今為止特征沒有統(tǒng)一和精確的定義。特征的精確定義往往由問題或者應(yīng)用類型決定。特征是一個(gè)數(shù)字圖像中“有趣”的部分,它是許多計(jì)算機(jī)圖像分析算法的起點(diǎn)。因此一個(gè)識(shí)別算法是否成功往往由它使用和定義的特征決定。特征提取最重要的一個(gè)特性是“不變性”:同一場景的不同圖像所提取的特征應(yīng)該是沒有大的變化的。常用的圖像特征有顏色特征、紋理特征、形狀特征、空間關(guān)系特征。(一)顏色特征是一種全局特征,描述了圖像或圖像區(qū)域所對應(yīng)的景物的表面性質(zhì)。一般顏色特征是基于像素點(diǎn)的特征。由于顏色對圖像或圖像區(qū)域的方向、大小等變化不敏感,所以顏色特征不能很好地捕捉圖像中對象的局部信息。(二)紋理特征也是一種全局特征,它也描述了圖像或圖像區(qū)域所對應(yīng)景物的表面性質(zhì)。但由于紋理只是一種物體表面的特性,并不能完全反映出物體的本質(zhì)屬性,所以僅僅利用紋理特征是無法獲得高層次圖像內(nèi)容的。(三)各種基于形狀特征的分類方法都可以比較有效地利用圖像中感興趣的目標(biāo)來進(jìn)行分類,但它們也有一些共同的問題,目前基于形狀的分類方法還缺乏比較完善的數(shù)學(xué)模型;如果目標(biāo)有變形時(shí)分類結(jié)果往往不太可靠;許多形狀特征所反映的目標(biāo)形狀信息與人的直觀感覺不完全一致,或者說,特征空間的相似性與人視覺系統(tǒng)感受到的相似性有差別。(四)所謂空間關(guān)系,是指圖像中分割出來的多個(gè)目標(biāo)之間的相互的空間位置或相對方向關(guān)系,這些關(guān)系也可分為連接/鄰接關(guān)系、交疊/重疊關(guān)系和包含/包容關(guān)系等。通??臻g位置信息可以分為兩類:相對空間位置信息和絕對空間位置信息。前一種關(guān)系強(qiáng)調(diào)的是目標(biāo)之間的相對情況,如上下左右關(guān)系等,后一種關(guān)系強(qiáng)調(diào)的是目標(biāo)之間的距離大小以及方位。顯而易見,由絕對空間位置可推出相對空間位置,但表達(dá)相對空間位置信息常比較簡單。空間關(guān)系特征的使用可加強(qiáng)對圖像內(nèi)容的描述區(qū)分能力,但空間關(guān)系特征常對圖像或目標(biāo)的旋轉(zhuǎn)、反轉(zhuǎn)、尺度變化等比較敏感。另外,實(shí)際應(yīng)用中,僅僅利用空間信息往往是不夠的,不能有效準(zhǔn)確地表達(dá)場景信息,往往還要結(jié)合其他特征。
在現(xiàn)已提出的圖像分類方法中,基于局部特征的圖像分類方法取得了最好效果,尤其是建立在詞袋(bag-of-words)模型框架下的一些改進(jìn)方法取得了當(dāng)前最好的分類效果。BOW模型在文本分類中的成功應(yīng)用使得將BOW模型應(yīng)用于圖像分類成為可能。從圖像中提取出的局部特征類似于文本中的單詞,分別代表著圖像和文本的局部信息。與文本分類的原理類似,從不同的圖像中提取出的特征反映了不同圖像的信息,這些信息就可以作為我們分類的依據(jù)。例如對于森林場景來說,出現(xiàn)樹葉的局部特征頻率要比高山出現(xiàn)樹葉的局部特征的頻率要高一些。反之,在高山場景中出現(xiàn)山峰狀局部特征的頻率要比森林場景要高一些。因此每一類圖像或目標(biāo)總有它區(qū)分于其他類別的特征。BOW模型正是根據(jù)這點(diǎn),應(yīng)用統(tǒng)計(jì)學(xué)的方法來計(jì)算不同特征在圖像中出現(xiàn)的頻率來達(dá)到分類圖像的目的?;贐OW模型的圖像分類可以分為五個(gè)步驟:特征提取、碼本生成、圖像表達(dá)生成、圖像分類。
局部特征提取:對于特征的選擇,一般情況下,人們使用的是局部不變性特征SIFT,當(dāng)然使用HOG、SUFT及LBP等局部特征也可以獲得比較不錯(cuò)的結(jié)果。
碼本(codebook)的生成:碼本生成又稱為字典學(xué)習(xí),因?yàn)閺脑紙D像中提取的局部特征非常多,不便于比對,而且其中有很多重復(fù)的。因此需要找出其中獨(dú)立的特征,類似于構(gòu)建一本字典,然后用每個(gè)字出現(xiàn)的次數(shù)的直方圖來表示一篇文章,比對兩個(gè)直方圖就方便多了。傳統(tǒng)的BOW方法采用的碼本生成方法是基于K-means聚類的方法,這種方法具有快速、高效、無監(jiān)督特性,因此被廣泛地采用。將從訓(xùn)練樣本中提取出的所有局部特征進(jìn)行K-means聚類,得到的聚類中心即為碼本的碼字。
圖像特征的生成:最終判別圖像類別的是一些具有區(qū)分性特征出現(xiàn)的頻率。因此我們最后用一個(gè)直方圖來表達(dá)一幅圖像,直方圖表達(dá)的是碼本中每一個(gè)碼字在圖像中出現(xiàn)的次數(shù)。為了更好地計(jì)算我們將直方圖歸一化,并且用一個(gè)向量表示。因此每幅圖像最終的表達(dá)就是一個(gè)與碼本大小相同的向量。
圖像分類:分類器根據(jù)其線性特征可以分為線性分類器和非線性分類器,線性分類器沒有對數(shù)據(jù)進(jìn)行處理就直接在特征空間進(jìn)行分類,而非線性分類器對數(shù)據(jù)進(jìn)行了一個(gè)映射,例如采用了核函數(shù)。對于圖像的分類,因?yàn)槠涮卣魇歉呔S的而且數(shù)據(jù)量很大,人們通常使用的是使用RBF核函數(shù)的SVM分類器。
BOW模型被發(fā)明于文本處理領(lǐng)域,后引入到圖像處理。其忽略了一個(gè)圖像與文本的根本區(qū)別,文本中的單詞之間沒有空間關(guān)系這個(gè)概念,但是圖像卻是有拓?fù)浣Y(jié)構(gòu)的,局部特征之間的空間關(guān)系對于分類非常重要,用局部特征的直方圖來表示圖像并不合適。而且,菜品圖像具有圖像結(jié)構(gòu)相似、紋理差別不大這樣的問題,使用基于一般的局部特征的方法并不能很好的區(qū)分,比如豆腐和雞塊的圖像局部。它們的區(qū)別在于不同紋理的組合,我們很難形式化的定義這種組合。受到深度學(xué)習(xí)的從圖像學(xué)習(xí)特征而非人為定義的啟發(fā),可以推斷將其用于菜品圖像分類可以取得良好的效果。通過多層的卷積神經(jīng)網(wǎng)絡(luò),可以學(xué)習(xí)到最好的適用于菜品圖像的特征提取方式。神經(jīng)網(wǎng)絡(luò)的底層會(huì)學(xué)習(xí)到線條、顏色塊這樣的特征,然后組合出各種食材的紋理特征,進(jìn)一步組合出菜品的部分和整體。神經(jīng)網(wǎng)絡(luò)中的多次池化操作能夠一定程度上抵抗環(huán)境條件和拍攝方式的干擾,提升識(shí)別系統(tǒng)的魯棒性。通過大量的實(shí)驗(yàn)證明,我們的分類系統(tǒng)能夠達(dá)到實(shí)用的程度。
下面結(jié)合具體實(shí)施例來介紹我們的方案。本發(fā)明的菜品識(shí)別方案包含以下內(nèi)容:1)獲取圖像;2)保存圖像;3)圖像預(yù)處理;4)使用卷積神經(jīng)網(wǎng)絡(luò)進(jìn)行處理,輸出相應(yīng)菜品信息。
1、獲取/響應(yīng)Web請求
Web服務(wù)器采用Flask框架實(shí)現(xiàn),該框架非常簡潔而又功能齊全,非常適合用于快速構(gòu)造應(yīng)用。一個(gè)最小的Flask應(yīng)用如下
首先,代碼導(dǎo)入了Flask類。這個(gè)類的實(shí)例將會(huì)是我們的WSGI應(yīng)用程序。接下來,創(chuàng)建一個(gè)該類的實(shí)例,第一個(gè)參數(shù)是應(yīng)用模塊或者包的名稱。這里使用__name__,因?yàn)槟K的名稱將會(huì)因其作為單獨(dú)應(yīng)用啟動(dòng)還是作為模塊導(dǎo)入而有不同。這是必須的,這樣Flask才知道到哪去找模板、靜態(tài)文件等等。詳情見Flask的文檔。然后,使用route()裝飾器告訴Flask什么樣的URL能觸發(fā)該響應(yīng)函數(shù)。這個(gè)函數(shù)的名字也在生成URL時(shí)被特定的函數(shù)采用,這個(gè)函數(shù)定義了如何處理該HTTP請求。最后我們用run()函數(shù)來讓應(yīng)用運(yùn)行在本地服務(wù)器上。其中if__name__=='__main__':確保服務(wù)器只會(huì)在該腳本被Python解釋器直接執(zhí)行的時(shí)候才會(huì)運(yùn)行,而不是作為模塊導(dǎo)入的時(shí)候。
2、保存/讀取圖像
獲取輸入數(shù)據(jù)流,生成一個(gè)隨機(jī)的UUID作為圖像文件名,保存至磁盤。讀取時(shí),使用OpenCV的cv2接口,將本地圖像讀取為一個(gè)Numpy的矩陣對象,等待后續(xù)處理。
3、圖像預(yù)處理
圖像的預(yù)處理步驟一般包括尺寸調(diào)整和歸一化,這兩個(gè)步驟的具體設(shè)置會(huì)和使用的模型相關(guān),比如說不同的模型的輸入尺寸是不一樣的。在這里,我們使用的AlexNet網(wǎng)絡(luò)模型要求輸入圖像為224*224像素,所以首先將上傳的圖像縮放為短的一條邊為224像素,再截取較長的一條邊的中間224像素部分。歸一化設(shè)置需要和訓(xùn)練時(shí)一致,圖像的RGB通道分別減去104,117,123。
//讀取
img=cv2.imread(img_path)
//根據(jù)短邊計(jì)算縮放率
min_size=min(img.shape[0],img.shape[1])
resize_ratio=input_shape[2]/224
//縮放操作
img=cv2.resize(img,None,fx=resize_ratio,fy=resize_ratio)
//截取
y_margin=(img.shape[0]-input_shape[2])//2
x_margin=(img.shape[1]-input_shape[2])//2
img=img[y_margin:input_shape[2]+y_margin,x_margin:input_shape[2]+x_margin]
//歸一化
mean_img=np.asarray([104,117,123]).reshape((3,1,1))
img=img.transpose((2,0,1))-mean_img
4、輸入到分類神經(jīng)網(wǎng)絡(luò)
Caffe提供了Python的接口(pycaffe),詳見caffe/python文件夾。在python代碼中可以導(dǎo)入模型,前向、反向迭代,數(shù)據(jù)輸入輸出,網(wǎng)絡(luò)可視化,自定義優(yōu)化方法。所有的模型數(shù)據(jù)、計(jì)算參數(shù)都是可供讀寫的。要使用caffe的Python接口,首先需要把caffe/python的絕對路徑添加到PYTHONPATH環(huán)境變量中,然后在Python代碼中import caffe就可以導(dǎo)入caffe庫。
import caffe
//創(chuàng)建模型,載入?yún)?shù)
network=caffe.Net(…)
//前向計(jì)算
output=network.forward(data=image)
//獲得菜品和概率
foods=output[‘a(chǎn)rgmax’][0,0].astype(‘int16’)
probs=net.blobs['prob'].data[0].tolist()
圖像輸入到卷積神經(jīng)網(wǎng)絡(luò)后,進(jìn)行的是一個(gè)前向計(jì)算過程,包括卷積、激活函數(shù)和池化操作。卷積神經(jīng)網(wǎng)絡(luò)與普通神經(jīng)網(wǎng)絡(luò)的區(qū)別在于,卷積神經(jīng)網(wǎng)絡(luò)包含了一個(gè)由卷積層和池化層構(gòu)成的特征抽取器。在卷積神經(jīng)網(wǎng)絡(luò)的卷積層中,一個(gè)神經(jīng)元只與部分鄰層神經(jīng)元連接。在一個(gè)卷積層中,通常包含若干個(gè)特征平面(FeatureMap),每個(gè)特征平面由一些矩形排列的的神經(jīng)元組成,同一特征平面的神經(jīng)元共享權(quán)值,這里共享的權(quán)值就是卷積核。卷積核一般以隨機(jī)小數(shù)矩陣的形式初始化,在網(wǎng)絡(luò)的訓(xùn)練過程中卷積核將學(xué)習(xí)得到合理的權(quán)值。共享權(quán)值(卷積核)帶來的直接好處是減少網(wǎng)絡(luò)各層之間的連接,同時(shí)又降低了過擬合的風(fēng)險(xiǎn)。池化也叫做池化(pooling),通常有均值池化(mean pooling)和最大值池化(max pooling)兩種形式。池化可以看作一種特殊的卷積過程。卷積和池化大大簡化了模型復(fù)雜度,減少了模型的參數(shù)。
卷積操作
卷積過程有三個(gè)二維矩陣參與,它們分別是兩個(gè)特征圖和一個(gè)卷積核:原圖inputX、輸出圖outputY、卷積核kernelW。卷積過程可以理解為卷積核kernalW覆蓋在原圖inputX的一個(gè)局部的面上,kernalW對應(yīng)位置的權(quán)重乘于inputX對應(yīng)神經(jīng)元的輸出,對各項(xiàng)乘積求和并賦值到outputY矩陣的對應(yīng)位置。卷積核在inputX圖中從左向右,從上至下每次移動(dòng)一個(gè)位置,完成整張inputX的卷積過程。
池化操作
池化有兩種形式,一種是均值池化(mean-pooling),一種是最大值池化(max-pooling)。兩種池化看成特殊的卷積過程:(1)均值池化的卷積核中每個(gè)權(quán)重都是0.25,卷積核在原圖inputX上的滑動(dòng)的步長為2。均值池化的效果相當(dāng)于把原圖模糊縮減至原來的1/4。(2)最大值池化的卷積核中各權(quán)重值中只有一個(gè)為1,其余均為0,卷積核中為1的位置對應(yīng)inputX被卷積核覆蓋部分值最大的位置。卷積核在原圖inputX上的滑動(dòng)步長為2。最大值池化的效果是把原圖縮減至原來的1/4,并保留每個(gè)2*2區(qū)域的最強(qiáng)輸入。
激活函數(shù)
激活函數(shù)是用來加入非線性因素的,因?yàn)榫€性模型的表達(dá)能力不夠。在本算法使用的神經(jīng)網(wǎng)絡(luò)的激活函數(shù)是ReLU函數(shù),其具有求導(dǎo)簡便,梯度不消失的優(yōu)點(diǎn)。
用于圖像識(shí)別的卷積神經(jīng)網(wǎng)絡(luò)主要由卷積層、池化層和激活函數(shù)層交替連接組成,深度從幾到幾十。并且,每個(gè)模塊也有自由參數(shù)可以選擇,比如說卷積層的卷積核大小、數(shù)量,池化窗口的尺寸以及每種類型使用多少次等,不同的超參數(shù)組合得到不同的網(wǎng)絡(luò)結(jié)構(gòu),在分類效果上也會(huì)有一些區(qū)別。本算法的模型的基本參數(shù)如下所示:
輸入:224×224大小的圖片,3通道;
第一層卷積:11×11大小的卷積核96個(gè);
第一層max-pooling:2×2的核;
第二層卷積:5×5卷積核256個(gè);
第二層max-pooling:2×2的核;
第三層卷積:與上一層是全連接,3*3的卷積核384個(gè),分到兩個(gè)GPU上個(gè)192個(gè);
第四層卷積:3×3的卷積核384個(gè),與上一層連接沒有經(jīng)過池化層;
第五層卷積:3×3的卷積核256個(gè);
第五層max-pooling:2×2的核;
第一層全連接:4096維,將第五層max-pooling的輸出連接成為一個(gè)一維向量,作為該層的輸入;
第二層全連接:4096維;
Softmax層:輸出節(jié)點(diǎn)數(shù)量為菜品的數(shù)量,每一維對應(yīng)圖片屬于某類別的概率。
上面結(jié)合附圖對本發(fā)明的實(shí)施方式作了詳細(xì)的說明,但是本發(fā)明不限于上述實(shí)施方式,在所屬技術(shù)領(lǐng)域普通技術(shù)人員所具備的知識(shí)范圍內(nèi),還可以在不脫離本發(fā)明宗旨的前提下做出各種變化。