0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

OpenCV的數(shù)字識別實(shí)踐案例

華為開發(fā)者社區(qū) ? 來源:CSDN技術(shù)社區(qū) ? 作者:華為云 ? 2021-03-26 17:16 ? 次閱讀

前言

實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn)。因?yàn)橛X得一板一眼地學(xué)習(xí)OpenCV太過枯燥,于是在網(wǎng)上找了一個(gè)以項(xiàng)目為導(dǎo)向的教程學(xué)習(xí)。話不多說,動(dòng)手做起來。

1、案例介紹

提供信用卡上的數(shù)字模板:

要求:識別出信用卡上的數(shù)字,并將其直接打印在原圖片上。雖然看起來很蠢,但既然可以將數(shù)字打印在圖片上,說明已經(jīng)成功識別數(shù)字,因此也可以將其轉(zhuǎn)換為數(shù)字文本保存。車牌號識別等項(xiàng)目的思路與此案例類似。

示例:

原圖

處理后的圖

步驟

大致分為如下幾個(gè)步驟:

1.模板讀入

2.模板預(yù)處理,將模板數(shù)字分開,并排序

3.輸入圖像預(yù)處理,將圖像中的數(shù)字部分提取出來

4.將數(shù)字與模板數(shù)字進(jìn)行匹配,匹配率最高的即為對應(yīng)數(shù)字。

1、模板讀入,以及一些包的導(dǎo)入,函數(shù)定義等

import cv2 as cvimport numpy as npimport myutilsdef cv_show(name, img): # 自定義的展示函數(shù) cv.imshow(name, img) cv.waitKey(0)# 讀入模板圖n = ‘text’img = cv.imread(“images/ocr_a_reference.png”)# cv_show(n, template) # 自定義的展示函數(shù),方便顯示圖

2、模板預(yù)處理,將模板數(shù)字分開,并排序

模板的預(yù)處理順序:灰度圖,二值化,再進(jìn)行輪廓檢測。需要注意的是openCV檢測輪廓時(shí)是檢測白色邊框,因此要將模板圖的數(shù)字二值化變?yōu)榘咨?/p>

# 模板轉(zhuǎn)換為灰度圖ref = cv.cvtColor(img, cv.COLOR_BGR2GRAY)# cv_show(n, ref)

# 轉(zhuǎn)換為二值圖,把數(shù)字部分變?yōu)榘咨玶ef = cv.threshold(ref, 10, 255, cv.THRESH_BINARY_INV)[1] # 騷寫法,函數(shù)多個(gè)返回值為元組,這里取第二個(gè)返回值cv_show(n, ref)

# 對模板進(jìn)行輪廓檢測,得到輪廓信息refCnts, hierarchy = cv.findContours(ref.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE)cv.drawContours(img, refCnts, -1, (0, 0, 255), 2) # 第一個(gè)參數(shù)為目標(biāo)圖像# cv_show(n, img

紅色部分即為檢測出的輪廓。接下來進(jìn)行輪廓排序,因?yàn)闄z測出的輪廓是無序的,因此要按照輪廓的左上角點(diǎn)的x坐標(biāo)來排序。輪廓排序后按順序放入字典,則字典中的鍵值對是正確匹配的,如‘0’對應(yīng)輪廓0 ,‘1’對應(yīng)輪廓1。

# 輪廓排序refCnts = myutils.sort_contours(refCnts)[0]digits = {}

# 單個(gè)輪廓提取到字典中for (i, c) in enumerate(refCnts): (x, y, w, h) = cv.boundingRect(c) roi = ref[y:y + h, x:x + w] # 在模板中復(fù)制出輪廓 roi = cv.resize(roi, (57, 88)) # 改成相同大小的輪廓 digits[i] = roi # 此時(shí)字典鍵對應(yīng)的輪廓即為對應(yīng)數(shù)字。如鍵‘1’對應(yīng)輪廓‘1’

至此,模板圖處理完畢。

3、輸入圖像預(yù)處理,將圖像中的數(shù)字部分提取出來

在此步驟中需要將信用卡上的每個(gè)數(shù)字提取出來,并與上一步得到的模板一一匹配。首先初始化卷積核,方便之后tophat操作以及閉運(yùn)算操作使用。

# 初始化卷積核rectKernel = cv.getStructuringElement(cv.MORPH_RECT, (9, 3))sqKernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))

接下來讀入圖片,調(diào)整圖片大小,轉(zhuǎn)換為灰度圖。

