校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁(yè) > 知識(shí)庫(kù) > 使用Python+OpenCV進(jìn)行卡類(lèi)型及16位卡號(hào)數(shù)字的OCR功能

使用Python+OpenCV進(jìn)行卡類(lèi)型及16位卡號(hào)數(shù)字的OCR功能

熱門(mén)標(biāo)簽:地圖標(biāo)注多個(gè) 企業(yè)微信地圖標(biāo)注 萊蕪電信外呼系統(tǒng) 銀川電話(huà)機(jī)器人電話(huà) 高德地圖標(biāo)注收入咋樣 沈陽(yáng)防封電銷(xiāo)電話(huà)卡 B52系統(tǒng)電梯外呼顯示E7 怎么辦理400客服電話(huà) 鶴壁手機(jī)自動(dòng)外呼系統(tǒng)違法嗎

這篇博客將介紹如何通過(guò)OpenCV和Python使用模板匹配執(zhí)行光學(xué)字符識(shí)別(OCR)。具體來(lái)說(shuō),將使用Python+OpenCV實(shí)現(xiàn)模板匹配算法,以自動(dòng)識(shí)別卡的類(lèi)型和以及16位卡號(hào)數(shù)字。

在比較數(shù)字時(shí),模板匹配是一種非常快速的方法。

為此將圖像處理管道分為4個(gè)步驟:

  1. 通過(guò)各種圖像處理技術(shù)檢測(cè)信用卡上四組四個(gè)數(shù)字,包括形態(tài)學(xué)操作、閾值和輪廓提取。
  2. 從四個(gè)分組中提取每個(gè)單獨(dú)的數(shù)字,得到16個(gè)需要分類(lèi)的數(shù)字。
  3. 將模板匹配應(yīng)用于每個(gè)數(shù)字,將其與OCR-A字體進(jìn)行比較,以獲得數(shù)字分類(lèi)。
  4. 檢查信用卡號(hào)的第一位數(shù)字以確定發(fā)卡公司。

在對(duì)信用卡OCR系統(tǒng)進(jìn)行評(píng)估后,發(fā)現(xiàn)如果發(fā)卡信用卡公司使用OCR-A字體作為數(shù)字,該系統(tǒng)的準(zhǔn)確率為100%。 優(yōu)化可以考慮在野外采集信用卡的真實(shí)圖像,并訓(xùn)練機(jī)器學(xué)習(xí)模型(通過(guò)標(biāo)準(zhǔn)特征提取或訓(xùn)練或卷積神經(jīng)網(wǎng)絡(luò)),以進(jìn)一步提高此系統(tǒng)的準(zhǔn)確性。

1. 效果圖

首先了解一下卡的組成:

OCR-A 參考字體識(shí)別如下:原始圖 VS 灰度圖 VS 閾值化圖 VS 輪廓每個(gè)數(shù)字提取圖:
灰度圖:忽略顏色對(duì)輪廓提取的影響
閾值化圖:使得輪廓在前景白色,背景黑色便于輪廓提取。
輪廓提取圖:提取每個(gè)數(shù)字ROI并記錄,方便后續(xù)對(duì)比卡片中的區(qū)域以識(shí)別出對(duì)應(yīng)的數(shù)字。

以下卡號(hào)均是演示卡,
正確的識(shí)別卡的類(lèi)型和卡號(hào),效果圖1:

識(shí)別過(guò)程1——原圖 VS 灰度圖 VS 白帽圖 VS 梯度圖如下:
灰度圖:忽略色彩影響
白帽圖:從較暗的背景中提取較亮的區(qū)域
梯度圖:計(jì)算Schaar梯度圖,便于了解圖像的色彩分配及提取;

識(shí)別過(guò)程2——形態(tài)學(xué)閉合圖 VS 二值化圖1 VS 閾值化圖2 如下:
形態(tài)學(xué)閉合圖:矩形框形態(tài)學(xué)閉合操作,以幫助閉合信用卡數(shù)字之間的小的縫隙
二值化圖:以便于提取
閾值化圖:方形框形態(tài)學(xué)閉合操作,以二次幫助閉合信用卡數(shù)字區(qū)域之間的縫隙

識(shí)別過(guò)程3——輪廓過(guò)濾圖 VS 提取最終效果圖 如下:
輪廓過(guò)濾圖:根據(jù)面積及縱橫比,只保留卡片中的卡號(hào)區(qū)
最終效果圖:提取4組4數(shù)字每一個(gè)組,然后對(duì)每一個(gè)組中的4個(gè)數(shù)字進(jìn)行截取ROI并識(shí)別,并與之前存儲(chǔ)的數(shù)字ROI進(jìn)行模板匹配,選取匹配值最高的作為最終結(jié)果。

2. 原理

2.1 OCR-A字體

