基於OpenCV的簡單機讀卡識別

2021-09-29 16:04:11 字數 4287 閱讀 8748

2.2 影象識別

三、執行結果

四、總結

ps:以前的c++**風格真的慘不忍睹,而且沒有注釋,23333

這是這個程式需要識別的機讀卡:

2.1.1 影象的二值化

一般情況我們需要識別的基本都是三通道的彩色影象。

而影象的處理一般都會需要講這些影象進行二值化的處理,讓整個影象呈現出明顯的只有黑和白的視覺效果,便於進行影象的分割和識別。

bool

loadimage

(const

char

* src_path, cv::mat& binary_img)

cv::mat src_gary_img;

cv::

cvtcolor

(src_img, src_gary_img, cv_bgr2gray)

;// 自適應閾值的二值化處理

// 將灰度圖轉換為二值圖

cv::

adaptivethreshold

(src_gary_img, binary_img,

255,0,

1,101,10)

;return

true

;}

這是處理的效果:

2.1.2 roi(region of interest,感興趣區域)的分割

這張的roi就是數字資訊和選擇題答案的區域,我們需要將其單獨分割出來。

cv::mat getmaxcontourrect

(const cv::mat& src)

}// 根據最大連通域切割矩形框

cv::rect max_contour_rect = cv::

boundingrect

(max_contours)

; cv::mat roi_box =

src(max_contour_rect)

;return roi_box;

}

分割後的效果:

a. 選擇題部分分割

將分割後的影象反色處理後,再次提取最大連通域即可定位到選擇題方框。

接著再次反色讓背景變成黑色,然後對得到的影象進行簡單的裁剪,降低識別誤差。

ps:二值圖中白色為1,黑色為0。查詢連通域是根據的是白色區域查詢,所以需要反色操作。

// 定位答題區域,即最大連通域區域

cv::mat roi_box =

getmaxcontourrect

(src)

;// 反色處理定位選擇題區域,然後再做反色便於提取選項

cv::mat choice_box =

getmaxcontourrect

(~roi_box)

; choice_box =

~choice_box;

// 裁剪為最佳定位樣式

choice_box =

choice_box

(cv::

rect(0

,15, choice_box.cols, choice_box.rows /2-

22));

分割效果:

b. 數字部分分割

// 定位選擇題上方數字資訊

cv::mat roi_img =

getmaxcontourrect

(src)

;cv::mat info_box =

roi_img

(cv::

rect(0

,10, roi_img.cols, roi_img.rows /4-

10));

std::vector<:vector>> contours, num_box;

cv::

findcontours

;// 獲取兩個數字框

for(

auto iter = contours.

begin()

; iter != contours.

end(

); iter++

)std::vector<:mat> num;

for(

auto iter = num_box.

begin()

; iter != num_box.

end(

); iter++

)

分割效果:

2.2.1 選擇題識別

根據選擇題的分割效果,可以明顯的看出塗抹了選項的選項部分連通域大小明顯的突出。

所以這裡可以很輕易的得到40道選擇題的塗抹區域的相對位置。

將選擇題部分分割為10x20的矩陣,每個位置對於乙個區域資訊,從而得到塗抹結果。

**實現:

// 定位塗抹區間的連通域,根據塗抹區域大小決定

std::vector<:vector>> contours;

cv::

findcontours

;std::vector<:vector>> answer_contours;

for(

auto iter = contours.

begin()

; iter != contours.

end(

); iter++)}

// 儲存中心點區域

std::vector<:moments> contours_moments;

for(

auto iter = answer_contours.

begin()

; iter != answer_contours.

end(

); iter++

)// 計算中心矩

std::vector<:point2f> moments_point;

for(

auto iter = contours_moments.

begin()

; iter != contours_moments.

end(

); iter++

)// todo: 根據中心點位置計算題號和答案

// ......

}

2.2.2 數字識別

數字識別相較於選擇題識別更加複雜一點,需要進行模板匹配。

ps: 通過深度學習的方法實現效果會更好。

這裡我使用的是較為簡單一點的模板識別,這是匹配用得模板:

按照選擇題識別的方法,將0~9的數字放在乙個影象上,通過opencv提供的匹配函式定位識別區域中心的位置。為了使識別更精準,現將待匹配的數字影象提取其最大連通域進行匹配。下面是**實現的過程:

int

nummatch

(cv::mat& src,

int method)

試卷號: 073008

手機號: 15764713111

選擇題答案:

01:a 02:b 03:c 04:d 05:a

06:a 07:b 08:c 09:d 10:b

11:b 12:b 13:c 14:d 15:a

16:a 17:b 18:c 19:b 20:a

21:a 22:b 23:c 24:d 25:a

26:a 27:b 28:c 29:d 30:a

31:a 32:b 33:c 34:d 35:b

36:a 37:b 38:b 39:d 40:a

請按任意鍵繼續. .

.

這個程式存在一些缺陷,即識別過於單一化,識別精度不夠。對機讀卡的要求很高,更適用於機器固定掃瞄的。

專案很簡單,主要是我學習opencv基礎後一些簡單的實際應用。

基於Opencv自帶BP網路的車標簡易識別

位址如下 記得把這幾點描述好咯 實現過程 專案檔案結構截圖 演示效果 先將資料集手動劃分成訓練集和測試集,並分好類,比如第一類就放在資料夾名為0的資料夾下,第二類就是1,如此類推。當前程式只能處理10類以下車標,因為當前程式邏輯不支援10以上的數字識別 具體可以仔細看下 所有訓練集的放在train資...

基於OpenCV的簡單的人臉檢測

這個是在數字影象處理課程裡面的乙個小實踐內容。參考網上已有 重新配置編譯,效果不錯。人臉識別的庫使用的是haarcascade frontalface檔案,包含在opencv當中的。關鍵部分 如下 本原始碼只為學習交流之用 typersever from gzhu static cvmemstora...

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

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