# 待分析圖片讀入,預(yù)處理card_image = cv.imread(“images/credit_card_01.png”)# cv_show(‘a(chǎn)’, card_image)card_image = myutils.resize(card_image, width=300) # 更改圖片大小gray = cv.cvtColor(card_image, cv.COLOR_BGR2GRAY)# cv_show(‘gray’, gray)

然后進(jìn)行tophat操作,tophat可以突出圖片中明亮的區(qū)域,過濾掉較暗的部分:

tophat = cv.morphologyEx(gray, cv.MORPH_TOPHAT, rectKernel)# cv_show(‘tophat’, tophat)

再通過sobel算子檢測邊緣,進(jìn)行一次閉操作,二值化,再進(jìn)行一次閉操作,填補(bǔ)空洞。

# x方向的Sobel算子gradX = cv.Sobel(tophat, cv.CV_32F, 1, 0, ksize=3)

gradX = np.absolute(gradX) # absolute: 計(jì)算絕對值min_Val, max_val = np.min(gradX), np.max(gradX)gradX = (255 * (gradX - min_Val) / (max_val - min_Val))gradX = gradX.astype(“uint8”)

# 通過閉操作(先膨脹,再腐蝕)將數(shù)字連在一起。 將本是4個(gè)數(shù)字的4個(gè)框膨脹成1個(gè)框,就腐蝕不掉了gradX = cv.morphologyEx(gradX, cv.MORPH_CLOSE, rectKernel)# cv_show(‘close1’, gradX)

# 二值化thresh = cv.threshold(gradX, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)[1]

# 閉操作,填補(bǔ)空洞thresh = cv.morphologyEx(thresh, cv.MORPH_CLOSE, sqKernel)# cv_show(‘close2’, thresh)

之后就可以查找輪廓了。

threshCnts = cv.findContours(thresh.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)[0]card_copy = card_image.copy()cv.drawContours(card_copy, threshCnts, -1, (0, 0, 255), 2)cv_show(‘Input_Contours’, card_copy)

4、模板匹配

將模板數(shù)字和待識別的圖片都處理好后,就可以進(jìn)行匹配了。

locs = [] # 存符合條件的輪廓for i, c in enumerate(threshCnts): # 計(jì)算矩形 x, y, w, h = cv.boundingRect(c)

ar = w / float(h) # 選擇合適的區(qū)域,根據(jù)實(shí)際任務(wù)來,這里的基本都是四個(gè)數(shù)字一組 if 2.5 《 ar 《 4.0: if (40 《 w 《 55) and (10 《 h 《 20): # 符合的留下來 locs.append((x, y, w, h))

# 將符合的輪廓從左到右排序locs = sorted(locs, key=lambda x: x[0])

接下來,遍歷每一個(gè)大輪廓,每個(gè)大輪廓中有四個(gè)數(shù)字,對應(yīng)四個(gè)小輪廓。將小輪廓與模板匹配。

output = [] # 存正確的數(shù)字for (i, (gx, gy, gw, gh)) in enumerate(locs): # 遍歷每一組大輪廓(包含4個(gè)數(shù)字) groupOutput = []

# 根據(jù)坐標(biāo)提取每一個(gè)組(4個(gè)值) group = gray[gy - 5:gy + gh + 5, gx - 5:gx + gw + 5] # 往外擴(kuò)一點(diǎn) # cv_show(‘group_’ + str(i), group) # 預(yù)處理 group = cv.threshold(group, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)[1] # 二值化的group # cv_show(‘group_’+str(i),group) # 計(jì)算每一組的輪廓 這樣就分成4個(gè)小輪廓了 digitCnts = cv.findContours(group.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)[0] # 排序 digitCnts = myutils.sort_contours(digitCnts, method=“l(fā)eft-to-right”)[0]

# 計(jì)算并匹配每一組中的每一個(gè)數(shù)值 for c in digitCnts: # c表示每個(gè)小輪廓的終點(diǎn)坐標(biāo) z = 0 # 找到當(dāng)前數(shù)值的輪廓,resize成合適的的大小 (x, y, w, h) = cv.boundingRect(c) # 外接矩形 roi = group[y:y + h, x:x + w] # 在原圖中取出小輪廓覆蓋區(qū)域,即數(shù)字 roi = cv.resize(roi, (57, 88)) # cv_show(“roi_”+str(z),roi)

# 計(jì)算匹配得分: 0得分多少,1得分多少。.. scores = [] # 單次循環(huán)中,scores存的是一個(gè)數(shù)值 匹配 10個(gè)模板數(shù)值的最大得分

