最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python使用OpenCV實(shí)現(xiàn)銀行卡卡號(hào)識(shí)別

 更新時(shí)間:2026年01月22日 09:43:04   作者:子夜江寒  
該文章詳細(xì)介紹了使用Python和OpenCV庫(kù)實(shí)現(xiàn)銀行卡卡號(hào)識(shí)別的流程,包括圖像預(yù)處理、模板匹配、數(shù)字分割和識(shí)別等步驟,并提供了詳細(xì)的代碼示例和參數(shù)說(shuō)明,需要的朋友可以參考下

一、流程概述

采用經(jīng)典的圖像處理流程,主要分為兩個(gè)核心階段:

  1. 模板預(yù)處理階段:預(yù)先處理標(biāo)準(zhǔn)OCR-A字體模板,提取并存儲(chǔ)每個(gè)數(shù)字的特征模板
  2. 卡號(hào)識(shí)別階段:對(duì)輸入的銀行卡圖像進(jìn)行多步處理,定位卡號(hào)區(qū)域,分割單個(gè)數(shù)字,通過(guò)模板匹配實(shí)現(xiàn)識(shí)別

整個(gè)系統(tǒng)基于OpenCV庫(kù)實(shí)現(xiàn)。

二、環(huán)境配置與參數(shù)設(shè)置

import numpy as np
import argparse
import cv2
import myutils
from imutils import contours

模塊作用分析:

  • numpy:提供高效的數(shù)值計(jì)算和數(shù)組操作
  • argparse:Python內(nèi)置庫(kù),用于解析命令行參數(shù)
  • cv2:OpenCV庫(kù),核心圖像處理功能
  • myutils:自定義工具模塊,包含輪廓排序等輔助函數(shù)
  • imutils.contours:提供輪廓處理的便捷函數(shù)

三、命令行參數(shù)配置

# 設(shè)置參數(shù)
ap = argparse.ArgumentParser()  # 創(chuàng)建ArgumentParser對(duì)象,用于定義和解析命令行參數(shù)
ap.add_argument("-i", "--image", required=True, help="path to input image")
ap.add_argument("-t", "--template", required=True, help="path to template OCR-A image")
args = vars(ap.parse_args())  # 將參數(shù)轉(zhuǎn)換為字典格式,便于訪問(wèn)

# 使用示例:
# python demo47.py -i card1.png -t kahao.png

參數(shù)說(shuō)明:

  • -i/--image:必需參數(shù),指定待識(shí)別的銀行卡圖像路徑
  • -t/--template:必需參數(shù),指定OCR-A模板圖像路徑

四、銀行卡類(lèi)型定義

# 根據(jù)卡號(hào)首位數(shù)字判斷銀行卡類(lèi)型
FIRST_NUMBER = {
    "3": "American Express",   # 美國(guó)運(yùn)通卡
    "4": "Visa",              # Visa卡
    "5": "MasterCard",        # 萬(wàn)事達(dá)卡
    "6": "Discover Card"      # 發(fā)現(xiàn)卡
}

這個(gè)字典基于銀行卡號(hào)的行業(yè)標(biāo)準(zhǔn):首位數(shù)字3代表美國(guó)運(yùn)通,4代表Visa,5代表萬(wàn)事達(dá),6代表發(fā)現(xiàn)卡。

五、輔助函數(shù)定義

def cv_show(name, img):  # 圖像顯示函數(shù)
    """顯示圖像并等待按鍵響應(yīng)"""
    cv2.imshow(name, img)
    cv2.waitKey(0)

這是一個(gè)簡(jiǎn)單的圖像顯示封裝函數(shù),便于在開(kāi)發(fā)過(guò)程中可視化各個(gè)處理階段的結(jié)果。

六、模板圖像預(yù)處理

6.1 模板加載與初步處理

# 讀取并顯示模板圖像
img = cv2.imread(args["template"])
cv_show('img', img)

# 轉(zhuǎn)換為灰度圖像
ref = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv_show('ref', ref)

# 二值化處理:黑底白字,便于輪廓檢測(cè)
ref = cv2.threshold(ref, 10, 255, cv2.THRESH_BINARY_INV)[1]
cv_show('ref', ref)

