1. 程式人生 > >Opencv手寫數字識別_Opencv3.0+KNN+HOG特徵_原始碼_MAC_OS環境搭建視訊教程.

Opencv手寫數字識別_Opencv3.0+KNN+HOG特徵_原始碼_MAC_OS環境搭建視訊教程.

  寫在前面

   最近在學習Opencv,本人android開發狗,對Opencv純屬興趣。一個破本科畢業的我,發現智商完全不夠用,書到用是方恨少,都怪自己數學太渣。好在Opencv封裝得比較好,如果只是使用的話,大概知道原理就知道該怎麼用。經過學習總結,寫了一個小Demo,一方面是自己做的筆記,另一方面也可以給初學者做一個參考,讓大家少走一些彎路。有些東西本來很容易理解,但是太過於概念化反而不好理解,吃了多次虧(可能是自己太渣:-)。其實這個Demo的原理也適用於任何文字手寫識別,只需要修改樣本庫就可以了。

開發環境

 Opencv 3.0

 Xcode 7.3

Opencv 跨平臺,如果不是用的Mac,自己去搜一下環境配置,網上很多資料,這裡不細說。如果你使用的Mac 我這裡有一些老外的簡潔配置視訊,文末和所有程式碼分享給大家。

用到的理論知識

1、          Opencv的Mat基本操作:很簡單啦,就是圖片讀取roi拷貝等。

2、          KNN演算法:K最近鄰(kNNk-NearestNeighbor)分類演算法,一個簡單有效的分類演算法,看了多個大牛寫的文章,很多人覺得KNN精確度相對較好,我覺得重要的是簡單有效。不懂的話,大家百度一下,我相信你學過向量,基本上就能明白KNN演算法。

3、          HOG 特徵:方向梯度直方圖(Histogramof Oriented Gradient, HOG)特徵,這個需要大家有一定基礎知識,採集過程有點複雜,實話是說我也並沒有完全看懂,但我知道了大概原理。但是網上很多文章介紹這個東東。
    這裡我想說一些我的看法:影象識別的核心技術我認為是影象的描述特徵,而不是高大上的機器學習演算法,什麼是影象特徵?拋開很多亂七八糟的數學符號不說,特徵嘛,唯一標示一個物件的東西了。只不過影象特徵在Opencv裡多是用向量來描述的(說到底就是用一個多維向量來確定一張圖片)。當然其實也可以用任何格式來描述,也可以創造自己的特徵演算法,只有能行之有效。無所謂是用向量啊,函式啊,點集啊,只要能唯一描述一張圖片或者一類圖片就行。你甚至可以直接使用圖片的所有畫素RGB值組成一個向量來作為影象特徵。所以我的建議是當提到影象特徵時不要拘泥於書中的演算法,完全可以大開腦洞,試著去設計自己的特徵演算法。說不定比某位前輩的演算法更精確高效。

    當然了,本文中使用的就是HOG特徵,因為看了別人的文章覺得HOG特徵在這種應用場合效果應該還不錯,HOG特徵最成功的地方是行人檢測,大家可以去網上搜一下相關資料。

手寫數字識別過程介紹

第一步:

當然是資料採集啦,我們根據已有的資料和分類去確定未知的資料屬於哪一類,專業名詞叫“監督學習”,去它的專業名字,我只是個學渣,你給我念八股文J。

為了方便先貼出一段程式碼:


這就是Opencv3.0 採集影象Hog特徵的程式碼,正如我前面所說,Opencv裡面用一個向量來標示一張圖片,至於這個向量怎麼得出來的,就是演算法的事情了。如果你感興趣可以深入研究。這段程式碼的意思是從path這個路徑的圖片採集出它的HOG特徵,descriptors這個vector儲存的就是path這個路徑下的圖片的特徵。換言之,現在就是用descriptors來標示這張圖片了,在以後的圖片匹配啊,計算啊,就用這個vector了,基本上和這個影象沒關係了。在這個Demo專案中,樣本和測試樣本都是128X128的,在實際應用中可能樣本和測試樣本大小不一樣,但要想辦法優化原圖之後進行歸一化,至於HOGDescriptor引數為什麼要這樣設定,大家去網上了解一下HOG特徵原理就知道了,這裡我設定的引數是為了快速和準確而取的一個折衷。按照這個引數採集的最終特徵值是384個,也就是說,現在這張圖片要被這個長度為384的vector來代替。

值得注意的是,手寫的時候可能影象並不能居中,這樣可能會增加誤差,在本Demo中通過輪廓尋找把內容重新拷貝到手寫去中間,來減少誤差。原理如下圖:

 

第二步:

         使用Opencv自帶的機器學習演算法API,組裝資料,


呼叫Opencv自帶的KNN 分類API,這裡設定K值大小:1=<k<=10(因為我們這裡是0-9共10個數字,相當於10個分類),最好不要設定成1 ,有時候因為樣本太少可能會導致誤差太大,稍微設定大一點,可以減少誤差。這裡的dataMat就是採集到的所有HOG特徵,labelMat 就是每一行對應代表的是那個值.畫一個草圖就像這樣:


第三步:

通過以上的步驟,現在我們就可以預測或者說是分類識別了:

這裡我使用10張測試圖片,命名是0-9.png,一來方便讀取而來方便對比結果,predict 就是預測分類,注意這裡的去預測這個圖片時候不是呼叫圖片的Mat而是這個影象的HOG特徵,沒想到我僅僅用了對每個手寫數字用了20個樣本,使用了完全不同的10個樣本來測試,竟然都識別出來了.效果還是蠻不錯的。

 

最終結果:按‘C’鍵清除畫板,按’S’鍵識別

原始碼,文件,環境搭建教程下載地址

github:

https://github.com/woshiwzy/Opencv3.0_Digital-recognition_onMacOS_Xcode_video_source

百度雲盤:

csdn:

http://download.csdn.net/detail/wang382758656/9644725