OCR-A字體,是一種專(zhuān)門(mén)用于輔助光學(xué)字符識(shí)別算法的字體。

主要分為:

檢測(cè)圖像中信用卡的位置;本地化信用卡上的四組四位數(shù)字;應(yīng)用OCR識(shí)別信用卡上的16位數(shù)字;識(shí)別信用卡的類(lèi)型。

Tesseract庫(kù)在某些情況無(wú)法正確識(shí)別數(shù)字(這可能是因?yàn)門(mén)esseract未接受信用卡示例字體培訓(xùn))。

2.2 檢測(cè)過(guò)程步驟

在字典中存儲(chǔ)卡類(lèi)型映射關(guān)系(卡號(hào)的第一位數(shù)字代表卡類(lèi)型)。獲取參考圖像并提取數(shù)字。將數(shù)字模板存儲(chǔ)在字典中。本地化四個(gè)信用卡號(hào)組,每個(gè)組有四位數(shù)字(總共16位)。提取要“匹配”的數(shù)字。對(duì)每個(gè)數(shù)字執(zhí)行模板匹配,將每個(gè)單獨(dú)的ROI與每個(gè)數(shù)字模板0-9進(jìn)行比較,同時(shí)存儲(chǔ)每個(gè)嘗試匹配的分?jǐn)?shù)。查找每個(gè)候選數(shù)字的最高分?jǐn)?shù),并構(gòu)建一個(gè)名為“輸出”的列表。其中包含信用卡號(hào)。將信用卡號(hào)和信用卡類(lèi)型輸出到終端,并將輸出圖像顯示到屏幕上。

2.3 優(yōu)化

使用OpenCV和Python匹配OCR腳本的模板在100%的時(shí)間內(nèi)正確識(shí)別了16位數(shù)字中的每一位。然而在將OCR圖像應(yīng)用于真實(shí)的信用卡圖像時(shí),考慮到照明條件、視角和其他一般噪音的變化,可能需要采取更面向機(jī)器學(xué)習(xí)的方法。

3. 源代碼

# 信用卡類(lèi)型及卡號(hào)OCR系統(tǒng)
# USAGE
# python ocr_template_match.py --reference images/ocr_a_reference.png --image images/credit_card_05.png

import argparse

import cv2
import imutils
import numpy as np
# 導(dǎo)入必要的包
from imutils import contours

# 構(gòu)建命令行參數(shù)及解析
# --image 必須 要進(jìn)行OCR的輸入圖像
# --reference 必須 參考OCR-A圖像
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
                help="path to input image")
ap.add_argument("-r", "--reference", required=True,
                help="path to reference OCR-A image")
args = vars(ap.parse_args())

# 定義一個(gè)字典(映射信用卡第一位數(shù)字和信用卡類(lèi)型的編號(hào))
FIRST_NUMBER = {
    "3": "American Express",
    "4": "Visa",
    "5": "MasterCard",
    "6": "Discover Card"
}

# 從磁盤(pán)加載參考OCR-A圖像,轉(zhuǎn)換為灰度圖,閾值化圖像以顯示為白色前景和黑色背景
# 并反轉(zhuǎn)圖像
# and invert it, such that the digits appear as *white* on a *black*
ref_origin = cv2.imread(args["reference"])
cv2.imshow("ref_origin", ref_origin)
ref = ref_origin.copy()
ref = cv2.cvtColor(ref, cv2.COLOR_BGR2GRAY)
cv2.imshow("ref_gray", ref)
ref = cv2.threshold(ref, 180, 255, cv2.THRESH_BINARY)[1]
cv2.imshow("ref_threshhold", ref)
cv2.waitKey(0)

# 尋找OCR-A圖像中的輪廓(數(shù)字的外輪廓線(xiàn))
# 并從左到右排序輪廓,初始化一個(gè)字典來(lái)存儲(chǔ)數(shù)字ROI
refCnts = cv2.findContours(ref.copy(), cv2.RETR_EXTERNAL,
                           cv2.CHAIN_APPROX_SIMPLE)
print('findContours: ', len(refCnts))
refCnts = imutils.grab_contours(refCnts)
refCnts = contours.sort_contours(refCnts, method="left-to-right")[0]
digits = {}

# 遍歷OCR-A輪廓
for (i, c) in enumerate(refCnts):
    # 計(jì)算數(shù)字的邊界框,提取它,縮放到固定的大小
    (x, y, w, h) = cv2.boundingRect(c)
    cv2.rectangle(ref_origin, (x, y), (x + w, y + h), (0, 255, 0), 2)
    roi = ref[y:y + h, x:x + w]
    roi = cv2.resize(roi, (57, 88))

    # 更新數(shù)字字典,數(shù)字匹配ROI
    digits[i] = roi
cv2.imshow("ref and digits", ref_origin)
cv2.waitKey(0)

