機器學習 基於OpenCV實現最簡單的數字識別

2021-06-19 08:04:09 字數 2752 閱讀 9004

本文將基於opencv實現簡單的數字識別。這裡以遊戲angry birds為例,通過以下幾個主要步驟對其中右上角的分數部分進行自動識別。

1. 學習分類器

根據訓練樣本,選取模型訓練產生數字分類器。這裡的樣本可以是通用的數字樣本庫(如nist等),也可以是針對應用場景而製作的專門訓練樣本。前者優在泛化性,後者強在準確率,當然常用做法是將這兩者結合,即在通用數字庫基礎上做修改。另外這裡由於模式並不複雜,計算量也不大,所以不對樣本進行特徵提取,對原始樣本作簡單變換後直接作為訓練樣本。

具體地,首先是生成訓練樣本矩陣,一般樣本是以二維矩陣的方式存在檔案當中,現在要將它們讀出來,進行適當的預處理,然後生成opencv能理解的資料結構。

train_x = cvcreatemat(sample_num * class_num, size * size, cv_32fc1);  

train_y = cvcreatemat(sample_num * class_num, 1, cv_32fc1);  

for(i = 0; i 

}  

訓練樣本中的數字位置形態各異,因此讀入時需要進行規整化。主要方法是先找到數字的邊界框,然後以寬和高中大的一邊為基準進行縮放和拉伸,從而使得其可以佔滿整個表示單個樣本的矩陣。

iplimage preprocessing(iplimage* img, int w, int h)  

假設單個樣本可表示為0/1矩陣,那findboundingbox()只要從x和y方向分別掃瞄最大最小的非0值就可以了。 訓練樣本準備好後,在opencv中建立相應的分類器非常方便。這裡用的是knn,當然除了knn外還有其它很多封裝好的分類器(如nn, svm等)。

knn = new cvknearest(train_x, train_y, 0, false, k);  

2. 影象預處理

前面通過學習產生了分類器,但我們輸入影象中的數字並不能直接作為測試輸入。影象中的數字筆畫有時並不規整,還可能相互重疊。因為本文例子為了簡化用的是螢幕截圖,所以位置形變校正,色彩亮度校正等等都省去了,但仍需要一些簡單處理。下面先對輸入影象進行一把簡單的預處理,主要目的是將數字之間兩兩分開。方法很簡單,首先將影象轉成二值圖,然後腐蝕一把,數字之間就分離得比較開了,這樣便於我們下一步分割和識別。這樣做還有個好處,就是把其餘的雜訊也順帶去掉了。

cvtcolor(input, out_img, cv_bgr2gray);  

threshold(out_img, out_img, 0, 255, cv_thresh_otsu + cv_thresh_binary);  

...  

erode(out_img, out_img, elem);  

結果:

3. 影象分割

接下來,就可以對影象進行分割了。由於我們的分類器只能對數字乙個乙個地識別,所以首先要把每個數字分割出來。基本思想是先用findcontours()函式把基本輪廓找出來,然後通過簡單驗證以確認是否為數字的輪廓。對於那些通過驗證的輪廓,接下去會用boundingrect()找出它們的包圍盒。

vector > contours;    

vector>::iterator it = contours.begin();    

while (it!=contours.end())  else     

}    

...    

vectorboundrect(contours.size());    

for (int i = 0; i 

結果:

4. 應用分類器

分割完後就可以應用我們前面訓練好的分類器對分割結果進行識別了。當然,如果感覺結果不滿意,可以將分類錯誤的樣本加上正確的標籤後放入訓練樣本重新生成分類器,使得分類器能夠有更好的識別率。上一步中的do_ocr()函式就是利用先前訓練好的分類器識別單個數字。注意訓練樣本進行過怎麼樣的預處理,這裡也一樣要做。

int do_ocr(iplimage *img)    

5. 後期處理

因為分割影象時查詢數字輪廓並不保證是按順序來的,所以這兒要將識別結果按分割時輸出的包圍盒位置資訊進行排序,最後將它們轉換成數字輸出。

sort(res_vec.begin(), res_vec.end(), sort_func);  

int j, num = 0;  

for (j = 0; j 

char resbuf[256];  

sprintf(resbuf, "%d", num);  

puttext(show_img, resbuf, point(output_x, output_y), font_hershey_******x, 0.8, scalar(0, 255, 0), 2);  

imshow("show", show_img);  

結果:

機器學習 基於OpenCV實現最簡單的數字識別

本文將基於opencv實現簡單的數字識別。這裡以遊戲angry birds為例,通過以下幾個主要步驟對其中右上角的分數部分進行自動識別。1.學習分類器 根據訓練樣本,選取模型訓練產生數字分類器。這裡的樣本可以是通用的數字樣本庫 如nist等 也可以是針對應用場景而製作的專門訓練樣本。前者優在泛化性,...

python基於opencv最簡單的人臉檢測01

準備開始學習opencv4 opencv 的意思就是開放的計算機視覺,是乙個基於c 的超實用庫 執行此 需要安裝opencv庫 可以通過pip安裝 以下是基於opencv自帶的人臉檢測模型的人臉檢測 import cv2 as cv defplot rectangle image,faces for...

機器學習opencv學習筆記

haar adaboost實現人臉識別 1 首先明白什麼是特徵 特徵 畫素經過運算 得到的結果 具體值 向量 矩陣 多維 2 如何利用特徵區分目標?閾值判決 3 得到判決?機器學習 haar特徵,是一種利用模版對畫素的計算,主要有模版的滑動和模版的縮放 opencv中haar特徵模版有一下的14種 ...