關(guān)鍵步驟解析:

  1. 灰度轉(zhuǎn)換:將彩色 圖像轉(zhuǎn)換為單通道灰度圖,減少計(jì)算復(fù)雜度
  2. 二值化:使用閾值處理,將圖像轉(zhuǎn)換為純黑白兩色,便于輪廓提取
  3. THRESH_BINARY_INV:反向二值化,生成黑底白字效果

6.2 輪廓提取與數(shù)字模板建立

# 檢測(cè)輪廓(只檢測(cè)外輪廓)
_, refCnts, hierarchy = cv2.findContours(ref.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 在原始圖像上繪制輪廓(紅色)
cv2.drawContours(img, refCnts, -1, (0, 0, 255), 3)
cv_show('refCnts', img)

# 對(duì)輪廓從左到右排序
refCnts = myutils.sort_contours(refCnts, method="left-to-right")[0]
digits = {}  # 存儲(chǔ)數(shù)字模板的字典

# 提取每個(gè)數(shù)字作為模板
for (i, c) in enumerate(refCnts):  # 遍歷每個(gè)數(shù)字輪廓
    # 計(jì)算輪廓的外接矩形
    (x, y, w, h) = cv2.boundingRect(c)
    
    # 提取數(shù)字區(qū)域并縮放到統(tǒng)一尺寸
    roi = ref[y:y + h, x:x + w]
    roi = cv2.resize(roi, (57, 88))  # 標(biāo)準(zhǔn)化尺寸
    cv_show('roi', roi)
    
    digits[i] = roi  # 存儲(chǔ)模板:鍵為數(shù)字,值為模板圖像

技術(shù)細(xì)節(jié):

  • cv2.findContours():在二值圖像中查找輪廓
  • RETR_EXTERNAL:僅檢測(cè)最外層輪廓
  • CHAIN_APPROX_SIMPLE:壓縮輪廓點(diǎn),減少內(nèi)存使用
  • 模板標(biāo)準(zhǔn)化:將所有數(shù)字縮放到57×88像素,確保后續(xù)匹配的準(zhǔn)確性

七、銀行卡圖像處理流程

7.1 圖像加載與初步調(diào)整

# 讀取待識(shí)別圖像
image = cv2.imread(args["image"])
cv_show('image', image)

# 調(diào)整圖像尺寸,保持寬高比
image = myutils.resize(image, width=300)

# 轉(zhuǎn)換為灰度圖像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv_show('gray', gray)

寬度統(tǒng)一調(diào)整為300像素,既保證處理速度,又維持足夠的分辨率。

7.2 形態(tài)學(xué)處理突出數(shù)字區(qū)域

# 定義形態(tài)學(xué)操作的卷積核
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))

# 頂帽操作:突出亮色細(xì)節(jié),抑制背景
tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)
open_img = cv2.morphologyEx(gray, cv2.MORPH_OPEN, rectKernel)
cv_show('open', open_img)
cv_show('tophat', tophat)

形態(tài)學(xué)操作原理:

  • 頂帽操作:原始圖像減去開(kāi)運(yùn)算結(jié)果,突出比背景亮的細(xì)小區(qū)域
  • 開(kāi)運(yùn)算:先腐蝕后膨脹,消除小物體,平滑邊界
  • 銀行卡數(shù)字通常比背景亮,頂帽操作能有效突出這些數(shù)字

7.3 數(shù)字區(qū)域定位與提取

# 第一次閉操作:連接相近的數(shù)字
closeX = cv2.morphologyEx(tophat, cv2.MORPH_CLOSE, rectKernel)
cv_show('close1', closeX)

# 自適應(yīng)閾值二值化
thresh = cv2.threshold(closeX, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv_show('thresh', thresh)

# 第二次閉操作:進(jìn)一步連接數(shù)字區(qū)域
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel)
cv_show('close2', thresh)

閉操作的作用:通過(guò)先膨脹后腐蝕,連接相鄰的白色區(qū)域(數(shù)字),將分散的數(shù)字點(diǎn)連接成完整的數(shù)字組。

7.4 數(shù)字組輪廓檢測(cè)與篩選

# 檢測(cè)輪廓
_, cnts, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 可視化所有輪廓
cnts_img = image.copy()
cv2.drawContours(cnts_img, cnts, -1, (0, 0, 255), 3)
cv_show('cnts_img', cnts_img)