# 初始化矩形和方形結(jié)構(gòu)內(nèi)核
# 在圖像上滑動(dòng)它來(lái)進(jìn)行(卷積)操作,如模糊、銳化、邊緣檢測(cè)或其他圖像處理操作。
# 使用矩形函數(shù)作為T(mén)op-hat形態(tài)學(xué)運(yùn)算符,使用方形函數(shù)作為閉合運(yùn)算。
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))

# 準(zhǔn)備進(jìn)行OCR的輸入圖像
# 加載輸入圖像,保持縱橫比縮放圖像寬度為300,轉(zhuǎn)換為灰度圖
origin = cv2.imread(args["image"])
origin = imutils.resize(origin, width=300)
image = origin.copy()
cv2.imshow("origin", origin)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow("gray", gray)

# 執(zhí)行形態(tài)學(xué)操作
# 應(yīng)用tophat(白帽)形態(tài)學(xué)操作以在暗的背景中提取出亮的區(qū)域(信用卡上的數(shù)字卡號(hào))
# Top hat操作在深色背景(即信用卡號(hào))下顯示淺色區(qū)域
tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)
cv2.imshow("tophat", tophat)

# 計(jì)算Scharr梯度,計(jì)算梯度值
# 在白色禮帽上,計(jì)算x方向的Scharr梯度,然后縮放到范圍[0, 255]
gradX = cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=-1)
gradX = np.absolute(gradX)
(minVal, maxVal) = (np.min(gradX), np.max(gradX))
# 最小/最大歸一化, 由float轉(zhuǎn)換gradX到uint8范圍[0-255]
gradX = (255 * ((gradX - minVal) / (maxVal - minVal)))
gradX = gradX.astype("uint8")
cv2.imshow("gradient", gradX)

# 使用矩形框應(yīng)用閉合操作以幫助閉合信用卡數(shù)字之間的小的縫隙
# 應(yīng)用Otsu's閾值方法二值化圖像
gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel)
cv2.imshow("morphologyEx", gradX)
thresh = cv2.threshold(gradX, 0, 255,
                       cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv2.imshow("thresh1", thresh)

# 在二值化圖像上,應(yīng)用二次閉合操作
# 再一次方形框形態(tài)學(xué)操作,幫助閉合信用卡數(shù)字區(qū)域之間的縫隙
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel)
cv2.imshow("thresh2", thresh)

# 閾值圖像中查找輪廓,然后初始化數(shù)字位置列表
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
                        cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
locs = []

# 遍歷輪廓
for (i, c) in enumerate(cnts):
    # 計(jì)算輪廓的邊界框,并計(jì)算縱橫比
    (x, y, w, h) = cv2.boundingRect(c)
    ar = w / float(h)

    # 由于信用卡有固定的4組4數(shù)字,可以根據(jù)縱橫比來(lái)尋找潛在的輪廓
    if ar > 2.5 and ar  4.0:
        # 輪廓可以在最小/最大寬度上進(jìn)一步修剪
        if (w > 40 and w  55) and (h > 10 and h  20):
            # 添加數(shù)字組輪廓的編輯框輪廓到位置list
            locs.append((x, y, w, h))
            cv2.rectangle(origin, (x, y), (x + w, y + h), (255, 0, 0), -1)

cv2.imshow("contours filter", origin)
# 突出顯示信用卡上四組四位數(shù)字(總共十六位)。
# 從左到右排序輪廓,并初始化list來(lái)存儲(chǔ)信用卡數(shù)字列表
locs = sorted(locs, key=lambda x: x[0])
output = []