# 在模板中計(jì)算每一個(gè)得分 # digits的digit正好是數(shù)值0,1,。..,9;digitROI是每個(gè)數(shù)值的特征表示 for (digit, digitROI) in digits.items(): # 進(jìn)行模板匹配, res是結(jié)果矩陣 res = cv.matchTemplate(roi, digitROI, cv.TM_CCOEFF) # 此時(shí)roi是X digitROI是0 依次是1,2.。 匹配10次,看模板最高得分多少 Max_score = cv.minMaxLoc(res)[1] # 返回4個(gè),取第二個(gè)最大值Maxscore scores.append(Max_score) # 10個(gè)最大值 # print(“scores:”,scores) # 得到最合適的數(shù)字 groupOutput.append(str(np.argmax(scores))) # 返回的是輸入列表中最大值的位置 z = z + 1# 畫出來 cv.rectangle(card_image, (gx - 5, gy - 5), (gx + gw + 5, gy + gh + 5), (0, 0, 255), 1) # 左上角,右下角# putText參數(shù):圖片,添加的文字,左上角坐標(biāo),字體,字體大小,顏色,字體粗細(xì) cv.putText(card_image, “”.join(groupOutput), (gx, gy - 15), cv.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)

最后將其打印出來,任務(wù)就完成了。

cv.imshow(“Output_image_”+str(i), card_image)cv.waitKey(0)

總結(jié)

信用卡識別的案例用到了圖像處理的一些基本操作,對剛上手CV的人來說還是比較友好的。
編輯:lyn

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 數(shù)字識別
    +關(guān)注

    關(guān)注

    2

    文章

    19

    瀏覽量

    10123
  • OpenCV
    +關(guān)注

    關(guān)注

    29

    文章

    622

    瀏覽量

    41091

原文標(biāo)題:OpenCV萌新福音:易上手的數(shù)字識別實(shí)踐案例