# 篩選符合條件的輪廓(銀行卡號(hào)區(qū)域)
locs = []
for c in cnts:
    (x, y, w, h) = cv2.boundingRect(c)  # 獲取外接矩形
    ar = w / float(h)  # 寬高比
    
    # 篩選條件:寬高比和尺寸范圍
    if 2.5 < ar < 4.0:  # 銀行卡號(hào)區(qū)域的典型寬高比
        if (40 < w < 55) and (10 < h < 20):  # 尺寸范圍
            locs.append((x, y, w, h))

# 按x坐標(biāo)排序(從左到右)
locs = sorted(locs, key=lambda x: x[0])

篩選邏輯:

  • 寬高比2.5-4.0:匹配銀行卡號(hào)區(qū)域的長(zhǎng)條形特征
  • 寬度40-55像素,高度10-20像素:匹配標(biāo)準(zhǔn)尺寸

八、數(shù)字識(shí)別核心算法

8.1 單個(gè)數(shù)字組處理

output = []  # 存儲(chǔ)最終識(shí)別結(jié)果

# 遍歷每個(gè)數(shù)字組(通常一組4個(gè)數(shù)字)
for (gx, gy, gw, gh) in locs:
    groupOutput = []  # 存儲(chǔ)當(dāng)前組的識(shí)別結(jié)果
    
    # 提取數(shù)字組區(qū)域,添加5像素邊界
    group = gray[gy - 5:gy + gh + 5, gx - 5:gx + gw + 5]
    cv_show('group', group)
    
    # 對(duì)數(shù)字組進(jìn)行二值化
    group = cv2.threshold(group, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
    cv_show('group', group)
    
    # 檢測(cè)組內(nèi)每個(gè)數(shù)字的輪廓
    _, digitCnts, _ = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    digitCnts = myutils.sort_contours(digitCnts, method="left-to-right")[0]

8.2 模板匹配識(shí)別數(shù)字

    # 識(shí)別組內(nèi)每個(gè)數(shù)字
    for c in digitCnts:
        # 提取單個(gè)數(shù)字區(qū)域
        (x, y, w, h) = cv2.boundingRect(c)
        roi = group[y:y + h, x:x + w]
        roi = cv2.resize(roi, (57, 88))  # 縮放到模板相同尺寸
        cv_show('roi', roi)
        
        # 模板匹配:計(jì)算與每個(gè)模板的相似度
        scores = []
        for (digit, digitROI) in digits.items():
            # 使用相關(guān)系數(shù)匹配法
            result = cv2.matchTemplate(roi, digitROI, cv2.TM_CCOEFF)
            (_, score, _, _) = cv2.minMaxLoc(result)
            scores.append(score)
        
        # 選擇最高得分的數(shù)字
        groupOutput.append(str(np.argmax(scores)))

模板匹配原理:

  • cv2.matchTemplate():在輸入圖像中搜索與模板匹配的區(qū)域
  • TM_CCOEFF:相關(guān)系數(shù)匹配方法,對(duì)光照變化魯棒
  • np.argmax(scores):返回最高得分的索引,即識(shí)別出的數(shù)字

8.3 結(jié)果可視化

    # 繪制數(shù)字組矩形框(紅色)
    cv2.rectangle(image, (gx - 5, gy - 5), (gx + gw + 5, gy + gh + 5), (0, 0, 255), 1)
    
    # 在矩形上方顯示識(shí)別結(jié)果(紅色)
    cv2.putText(image, "".join(groupOutput), (gx, gy - 15),
                cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)
    
    # 添加到總結(jié)果
    output.extend(groupOutput)

九、最終結(jié)果輸出

# 輸出銀行卡類(lèi)型和完整卡號(hào)
print("Credit Card Type: {}".format(FIRST_NUMBER.get(output[0], "Unknown")))
print("Credit Card #: {}".format("".join(output)))

# 顯示最終處理結(jié)果
cv2.imshow("Image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

以上就是Python使用OpenCV實(shí)現(xiàn)銀行卡卡號(hào)識(shí)別的詳細(xì)內(nèi)容,更多關(guān)于Python OpenCV銀行卡卡號(hào)識(shí)別的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python使用WebSocket和SSE實(shí)現(xiàn)HTTP服務(wù)器消息推送方式

    Python使用WebSocket和SSE實(shí)現(xiàn)HTTP服務(wù)器消息推送方式

    本文介紹了兩種實(shí)時(shí)數(shù)據(jù)獲取的技術(shù):WebSocket和SSE,WebSocket是全雙工通信協(xié)議,支持雙向通信,但需要專門(mén)定義數(shù)據(jù)協(xié)議,SSE是一種單工通信技術(shù),基于HTTP的流式數(shù)據(jù)傳輸,客戶端開(kāi)發(fā)簡(jiǎn)單,但只能單工通信
    2024-11-11
  • 通過(guò)Python把學(xué)姐照片做成拼圖游戲

    通過(guò)Python把學(xué)姐照片做成拼圖游戲

    馬上就到畢業(yè)季了,你心中的那個(gè)學(xué)姐,你真的放下了嗎?本文將用pygame為你的學(xué)姐,定制開(kāi)發(fā)一個(gè)拼圖游戲,感興趣的快跟隨小編一起學(xué)習(xí)一下
    2022-02-02
  • python連接sql server亂碼的解決方法

    python連接sql server亂碼的解決方法

    為解決python連接sql server是出現(xiàn)的亂碼,需要在連接sql server 時(shí)指定字符集utf8(client charset = UTF-8),python環(huán)境制定了字符集變量(#coding=utf-8 )
    2013-01-01
  • Python技巧之四種多線程應(yīng)用分享

    Python技巧之四種多線程應(yīng)用分享

    這篇文章主要介紹了Python中多線程的所有方式,包括使用threading模塊、使用concurrent.futures模塊、使用multiprocessing模塊以及使用asyncio模塊,希望對(duì)大家有所幫助
    2023-05-05
  • python?字符串常用方法超詳細(xì)梳理總結(jié)

    python?字符串常用方法超詳細(xì)梳理總結(jié)

    字符串是Python中基本的數(shù)據(jù)類(lèi)型,幾乎在每個(gè)Python程序中都會(huì)使用到它。本文為大家總結(jié)了Python中必備的31個(gè)字符串方法,需要的可以參考一下
    2022-03-03
  • python實(shí)現(xiàn)多線程的方式及多條命令并發(fā)執(zhí)行

    python實(shí)現(xiàn)多線程的方式及多條命令并發(fā)執(zhí)行

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)多線程的方式及多條命令并發(fā)執(zhí)行,感興趣的小伙伴們可以參考一下
    2016-06-06
  • python實(shí)現(xiàn)對(duì)excel的覆蓋和追加操作

    python實(shí)現(xiàn)對(duì)excel的覆蓋和追加操作

    這篇文章主要為大家詳細(xì)介紹了如何使用python實(shí)現(xiàn)對(duì)excel的覆蓋和追加操作,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2026-05-05
  • Windows下python3.7安裝教程

    Windows下python3.7安裝教程

    這篇文章主要為大家詳細(xì)介紹了Windows下python3.7安裝教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • Python網(wǎng)絡(luò)編程中urllib2模塊的用法總結(jié)

    Python網(wǎng)絡(luò)編程中urllib2模塊的用法總結(jié)

    使用urllib2模塊進(jìn)行基于url的HTTP請(qǐng)求等操作大家也許都比較熟悉,這里我們?cè)偕钊雭?lái)了解一下urllib2針對(duì)HTTP的異常處理相關(guān)功能,一起來(lái)看一下Python網(wǎng)絡(luò)編程中urllib2模塊的用法總結(jié):
    2016-07-07
  • tensorflow實(shí)現(xiàn)訓(xùn)練變量checkpoint的保存與讀取

    tensorflow實(shí)現(xiàn)訓(xùn)練變量checkpoint的保存與讀取

    今天小編就為大家分享一篇tensorflow實(shí)現(xiàn)訓(xùn)練變量checkpoint的保存與讀取,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-02-02

最新評(píng)論

柏乡县| 靖安县| 瑞金市| 新乡县| 怀宁县| 望谟县| 本溪市| 达拉特旗| 绥阳县| 繁昌县| 朔州市| 肥城市| 古田县| 汉寿县| 包头市| 鲁山县| 扎囊县| 精河县| 潼关县| 罗源县| 突泉县| 通榆县| 灵川县| 伊川县| 灵石县| 泗洪县| 丹棱县| 邹平县| 山阴县| 林甸县| 八宿县| 永康市| 枣庄市| 福建省| 山东| 含山县| 临澧县| 礼泉县| 昌平区| 芦溪县| 商洛市|