# 遍歷四組四位數(shù)字
for (i, (gX, gY, gW, gH)) in enumerate(locs):
    # 初始化存放每組數(shù)字的list
    groupOutput = []

    # 提取每組4位數(shù)字的灰度圖ROI
    # 應(yīng)用閾值方法從背景信用卡中分割數(shù)字
    group = gray[gY - 5:gY + gH + 5, gX - 5:gX + gW + 5]
    group = cv2.threshold(group, 0, 255,
                          cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]

    # 檢測(cè)組中每個(gè)單獨(dú)數(shù)字的輪廓
    # 從左到右排序輪廓
    digitCnts = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL,
                                 cv2.CHAIN_APPROX_SIMPLE)
    digitCnts = imutils.grab_contours(digitCnts)
    digitCnts = contours.sort_contours(digitCnts,
                                       method="left-to-right")[0]

    # 遍歷數(shù)字輪廓
    for c in digitCnts:
        # 計(jì)算每個(gè)單獨(dú)數(shù)字的邊界框
        # 提取數(shù)字,縮放以擁有和參考OCR-A字體模板圖像相同的大小
        (x, y, w, h) = cv2.boundingRect(c)
        roi = group[y:y + h, x:x + w]
        roi = cv2.resize(roi, (57, 88))

        # 初始化模板匹配分?jǐn)?shù)list
        scores = []

        # 遍歷參考數(shù)字名和數(shù)字ROI
        for (digit, digitROI) in digits.items():
            # 應(yīng)用基于相關(guān)性的模板匹配,計(jì)算分?jǐn)?shù),更新分?jǐn)?shù)list
            # apply correlation-based template matching, take the
            # score, and update the scores list
            result = cv2.matchTemplate(roi, digitROI,
                                       cv2.TM_CCOEFF)
            (_, score, _, _) = cv2.minMaxLoc(result)
            scores.append(score)

        # 數(shù)字ROI的分類(lèi)將取 模板匹配分?jǐn)?shù)中分?jǐn)?shù)最大的參考數(shù)字
        # the classification for the digit ROI will be the reference
        # digit name with the *largest* template matching score
        groupOutput.append(str(np.argmax(scores)))

    # 圍繞每組畫(huà)一個(gè)矩形,并以紅色文本標(biāo)識(shí)圖像上的信用卡號(hào)
    # 繪制每組的數(shù)字識(shí)別分類(lèi)結(jié)果
    cv2.rectangle(image, (gX - 5, gY - 5),
                  (gX + gW + 5, gY + gH + 5), (0, 0, 255), 2)
    cv2.putText(image, "".join(groupOutput), (gX, gY - 15),
                cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)

    # 更新輸出數(shù)字分組列表
    # Pythonic的方法是使用extend函數(shù),它將iterable對(duì)象的每個(gè)元素(本例中為列表)追加到列表的末尾
    output.extend(groupOutput)

# 顯示檢測(cè)到的信用卡類(lèi)型和卡號(hào)到屏幕上
print("Credit Card Type: {}".format(FIRST_NUMBER[output[0]]))
print("Credit Card #: {}".format("".join(output)))
cv2.imshow("Image", image)
cv2.waitKey(0)

參考 https://www.pyimagesearch.com/2017/07/17/credit-card-ocr-with-opencv-and-python/

到此這篇關(guān)于使用Pyhton+OpenCV進(jìn)行卡類(lèi)型及16位卡號(hào)數(shù)字的OCR功能的文章就介紹到這了,更多相關(guān)Pyhton+OpenCV卡號(hào)數(shù)字識(shí)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • Python內(nèi)置數(shù)據(jù)類(lèi)型list各方法的性能測(cè)試過(guò)程解析
  • python內(nèi)置數(shù)據(jù)類(lèi)型之列表操作
  • Python中內(nèi)置數(shù)據(jù)類(lèi)型list,tuple,dict,set的區(qū)別和用法
  • Python內(nèi)置數(shù)據(jù)類(lèi)型詳解
  • python基礎(chǔ)教程之基本內(nèi)置數(shù)據(jù)類(lèi)型介紹
  • 使用python svm實(shí)現(xiàn)直接可用的手寫(xiě)數(shù)字識(shí)別
  • python計(jì)算數(shù)字或者數(shù)組的階乘的實(shí)現(xiàn)
  • python數(shù)字轉(zhuǎn)對(duì)應(yīng)中文的方法總結(jié)
  • Python數(shù)字/字符串補(bǔ)零操作實(shí)例代碼
  • 怎么用Python識(shí)別手勢(shì)數(shù)字
  • Python的內(nèi)置數(shù)據(jù)類(lèi)型中的數(shù)字

標(biāo)簽:呼倫貝爾 銀川 湘西 安慶 烏魯木齊 葫蘆島 三亞 呼倫貝爾

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《使用Python+OpenCV進(jìn)行卡類(lèi)型及16位卡號(hào)數(shù)字的OCR功能》,本文關(guān)鍵詞  使用,Python+OpenCV,進(jìn)行,卡,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《使用Python+OpenCV進(jìn)行卡類(lèi)型及16位卡號(hào)數(shù)字的OCR功能》相關(guān)的同類(lèi)信息!
  • 本頁(yè)收集關(guān)于使用Python+OpenCV進(jìn)行卡類(lèi)型及16位卡號(hào)數(shù)字的OCR功能的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    主站蜘蛛池模板: 浪卡子县| 建平县| 新巴尔虎左旗| 深圳市| 连山| 通化县| 阳城县| 茌平县| 南陵县| 错那县| 抚松县| 西和县| 宁河县| 井陉县| 松桃| 石家庄市| 手游| 尚志市| 乡城县| 华阴市| 登封市| 奉化市| 阿瓦提县| 英德市| 淄博市| 尼玛县| 昆山市| 乐陵市| 潮州市| 陆丰市| 海门市| 崇礼县| 贵定县| 吴旗县| 芦山县| 唐海县| 双辽市| 岚皋县| 西乡县| 山西省| 广平县|