文章出處:【微信號:Huawei_Developer,微信公眾號:華為開發(fā)者社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    OpenCV圖像識別C++代碼

    安裝OpenCV庫 首先,您需要在您的計(jì)算機(jī)上安裝OpenCV庫。您可以從OpenCV官網(wǎng)下載預(yù)編譯的庫或從源代碼編譯。安裝完成后,確保將OpenCV的頭文件和庫文件添加到您的項(xiàng)目中。
    的頭像 發(fā)表于 07-16 10:42 ?1103次閱讀

    opencv圖像識別有什么算法

    OpenCV(Open Source Computer Vision Library)是一個(gè)開源的計(jì)算機(jī)視覺和機(jī)器學(xué)習(xí)軟件庫,提供了大量的圖像處理和計(jì)算機(jī)視覺相關(guān)的算法。以下是一些常見的OpenCV
    的頭像 發(fā)表于 07-16 10:40 ?375次閱讀

    opencv-python和opencv一樣嗎

    不一樣。OpenCV(Open Source Computer Vision Library)是一個(gè)開源的計(jì)算機(jī)視覺和機(jī)器學(xué)習(xí)軟件庫,它提供了大量的圖像和視頻處理功能。OpenCV
    的頭像 發(fā)表于 07-16 10:38 ?453次閱讀

    基于OpenCV的人臉識別系統(tǒng)設(shè)計(jì)

    基于OpenCV的人臉識別系統(tǒng)是一個(gè)復(fù)雜但功能強(qiáng)大的系統(tǒng),廣泛應(yīng)用于安全監(jiān)控、人機(jī)交互、智能家居等多個(gè)領(lǐng)域。下面將詳細(xì)介紹基于OpenCV的人臉識別系統(tǒng)的基本原理、實(shí)現(xiàn)步驟,并附上具體
    的頭像 發(fā)表于 07-11 15:37 ?1.1w次閱讀

    嵌入式學(xué)習(xí)-飛凌ElfBoard ELF 1板卡 - 如何在Ubuntu中編譯OpenCV

    Ubuntu環(huán)境下編譯X86架構(gòu)的OpenCV,這為快速迭代產(chǎn)品、優(yōu)化算法提供了堅(jiān)實(shí)的支撐。希望本篇指南能成為各位小伙伴在嵌入式技術(shù)探索之旅上的得力助手。如果您在實(shí)踐過程中遇到任何問題,歡迎留言交流。
    發(fā)表于 06-07 09:21

    使用OpenCV進(jìn)行儀表指針刻度的識別與讀取

    首先說一下模板匹配,它是OpenCV自帶的一個(gè)算法,可以根據(jù)一個(gè)模板圖到目標(biāo)圖上去尋找對應(yīng)位置,如果模板找的比較好那么效果顯著,這里說一下尋找模板的技巧,模板一定要標(biāo)準(zhǔn)、精準(zhǔn)且特征明顯。
    發(fā)表于 02-22 13:54 ?1521次閱讀
    使用<b class='flag-5'>OpenCV</b>進(jìn)行儀表指針刻度的<b class='flag-5'>識別</b>與讀取

    ELF 1技術(shù)貼|如何移植OpenCV

    ,OpenCV擁有了豐富的常用圖像處理函數(shù)庫,采用C/C++語言編寫,可以運(yùn)行在Linux、Windows、Mac等操作系統(tǒng)上流暢運(yùn)行,并能夠快速實(shí)現(xiàn)一系列圖像處理和識別
    的頭像 發(fā)表于 01-09 13:55 ?289次閱讀
    ELF 1技術(shù)貼|如何移植<b class='flag-5'>OpenCV</b>

    OpenCV對openEuler提供上游原生支持

    ),是一個(gè)多平臺的開源計(jì)算機(jī)視覺庫。它提供了豐富的功能,包括圖像處理,特征檢測,目標(biāo)識別,機(jī)器學(xué)習(xí)等,在計(jì)算機(jī)視覺領(lǐng)域,OpenCV憑借其強(qiáng)大的功能、性能和廣泛的應(yīng)用場景,已經(jīng)建立起絕對的領(lǐng)導(dǎo)
    的頭像 發(fā)表于 11-20 09:14 ?683次閱讀

    情感語音識別的研究方法與實(shí)踐

    一、引言 情感語音識別是指通過計(jì)算機(jī)技術(shù)和人工智能算法自動(dòng)識別和理解人類語音中的情感信息。為了提高情感語音識別的準(zhǔn)確性,本文將探討情感語音識別的研究方法與
    的頭像 發(fā)表于 11-16 16:26 ?708次閱讀

    基于OpenVINO+OpenCV的OCR處理流程化實(shí)現(xiàn)

    預(yù)處理主要是基于OpenCV、場景文字檢測與識別基于OpenVINO框架 + PaddleOCR模型完成。直接按圖索驥即可得到最終結(jié)果。 OpenCV預(yù)處理主要是完成偏斜矯正、背景矯正等操作,然后使用場景文字檢測模型+OCR
    的頭像 發(fā)表于 11-07 11:21 ?618次閱讀
    基于OpenVINO+<b class='flag-5'>OpenCV</b>的OCR處理流程化實(shí)現(xiàn)

    智能車識別圖an用openmv還是用opencv

    智能車創(chuàng)意組識別圖an用openmv 還是用 opencv 比較好
    發(fā)表于 10-24 06:24

    OpenCV 如何加載圖片

    之前也寫過一些 OpenCV 的文章,最近正好在考慮 寫一個(gè) OpenCV相關(guān)的工具,目前還是在開發(fā)過程中,邊開發(fā)邊更新。預(yù)計(jì)會(huì)持續(xù)一段時(shí)間。目前的想法是把 OpenCV 的 API 在這個(gè)工具上都
    的頭像 發(fā)表于 10-09 15:01 ?605次閱讀

    高速數(shù)字系統(tǒng)設(shè)計(jì)—互連理論和設(shè)計(jì)實(shí)踐手冊

    高速數(shù)字系統(tǒng)設(shè)計(jì)——互連理論和設(shè)計(jì)實(shí)踐手冊
    發(fā)表于 09-28 07:49

    【幸狐Core3566模組試用體驗(yàn)】基于openCV的貓臉識別

    本文主要介紹如何基于openCV來實(shí)現(xiàn)一個(gè)簡單的貓臉識別應(yīng)用。
    的頭像 發(fā)表于 09-25 09:05 ?842次閱讀
    【幸狐Core3566模組試用體驗(yàn)】基于<b class='flag-5'>openCV</b>的貓臉<b class='flag-5'>識別</b>

    【幸狐 Core3566 模組試用體驗(yàn)】基于openCV的貓臉識別

    本文主要介紹如何基于openCV來實(shí)現(xiàn)一個(gè)簡單的貓臉識別應(yīng)用。 一、基礎(chǔ)準(zhǔn)備 首先需要安裝openCV,因?yàn)閜ython版的方便點(diǎn),所以直接安裝python版openCV,通過命令su
    發(fā)表于 09-24 23:50