欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python?實(shí)現(xiàn)銀行卡號(hào)查詢銀行名稱和簡(jiǎn)稱功能

 更新時(shí)間:2023年11月23日 14:21:24   作者:Roc-xb  
這篇文章主要介紹了python?實(shí)現(xiàn)銀行卡號(hào)查詢銀行名稱和簡(jiǎn)稱功能,本文通過(guò)實(shí)例代碼補(bǔ)充介紹了基于PyQT5+OpenCv實(shí)現(xiàn)銀行卡號(hào)識(shí)別功能,感興趣的朋友一起看看吧

本章教程利用python實(shí)現(xiàn)查詢銀行卡號(hào)名稱和簡(jiǎn)稱 。

一、 實(shí)例代碼

#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""
@author: Roc-xb
@desc: python 實(shí)現(xiàn)銀行卡號(hào)查詢銀行簡(jiǎn)稱
"""
import requests
def bank_mes(bank_no):
    try:
        url = "https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardNo={}&cardBinCheck=true"
        data = requests.get(url.format(bank_no)).json()
        bank_abbr = data['bank']
        bank_map = {
            "ICBC": "中國(guó)工商銀行",
            "ABC": "中國(guó)農(nóng)業(yè)銀行",
            "CCB": "中國(guó)建設(shè)銀行",
            "CMB": "招商銀行",
            "BOC": "中國(guó)銀行",
            "PSBC": "中國(guó)郵政儲(chǔ)蓄銀行",
            "COMM": "交通銀行",
            "CITIC": "中信銀行",
            "CMBC": "中國(guó)民生銀行",
            "CEB": "中國(guó)光大銀行",
            "CIB": "興業(yè)銀行",
            "SPDB": "浦發(fā)銀行",
            "GDB": "廣發(fā)銀行",
            "SPABANK": "平安銀行",
            "HXBANK": "華夏銀行",
            "BJBANK": "北京銀行",
            "SHBANK": "上海銀行",
            "JSBANK": "江蘇銀行",
            "BJRCB": "北京農(nóng)商銀行",
            "JSRCU": "江蘇省農(nóng)村信用社聯(lián)合社",
            "BOYK": "營(yíng)口銀行",
            "WOORI": "友利銀行",
            "DZLCYRCZYH": "陵城圓融村鎮(zhèn)銀行",
            "BXBANK": "本溪市商業(yè)銀行",
            "WHBANK": "烏海銀行",
            "AXDSCB": "安新大商村鎮(zhèn)銀行",
            "RQCZYH": "任丘村鎮(zhèn)銀行",
            "JXRCU": "江西省農(nóng)村信用社",
            "JKRFCZYH": "長(zhǎng)春經(jīng)開(kāi)融豐村鎮(zhèn)銀行",
            "BOHN": "海南省農(nóng)村信用社",
            "CRCBANK": "重慶農(nóng)村商業(yè)銀行",
            "ASCB": "鞍山銀行",
            "LLVB": "蘭陵村鎮(zhèn)銀行",
            "UBCHN": "海口聯(lián)合農(nóng)商銀行",
            "BSB": "蒙商銀行",
            "MMDBCJCZYH": "天水秦州長(zhǎng)銀村鎮(zhèn)銀行",
            "CSRCB": "常熟農(nóng)商銀行",
            "NJMSCZYH": "固始天驕村鎮(zhèn)銀行",
            "IELZSXHDCZYH": "稷山縣河?xùn)|村鎮(zhèn)銀行",
            "FSVB": "豐南舜豐村鎮(zhèn)銀行",
            "JSB": "晉商銀行",
            "HURCB": "湖北省農(nóng)信社",
            "ZGCBANK": "北京中關(guān)村銀行",
            "EGBANK": "恒豐銀行",
            "SQZYFDCZYH": "貴陽(yáng)花溪建設(shè)村鎮(zhèn)銀行",
            "YJSHCB": "永濟(jì)市三禾村鎮(zhèn)銀行有限責(zé)任公司",
            "GXYHGMCZYH": "長(zhǎng)春二道農(nóng)商村鎮(zhèn)銀行",
            "SDLJB": "山東利津舜豐村鎮(zhèn)銀行",
            "LSBANK": "萊商銀行",
            "JHBANK": "金華銀行",
            "LSBC": "臨商銀行",
            "YZBANK": "銀座村鎮(zhèn)銀行",
            "XMBANK": "廈門(mén)銀行",
            "XNZJCZYH": "深圳龍崗鼎業(yè)村鎮(zhèn)銀行",
            "JXYMYH": "江西裕民銀行股份有限公司",
            "DBSHMCZYH": "調(diào)兵山惠民村鎮(zhèn)銀行",
            "DRCBCL": "東莞農(nóng)村商業(yè)銀行",
            "RBOZ": "珠海華潤(rùn)銀行",
            "PZHCCB": "四川銀行",
            "GDRCC": "廣東省農(nóng)村信用社聯(lián)合社",
            "HANABANK": "韓亞銀行",
            "TLSHCB": "屯留三禾村鎮(zhèn)銀行",
            "MTBANK": "浙江民泰商業(yè)銀行",
            "LANGFB": "廊坊銀行",
            "BOJZ": "錦州銀行",
            "TJBHB": "天津?yàn)I海農(nóng)村商業(yè)銀行",
            "LLBJSJJRFCZYH": "東豐吉銀村鎮(zhèn)銀行",
            "HSBANK": "徽商銀行",
            "NNJNGMCZYH": "南寧江南國(guó)民村鎮(zhèn)銀行",
            "NXRCU": "寧夏黃河農(nóng)村商業(yè)銀行",
            "FXLZCB": "費(fèi)縣梁鄒村鎮(zhèn)銀行",
            "QLBANK": "齊魯銀行",
            "WRCB": "無(wú)錫農(nóng)村商業(yè)銀行",
            "CGXYYH": "長(zhǎng)葛軒轅村鎮(zhèn)銀行",
            "IBK": "企業(yè)銀行",
            "BANKWF": "濰坊銀行",
            "CZBANK": "浙商銀行",
            "LQRB": "臨朐村鎮(zhèn)銀行",
            "ZYTYCZYH": "寧夏西吉匯發(fā)村鎮(zhèn)銀行",
            "HRXJB": "湖南銀行",
            "YBF": "豫豐村鎮(zhèn)銀行",
            "JZCBANK": "焦作中旅銀行",
            "TLXXCZYH": "鐵嶺新星村鎮(zhèn)銀行",
            "SDSHHJCZYH": "山東商河匯金村鎮(zhèn)銀行",
            "WCYRCZYH": "武城圓融村鎮(zhèn)銀行",
            "HKBEA": "東亞銀行",
            "GZRCU": "貴州省農(nóng)村信用社聯(lián)合社",
            "LPSZSLDCZYH": "六盤(pán)水鐘山?jīng)龆即彐?zhèn)銀行",
            "RHMYCZYH": "仁懷蒙銀村鎮(zhèn)銀行",
            "ZZYH": "棗莊銀行",
            "HYXHNSCZYH": "寧夏永寧匯發(fā)村鎮(zhèn)銀行",
            "LLYRCZYH": "樂(lè)陵圓融村鎮(zhèn)銀行",
            "ZRCBANK": "張家港農(nóng)村商業(yè)銀行",
            "QHJRCB": "清河金農(nóng)村鎮(zhèn)銀行",
            "WYYCCZYH": "舞陽(yáng)玉川村鎮(zhèn)銀行",
            "DCSFCZYH": "大城舜豐村鎮(zhèn)銀行",
            "QDCCB": "青島銀行",
            "HDCB": "黔西花都村鎮(zhèn)銀行",
            "ARCU": "安徽省農(nóng)村信用社",
            "SDLCYRCZYH": "歷城圓融村鎮(zhèn)銀行",
            "QLXACZYH": "隰縣新田村鎮(zhèn)銀行",
            "ZGCCB": "自貢銀行",
            "ALEJHCB": "阿拉爾津匯村鎮(zhèn)銀行",
            "BOHAIB": "渤海銀行",
            "SDEB": "順德農(nóng)商銀行",
            "HBC": "湖北銀行",
            "LYCB": "遼陽(yáng)銀行",
            "FXCB": "阜新銀行",
            "PSATCZYH": "盤(pán)山安泰村鎮(zhèn)銀行",
            "WJRCB": "蘇州農(nóng)村商業(yè)銀行",
            "SDZFQFCZYH": "山東芝罘齊豐村鎮(zhèn)銀行",
            "HBFNJXCZYH": "乳山天驕村鎮(zhèn)銀行",
            "HSB": "恒生銀行",
            "NYBANK": "廣東南粵銀行",
            "BGB": "廣西北部灣銀行",
            "DAQINGB": "龍江銀行",
            "CDCB": "成都銀行",
            "DZCBANK": "達(dá)州市商業(yè)銀行",
            "HLDB": "葫蘆島銀行",
            "ZZZYFDCZYH": "平遙縣晉融村鎮(zhèn)銀行",
            "ZYBZHLCZYH": "遵義播州匯隆村鎮(zhèn)銀行",
            "HEBXFCZYH": "平輿玉川村鎮(zhèn)銀行",
            "WZCB": "溫州銀行",
            "ZJSYHTCZYH": "浙江松陽(yáng)恒通村鎮(zhèn)銀行",
            "H3CB": "內(nèi)蒙古銀行",
            "GRCB": "廣州農(nóng)村商業(yè)銀行",
            "HSBC": "匯豐銀行(中國(guó))",
            "QHRC": "青海省農(nóng)村信用社",
            "LSCCB": "樂(lè)山市商業(yè)銀行",
            "SZSBK": "石嘴山銀行",
            "SINO": "永豐銀行",
            "CCQTGB": "重慶三峽銀行",
            "HSBK": "衡水市商業(yè)銀行",
            "NJXLRB": "內(nèi)江村鎮(zhèn)銀行",
            "GYGSB": "廣元貴商村鎮(zhèn)銀行",
            "SXBANK": "三湘銀行",
            "CJYMCZYH": "沙河襄通村鎮(zhèn)銀行",
            "WAHDCZYH": "平陰藍(lán)海村鎮(zhèn)銀行",
            "DLB": "大連銀行",
            "BHB": "河北銀行",
            "LYJDCZYH": "萊陽(yáng)膠東村鎮(zhèn)銀行",
            "AMBZJDYFMCZYH": "包頭市昆都侖蒙銀村鎮(zhèn)銀行",
            "SXQNRCB": "陜西秦農(nóng)農(nóng)村商業(yè)銀行股份有限公司",
            "YQCCB": "陽(yáng)泉市商業(yè)銀行",
            "XTB": "邢臺(tái)銀行",
            "SJBANK": "盛京銀行",
            "DYCCB": "東營(yíng)銀行",
            "SDZHQYCZYH": "山東沾化青云村鎮(zhèn)銀行",
            "BDCBANK": "保定銀行",
            "DZBANK": "德州銀行",
            "ANTBANK": "網(wǎng)商銀行",
            "ZJNX": "浙江農(nóng)商聯(lián)合銀行",
            "PZBANK": "盤(pán)錦銀行",
            "CSCB": "長(zhǎng)沙銀行",
            "PBDLCZYH": "平壩鼎立村鎮(zhèn)銀行",
            "ZQQLCZYH": "天鎮(zhèn)縣河?xùn)|村鎮(zhèn)銀行",
            "HZCB": "杭州銀行",
            "JZBANK": "晉中銀行",
            "BOCFCB": "中銀富登村鎮(zhèn)銀行",
            "RCXNSCZYH": "石阡長(zhǎng)征村鎮(zhèn)銀行",
            "SRCB": "深圳農(nóng)村商業(yè)銀行",
            "QHSRB": "黃島舜豐村鎮(zhèn)銀行",
            "YACCB": "雅安市商業(yè)銀行",
            "ZYB": "中原銀行",
            "SDRCU": "山東省農(nóng)村信用社聯(lián)合社",
            "BOHUIHE": "新疆匯和銀行",
            "QLCZYH": "青隆村鎮(zhèn)銀行",
            "GCB": "廣州銀行",
            "SXRCCU": "陜西省農(nóng)信社",
            "XJRCU": "新疆農(nóng)村信用社",
            "JLBANK": "吉林銀行",
            "TACCB": "泰安銀行",
            "GYCB": "貴陽(yáng)銀行",
            "GSBANK": "甘肅銀行",
            "SDLZHJCZYH": "山東臨淄匯金村鎮(zhèn)銀行",
            "LSYH": "遼沈銀行",
            "XHCZYH": "新華村鎮(zhèn)銀行",
            "HHRXCZYH": "蘭西農(nóng)商村鎮(zhèn)銀行",
            "NXTXJHCB": "寧夏同心津匯村鎮(zhèn)銀行",
            "NBIZJZSCZCZYH": "松桃長(zhǎng)征村鎮(zhèn)銀行",
            "RZB": "日照銀行",
            "DHDYCZYH": "德惠敦銀村鎮(zhèn)銀行",
            "KLB": "昆侖銀行",
            "XZBANK": "西藏銀行",
            "JJBANK": "九江銀行",
            "SXRCU": "山西省農(nóng)村信用社",
            "HNBANK": "海南銀行股份有限公司",
            "DJCZCZYH": "德江長(zhǎng)征村鎮(zhèn)銀行",
            "CGNB": "四川天府銀行",
            "WHFMCZYH": "威海富民村鎮(zhèn)銀行",
            "CZCB": "浙江稠州商業(yè)銀行",
            "WZMSBANK": "溫州民商銀行",
            "ETKQHZCB": "鄂托克旗匯澤村鎮(zhèn)銀行股份有限公司",
            "QWXXTCZYH": "阜平大商村鎮(zhèn)銀行",
            "SHRCB": "上海農(nóng)商銀行",
            "SNCCB": "遂寧銀行",
            "TLBANK": "鐵嶺銀行",
            "NDHB": "寧波東海銀行",
            "NXBANK": "寧夏銀行",
            "NMGNXS": "內(nèi)蒙古農(nóng)村信用社聯(lián)合社",
            "SNBANK": "蘇寧銀行",
            "ZQZSGYCZYH": "虞城通商村鎮(zhèn)銀行",
            "DBSCN": "星展銀行",
            "HBRCU": "河北省農(nóng)村信用社",
            "LXHRCZYH": "嵐縣慧融村鎮(zhèn)銀行",
            "GYBYDXCZYH": "貴陽(yáng)白云德信村鎮(zhèn)銀行",
            "LNRCC": "遼寧農(nóng)商銀行",
            "DYLSCB": "東營(yíng)萊商村鎮(zhèn)銀行",
            "TCCB": "天津銀行",
            "BOQZ": "泉州銀行",
            "NBBANK": "寧波銀行",
            "WHRCB": "武漢農(nóng)村商業(yè)銀行",
            "ZYYCCZYH": "正陽(yáng)玉川村鎮(zhèn)銀行",
            "NCB": "江西銀行",
            "ZJKCCB": "張家口銀行",
            "JNBANK": "濟(jì)寧銀行",
            "KELFMCZ": "庫(kù)爾勒富民村鎮(zhèn)銀行",
            "XCXPCZYH": "許昌新浦村鎮(zhèn)銀行",
            "EEDSSHTCZYH": "鄂爾多斯市罕臺(tái)村鎮(zhèn)銀行",
            "KLLACB": "墾利樂(lè)安村鎮(zhèn)銀行",
            "HRBANK": "哈爾濱銀行",
            "BOQH": "青海銀行",
            "YBCCB": "宜賓市商業(yè)銀行",
            "NJNKCZYH": "南江農(nóng)科村鎮(zhèn)銀行",
            "LTSFRB": "樂(lè)亭村鎮(zhèn)銀行",
            "LZYH": "蘭州銀行",
            "NJCB": "南京銀行",
            "JINCHB": "晉城銀行",
            "TZCB": "臺(tái)州銀行",
            "CQBANK": "重慶銀行",
            "SXBA": "山西銀行",
            "PYYRCZYH": "平原圓融村鎮(zhèn)銀行",
            "URB": "聯(lián)合村鎮(zhèn)銀行",
            "FDB": "富滇銀行",
            "LYRTCZYH": "長(zhǎng)春綠園融泰村鎮(zhèn)銀行",
            "SCRCU": "四川省農(nóng)村信用社聯(lián)合社",
            "AHXABANK": "安徽新安銀行",
            "GAXQB": "貴安新區(qū)發(fā)展村鎮(zhèn)銀行",
            "YTBANK": "煙臺(tái)銀行",
            "DLRCB": "大連農(nóng)村商業(yè)銀行",
            "PCNKCZYH": "平昌農(nóng)科村鎮(zhèn)銀行",
            "QYLACZYH": "慶云樂(lè)安村鎮(zhèn)銀行",
            "NYCB": "南陽(yáng)村鎮(zhèn)銀行",
            "ASXHNMCZYH": "安順西航南馬村鎮(zhèn)銀行",
            "BTSDHJGCZYH": "江口長(zhǎng)征村鎮(zhèn)銀行",
            "QHDBANK": "秦皇島銀行",
            "SDHMB": "山東惠民舜豐村鎮(zhèn)銀行",
            "NBCBANK": "寧波通商銀行",
            "JXRJGDCB": "江西瑞金光大村鎮(zhèn)銀行",
            "SRBANK": "上饒銀行",
            "BJCPBSCZYH": "哈爾濱阿城農(nóng)商村鎮(zhèn)銀行",
            "HNRCU": "河南省農(nóng)村信用社",
            "RXBANK": "瑞信村鎮(zhèn)銀行",
            "HNSSXNSCZYH": "山東金鄉(xiāng)藍(lán)海村鎮(zhèn)銀行",
            "MZKSB": "梅州客商銀行",
            "SHZGMCZYH": "平陸縣河?xùn)|村鎮(zhèn)銀行",
            "BOSZ": "蘇州銀行",
            "YXCCB": "云南紅塔銀行",
            "SCMYCZYH": "水城蒙銀村鎮(zhèn)銀行",
            "XIB": "廈門(mén)國(guó)際銀行",
            "BOCD": "承德銀行",
            "HUAMINGBANK": "華明村鎮(zhèn)銀行",
            "YYBSCB": "博商銀行",
            "HNRCC": "湖南省農(nóng)村信用社",
            "XABANK": "西安銀行",
            "TRCB": "天津農(nóng)商銀行",
            "BOSH": "新韓銀行",
            "GHB": "廣東華興銀行",
            "CCHRCZYH": "長(zhǎng)春朝陽(yáng)和潤(rùn)村鎮(zhèn)銀行",
            "CZRCB": "江南農(nóng)村商業(yè)銀行",
            "URMQCCB": "烏魯木齊銀行",
            "MYBANK": "綿陽(yáng)市商業(yè)銀行",
            "HDBANK": "邯鄲銀行",
            "JRCB": "江蘇江陰農(nóng)村商業(yè)銀行",
            "CITICN": "花旗銀行(中國(guó))",
            "KJCZYH": "梅縣客家村鎮(zhèn)銀行",
            "ZJQZQJSYCZYH": "衢江上銀村鎮(zhèn)銀行",
            "HLJRCU": "黑龍江省農(nóng)村信用社聯(lián)合社",
            "XJB": "新疆銀行",
            "KCBEBANK": "天津金城銀行",
            "DYCB": "長(zhǎng)城華西銀行",
            "QAXLCB": "遷安襄隆村鎮(zhèn)銀行",
            "BOD": "東莞銀行",
            "NCBANK": "南洋商業(yè)銀行",
            "WHCCB": "威海市商業(yè)銀行",
            "BOCZ": "滄州銀行",
            "BOCY": "朝陽(yáng)銀行",
            "CABANK": "長(zhǎng)安銀行",
            "BOL": "中原銀行洛陽(yáng)分行",
            "HKB": "漢口銀行",
            "WSQBSCZYH": "江蘇江都吉銀村鎮(zhèn)銀行",
            "BOP": "平頂山銀行",
            "GXRCU": "廣西壯族自治區(qū)農(nóng)村信用社聯(lián)合社",
            "SXCB": "紹興銀行",
            "YJHLLLCZYH": "神池縣河?xùn)|村鎮(zhèn)銀行",
            "PTFMCZYH": "都勻融通村鎮(zhèn)銀行",
            "HNCMCJCZYH": "夏縣河?xùn)|村鎮(zhèn)銀行",
            "YKYHCCB": "營(yíng)口沿海銀行",
            "FJNX": "福建省農(nóng)村信用社聯(lián)合社",
            "ZBCB": "齊商銀行",
            "GZB": "贛州銀行",
            "HZCCB": "湖州銀行",
            "GXPNGYCZYH": "浙江文成北銀村鎮(zhèn)銀行",
            "QJCCB": "曲靖市商業(yè)銀行",
            "ZJLXYSCZYH": "浙江蘭溪越商村鎮(zhèn)銀行",
            "ZXBXBANK": "百信銀行",
            "JXBANK": "嘉興銀行",
            "WACZYH": "武安村鎮(zhèn)銀行",
            "KSRB": "昆山農(nóng)村商業(yè)銀行",
            "FJHXBC": "福建海峽銀行",
            "BDXHRCZYH": "保德縣慧融村鎮(zhèn)銀行",
            "ZYCBANK": "貴州銀行",
            "KYHNSCZYH": "國(guó)民村鎮(zhèn)銀行",
            "YGCB": "前郭縣陽(yáng)光村鎮(zhèn)銀行",
            "AHDYMFCZYH": "泌陽(yáng)玉川村鎮(zhèn)銀行",
            "SDZPQLCZYH": "蕪湖圓融村鎮(zhèn)銀行",
            "ZJTLCB": "浙江泰隆商業(yè)銀行",
            "NHB": "南海農(nóng)商銀行",
            "CJCCB": "江蘇長(zhǎng)江商業(yè)銀行",
            "FBBANK": "富邦華一銀行",
            "LZCCB": "柳州銀行",
            "FSCB": "撫順銀行",
            "LJYSCJCZYH": "聞喜縣晉融村鎮(zhèn)銀行",
            "QJHMCB": "曲靖惠民村鎮(zhèn)銀行",
            "GYSFCB": "廊坊市廣陽(yáng)舜豐村鎮(zhèn)銀行股份有限公司",
            "CZCCB": "長(zhǎng)治銀行",
            "NXQTXHLSCZYH": "寧夏青銅峽賀蘭山村鎮(zhèn)銀行",
            "BQGYCZYH": "陜西周至農(nóng)科村鎮(zhèn)銀行",
            "LUZBANK": "瀘州銀行",
            "TJNHCZYH": "天津?qū)幒哟彐?zhèn)銀行",
            "GSRCU": "甘肅省農(nóng)村信用社",
            "GLBANK": "桂林銀行",
            "PDHF": "大洼恒豐村鎮(zhèn)銀行",
            "ZZBANK": "鄭州銀行",
            "SDGQHJCZYH": "山東高青匯金村鎮(zhèn)銀行",
            "TCRCB": "江蘇太倉(cāng)農(nóng)村商業(yè)銀行",
            "HSCZB": "湖商村鎮(zhèn)銀行",
            "CDRCB": "成都農(nóng)商銀行",
            "YSXRCZYH": "元氏信融村鎮(zhèn)銀行",
            "YTFSZJCZYH": "汝州玉川村鎮(zhèn)銀行",
            "WZYTMGJHCZYH": "鐵門(mén)關(guān)津匯村鎮(zhèn)銀行",
            "ZYXPCZCB": "遵義新蒲長(zhǎng)征村鎮(zhèn)銀行",
            "YDNSCZYH": "堯都農(nóng)商銀行村鎮(zhèn)銀行",
            "GYRCB": "貴陽(yáng)農(nóng)村商業(yè)銀行",
            "ORBANK": "鄂爾多斯銀行",
            "BZSFCB": "霸州舜豐村鎮(zhèn)銀行",
            "NBYZ": "寧波鄞州農(nóng)商行",
            "SCB": "渣打銀行",
            "JLRCU": "吉林省農(nóng)村信用社聯(lián)合社",
            "YNRCC": "云南省農(nóng)村信用社",
            "OJASZCFCZYH": "寧夏彭陽(yáng)賀蘭山村鎮(zhèn)銀行"
        }
        bank_name = bank_map[bank_abbr]
        print("銀行卡號(hào):{}".format(bank_no))
        print("銀行名稱:{}".format(bank_name))
        print("銀行簡(jiǎn)稱:{}".format(bank_abbr))
    except Exception as e:
        print("銀行卡號(hào)輸入有誤:{}".format(e))
if __name__ == '__main__':
    bank_mes("6217001340011005638")

二、運(yùn)行效果

38e0a941bd334662a7eb133c0e3e708b.png

基于PyQT5+OpenCv實(shí)現(xiàn)銀行卡號(hào)識(shí)別

一、實(shí)訓(xùn)內(nèi)容

         選擇合適的算法,編寫(xiě)程序進(jìn)行信用卡號(hào)識(shí)別;制作交互式用戶界面,實(shí)現(xiàn)一個(gè)能讀入信用卡圖片并識(shí)別信用卡號(hào)的系統(tǒng),系統(tǒng)界面上需要對(duì)輸入圖像、識(shí)別結(jié)果等進(jìn)行展示。并對(duì)實(shí)驗(yàn)結(jié)果進(jìn)行分析,評(píng)價(jià)算法性能。

二、實(shí)現(xiàn)思路

2.1.Python工具和庫(kù)的選擇

        選擇使用Python工具和庫(kù)來(lái)實(shí)現(xiàn)信用卡號(hào)識(shí)別系統(tǒng),安裝Python所需要使用的庫(kù)OpenCV、numpy、os、sys、PyQt5、pytesseract、QT Desinger、contours等。確保選擇的工具和庫(kù)提供了所需的圖像處理功能,并且易于使用和集成到銀行卡識(shí)別系統(tǒng)中。

2.2.主程序界面實(shí)現(xiàn)思路

        該模塊主要是實(shí)現(xiàn)了一個(gè)基于PyQt5的信用卡號(hào)識(shí)別系統(tǒng)的UI設(shè)計(jì),包含有一個(gè)Mywindow類(lèi)的定義和2個(gè)功能窗口類(lèi)的定義以及兩個(gè)自定義函數(shù)。算法原理主要包括以下幾個(gè)部分:

1.導(dǎo)入需要使用的模塊和庫(kù):從PyQt5中導(dǎo)入QApplication、QMainWindow、QFileDialog等類(lèi),從PyQt5.QtGui中導(dǎo)入用于圖像操作的類(lèi),從cv2和numpy庫(kù)中導(dǎo)入用于圖像處理的模塊,從card_recognize.py模塊中導(dǎo)入信用卡號(hào)識(shí)別的功能。

2.導(dǎo)入U(xiǎn)I文件:通過(guò)from card_re import Card_re_Window語(yǔ)句將識(shí)別信用卡號(hào)的窗口的UI文件導(dǎo)入到主程序中。這個(gè)UI文件使用Qt Designer軟件設(shè)計(jì)而成,包含了各個(gè)窗口的布局、控件和信號(hào)槽等信息。

3.創(chuàng)建主窗口并設(shè)置UI:自定義一個(gè) MyWindow 類(lèi)繼承于 QMainWindow 和 Ui_Mainwindow,用于界面的初始化和 button 的信號(hào)鏈接。 先調(diào)用父類(lèi)的構(gòu)造函數(shù)進(jìn)行界面的初始化,加載界面。

4.窗口類(lèi)的定義:定義了Card_re_class類(lèi),該類(lèi)繼承了QMainWindow和對(duì)應(yīng)的UI界面類(lèi),如Card_re_class繼承了QMainWindow和Card_re_Window類(lèi)。這些類(lèi)中定義了對(duì)應(yīng)功能窗口上的按鈕、標(biāo)簽、圖像顯示區(qū)等控件,并實(shí)現(xiàn)了對(duì)應(yīng)的功能函數(shù),如打開(kāi)和保存文件、選擇文件夾等操作,將圖像數(shù)據(jù)加載到內(nèi)存中,然后對(duì)其進(jìn)行操作和顯示。

5.實(shí)現(xiàn)窗口間的跳轉(zhuǎn):MyWindow類(lèi)添加了function1、function2兩個(gè)方法,分別對(duì)應(yīng)主界面上的2個(gè)功能按鈕。每個(gè)方法調(diào)用對(duì)應(yīng)的功能窗口類(lèi),并且關(guān)閉當(dāng)前界面。這樣,當(dāng)用戶點(diǎn)擊主界面上的某個(gè)功能按鈕時(shí),就會(huì)自動(dòng)打開(kāi)對(duì)應(yīng)的功能窗口,實(shí)現(xiàn)了不同功能窗口之間的切換。

6.添加圖標(biāo):使用QIcon類(lèi)給窗口添加圖標(biāo)的功能,為窗口添加南陽(yáng)理工學(xué)院?;?qǐng)D標(biāo)以增強(qiáng)軟件的視覺(jué)效果和用戶體驗(yàn),同時(shí)也給代碼增添了一些標(biāo)志性特點(diǎn)。

7.兩個(gè)自定義函數(shù):主要實(shí)現(xiàn)了將Qt中的QPixmap對(duì)象轉(zhuǎn)換為OpenCV中的Mat對(duì)象,以及將OpenCV中的Mat對(duì)象轉(zhuǎn)換為Qt中的QImage或QPixmap對(duì)象。

總體思路是通過(guò)PyQt5信用卡號(hào)識(shí)別系統(tǒng)的GUI界面,將不同的功能模塊分別設(shè)計(jì)為不同的窗口,用戶可以在主界面上選擇要進(jìn)行的操作,然后跳轉(zhuǎn)到相應(yīng)的功能窗口進(jìn)行圖像處理。

2.3.對(duì)模板圖片進(jìn)行預(yù)處理

        對(duì)模板圖片進(jìn)行處理,這部分的主要作用是對(duì)一個(gè)數(shù)字模板(t_img.png)進(jìn)行圖像處理,提取其中的數(shù)字輪廓和特征,并將以此識(shí)別的外輪廓分割存儲(chǔ)到一個(gè)列表變量 digits 中,以便后續(xù)識(shí)別圖像時(shí)比對(duì)。

2.4.對(duì)輪廓排序處理

        這部分實(shí)現(xiàn)對(duì)輪廓進(jìn)行排序的功能。它可以按照指定的排序方法,對(duì)一組輪廓 cnts 進(jìn)行排序,并返回排序后的輪廓集合和對(duì)應(yīng)的外接矩形列表。

2.5.對(duì)信用卡進(jìn)行卡號(hào)識(shí)別

        這部分是代碼的核心,主要對(duì)輸入的信用卡圖片進(jìn)行解析處理,提取出所需要的卡號(hào)部分,對(duì)卡號(hào)部分計(jì)算外接矩形,然后分割為每一個(gè)數(shù)字輪廓為一部分,最后對(duì)每個(gè)數(shù)字輪廓與模板數(shù)字輪廓比對(duì),選取得分最高的即認(rèn)為該數(shù)字模板為數(shù)字號(hào)碼,最后將號(hào)碼輸出。

        具體思路為:初始化卷積核:rectKernel 和 sqKernel,用于后續(xù)進(jìn)行形態(tài)學(xué)操作。對(duì)輸入的圖片進(jìn)行預(yù)處理操作:調(diào)整尺寸為寬度為 300,轉(zhuǎn)換為灰度圖像。使用禮帽(頂帽)操作突出更明亮的區(qū)域,使用 Sobel 算子進(jìn)行邊緣檢測(cè),對(duì)結(jié)果進(jìn)行歸一化和二值化。對(duì)二值化結(jié)果進(jìn)行閉操作,即先膨脹再腐蝕,將數(shù)字連在一起。對(duì)閉操作后的結(jié)果,再次進(jìn)行閉操作,對(duì)縫隙進(jìn)行填充。對(duì)閉操作后的結(jié)果進(jìn)行輪廓檢測(cè),找到符合要求的輪廓區(qū)域。將符合要求的輪廓從左到右排序,并遍歷每一個(gè)輪廓中的數(shù)字。根據(jù)坐標(biāo)提取每一個(gè)數(shù)字組,對(duì)每個(gè)數(shù)字組進(jìn)行預(yù)處理并進(jìn)行輪廓檢測(cè),計(jì)算每個(gè)數(shù)字的匹配得分。找到合適的數(shù)字并輸出,畫(huà)出每個(gè)數(shù)字所在的矩形框。

流程圖如下:

 三、程序代碼

主界面代碼:

# UI設(shè)計(jì)
import sys
from PyQt5.QtWidgets import QApplication,QMainWindow
# 用于打開(kāi)和保存文件、選擇文件夾等操作
from PyQt5.QtWidgets import QFileDialog
# 將圖像數(shù)據(jù)加載到內(nèi)存中,然后對(duì)其進(jìn)行操作和顯示
from PyQt5.QtGui import *
# 導(dǎo)入U(xiǎn)i
from main_win import Ui_Mainwindow
from card_re import Card_re_Window
# 給窗口添加圖標(biāo)
from PyQt5.QtGui import QIcon
# 銀行卡識(shí)別
import card_recognize
# 圖像處理
import cv2
import numpy as np
class MyWindow(QMainWindow,Ui_Mainwindow):
    def __init__(self):
        # 調(diào)用父類(lèi)構(gòu)造函數(shù)
        super().__init__()
        # 使用 Ui_MainWindow 類(lèi)中的 setupUi 方法來(lái)加載界面
        self.setupUi(self)
        # 創(chuàng)建圖標(biāo)對(duì)象并設(shè)置窗口圖標(biāo)
        self.setWindowIcon(QIcon("logo_64.png"))
        # 按鈕信號(hào)鏈接
        self.pushButton1.clicked.connect(self.function1)
    def function1(self):
        self.fun1=Card_re_class()
        self.fun1.show()
        self.close()
class Card_re_class(QMainWindow,Card_re_Window):
    def __init__(self):
        super(Card_re_class,self).__init__()
        # 加載UI
        self.setupUi(self)
        # 創(chuàng)建圖標(biāo)對(duì)象并設(shè)置窗口圖標(biāo)
        self.setWindowIcon(QIcon("logo_64.png"))
        # 按鈕信號(hào)鏈接
        self.pushButton_return.clicked.connect(self.push_return)
        self.pushButton_upload.clicked.connect(self.openimage)
        self.pushButton_save.clicked.connect(self.saveimage)
        self.pushButton_card_re.clicked.connect(self.fun)
    def push_return(self):
        self.Re_main = MyWindow()
        # 關(guān)閉當(dāng)前窗口
        self.close()
        # 打開(kāi)新窗口
        self.Re_main.show()
    def openimage(self):
        # 打開(kāi)一個(gè)文件選擇對(duì)話框,讓用戶選擇要打開(kāi)的圖片文件
        fname = QFileDialog.getOpenFileName(self, '打開(kāi)圖片', './', "Images (*.png *.jpg *.bmp)")
        # 檢查是否選擇了一個(gè)文件,fname 不為空,則進(jìn)入下面的代碼塊
        if fname[0]:
            # 使用 QPixmap 函數(shù)從文件路徑創(chuàng)建一個(gè) QPixmap 對(duì)象
            # 然后使用 setPixmap 方法將其設(shè)置為 label_daichuli 控件的圖片
            self.label_daichuli.setPixmap(QPixmap(fname[0]))
            # 自動(dòng)換行功能,確保圖片可以完全顯示在控件中
            self.label_daichuli.setWordWrap(True)
            # 調(diào)整為圖片大小,以確保圖片不會(huì)被縮小或拉伸
            self.label_daichuli.setScaledContents(True)
    def saveimage(self):
        # 打開(kāi)一個(gè)文件選擇對(duì)話框,讓用戶選擇要保存的圖片文件
        nfname = QFileDialog.getSaveFileName(self, "保存圖片", "./", "Images (*.png *.jpg *.bmp)")
        if nfname[0]:
            # 使用pixmap()方法獲取label_jieguo標(biāo)簽中的當(dāng)前圖像
            # 然后使用save()方法將其保存到用戶指定的文件名nfname[0]中
            self.label_jieguo.pixmap().save(nfname[0])
    def fun(self):                  #
        # 獲取圖像信息,并存儲(chǔ)在qimg中,pixmap()方法返回一個(gè)QPixmap對(duì)象,表示標(biāo)簽中顯示的圖像
        qimg = self.label_daichuli.pixmap()
        # 將QImage對(duì)象格式圖像信息轉(zhuǎn)換為numpy數(shù)組格式
        src = qimage_to_mat(qimg)
        # 使用自定義模塊,將彩色圖轉(zhuǎn)換為灰度圖像
        newsrc,re_text= card_recognize.main_run(src)
        # 將numpy數(shù)組格式的圖像數(shù)據(jù)轉(zhuǎn)化為QImage對(duì)象格式的圖像數(shù)據(jù)
        pix = mat_to_qimage(newsrc)
        # 將圖像顯示在名為結(jié)果的標(biāo)簽中,setPixmap()方法接受一個(gè)QPixmap對(duì)象作為參數(shù),并將其設(shè)置為標(biāo)簽中的圖像
        self.label_jieguo.setPixmap(pix)
        # setWordWrap()方法接受一個(gè)布爾值參數(shù),如果設(shè)置為T(mén)rue,則文本將自動(dòng)換行
        self.label_jieguo.setWordWrap(True)
        # setScaledContents()方法接受一個(gè)布爾值參數(shù),如果設(shè)置為T(mén)rue,則標(biāo)簽將自動(dòng)縮放其內(nèi)容以適應(yīng)標(biāo)簽大小
        self.label_jieguo.setScaledContents(True)
        ###########在 QLabel 控件中顯示識(shí)別的文本
        self.label_cardnum.setText(re_text)
            # setWordWrap()方法接受一個(gè)布爾值參數(shù),如果設(shè)置為T(mén)rue,則文本將自動(dòng)換行
        self.label_cardnum.setWordWrap(True)
            # setScaledContents()方法接受一個(gè)布爾值參數(shù),如果設(shè)置為T(mén)rue,則標(biāo)簽將自動(dòng)縮放其內(nèi)容以適應(yīng)標(biāo)簽大小
        self.label_cardnum.setScaledContents(True)
##################################################################################
def qimage_to_mat(qtpixmap):    #qtpixmap轉(zhuǎn)opencv
    # 將輸入的QPixmap對(duì)象轉(zhuǎn)換成了一個(gè)QImage對(duì)象
    qimg = qtpixmap.toImage()
    # 計(jì)算了輸出的NumPy數(shù)組的形狀。height是圖像的高度,bytesPerLine是每行掃描線的字節(jié)數(shù),depth是每個(gè)像素的位數(shù)
    temp_shape = (qimg.height(), qimg.bytesPerLine() * 8 // qimg.depth())
    # 將形狀元組添加了第四個(gè)維度。第四個(gè)維度表示RGBA顏色通道
    temp_shape += (4,)
    ptr = qimg.bits()
    # 獲取了指向QImage對(duì)象內(nèi)存緩沖區(qū)的指針,并將指針大小設(shè)置為QImage對(duì)象的大?。ㄒ宰止?jié)為單位)
    ptr.setsize(qimg.byteCount())
    # 創(chuàng)建了一個(gè)NumPy數(shù)組。該數(shù)組的形狀為temp_shape,數(shù)據(jù)類(lèi)型為uint8
    result = np.array(ptr, dtype=np.uint8).reshape(temp_shape)
    # 丟棄圖像的第四個(gè)(alpha)通道。結(jié)果得到的NumPy數(shù)組的形狀為(height, width, 3),表示圖像的RGB顏色通道
    result = result[..., :3]
    # 將NumPy數(shù)組作為qimage2mat函數(shù)的輸出
    return result
def mat_to_qimage(cvimg):       #opencv轉(zhuǎn)QImage
    # 判斷輸入的圖像是否是單通道的,也就是灰度圖像
    if cvimg.ndim==2:              #單通道
        # 獲取圖像的高度和寬度
        height, width= cvimg.shape
        # 將BGR格式的圖像數(shù)據(jù)轉(zhuǎn)換為RGB格式
        cvimg = cv2.cvtColor(cvimg, cv2.COLOR_BGR2RGB)
        #  將圖像數(shù)據(jù)轉(zhuǎn)換為QImage對(duì)象,并使用QImage.Format_RGB888格式表示。
        cvimg = QImage(cvimg.data, width, height, QImage.Format_RGB888)
        # 將QImage對(duì)象轉(zhuǎn)換為QPixmap對(duì)象并存儲(chǔ)在pix變量中
        pix = QPixmap.fromImage(cvimg)
        return pix
    else:                          #多個(gè)通道
        # 獲取圖像的高度和寬度
        width = cvimg.shape[1]
        height = cvimg.shape[0]
        # 根據(jù)已知的高度和寬度新建一個(gè)空的QPixmap對(duì)象
        pixmap = QPixmap(width, height)
        #  將QPixmap對(duì)象轉(zhuǎn)換為QImage對(duì)象類(lèi)型的qimg
        qimg = pixmap.toImage()
        # 嵌套循環(huán)遍歷圖像的所有像素,獲取每個(gè)像素的紅、綠、藍(lán)三個(gè)通道的值
        for row in range(0, height):
            for col in range(0, width):
                b = cvimg[row, col, 0]
                g = cvimg[row, col, 1]
                r = cvimg[row, col, 2]
                # 使用qRgb()函數(shù)將其轉(zhuǎn)換為QColor對(duì)象
                pix = qRgb(r, g, b)
                qimg.setPixel(col, row, pix)
                # 將QImage對(duì)象轉(zhuǎn)換為QPixmap對(duì)象
                pix = QPixmap.fromImage(qimg)
        return pix
if __name__ == '__main__':
    app = QApplication(sys.argv)
    # app.setWindowIcon(QIcon('img.png')) 加載頭像
    mywindow = MyWindow()
    mywindow.show()
    sys.exit(app.exec_())

銀行卡識(shí)別代碼:

import cv2
import numpy as np
from imutils import contours
#對(duì)圖像中的邊緣和輪廓進(jìn)行識(shí)別、分割和提取。使用imutils庫(kù)的contours函數(shù)能夠方便地檢測(cè)到圖像中的輪廓,
# 并且按照一定的順序返回,可以用于數(shù)字的識(shí)別、字符的識(shí)別等應(yīng)用。
#設(shè)為全局變量
digits = {}
global output
output = []
#################################################圖像繪圖
def cv_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
##################################################對(duì)輸入的輪廓進(jìn)行排序
def sort_contours(cnts,method="left-to-right"):
    reverse=False
    i=0
    if method=="right-to-left" or method =="bottom-to-top":
        reverse=True
    if method=="top-to-bottom" or method=="bottom-to-top":
        i=1
    # 在輪廓信息中計(jì)算外接矩形
    boundingBoxes=[cv2.boundingRect(c) for c in cnts] # 元組x,y,h,w
    # 對(duì)輪廓進(jìn)行排序操作
    (cnts,boundingBoxes)=zip(*sorted(zip(cnts,boundingBoxes),key=lambda b:b[1][i],reverse=reverse))
    return cnts,boundingBoxes
#重置大小,用于比較模板和圖像中的數(shù)字是否一致
#插值方法如下:
#INTER_NEAREST:最鄰近插值
#INTER_LINEAR:雙線性插值,默認(rèn)情況下使用該方式進(jìn)行插值.
#INTER_AREA:基于區(qū)域像素關(guān)系的一種重采樣或者插值方式.該方法是圖像抽取的首選方法,它可以產(chǎn)生更少的波紋,
#但是當(dāng)圖像放大時(shí),它的效果與INTER_NEAREST效果相似.
#INTER_CUBIC:4×4鄰域雙3次插值
#INTER_LANCZOS4:8×8鄰域蘭索斯插值
########################################將輸入的圖像按照指定的寬度、高度進(jìn)行縮放
def resize(image,width=None,height=None,inter=cv2.INTER_AREA):
    dim=None
    (h,w)=image.shape[:2] #(200,300,3)
    # 當(dāng)未指定寬度和高度時(shí),直接返回原圖像。
    if width is None and height is None:
        return image
    if width is None:
        r=height/float(h)
        dim=(int(w*r),height)
    else:
        r=width/float(w)
        dim=(width,int(h*r))
    # 利用OpenCV中resize函數(shù)對(duì)圖像進(jìn)行縮放
    resized=cv2.resize(image,dim,interpolation=inter)
    return resized
##################################################讀取模板圖片并處理###########
def process_template():
    # 讀取一個(gè)模板文件
    img = cv2.imread("t_img.png")
    # 灰度圖
    ref = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 二值圖像
    ref = cv2.threshold(ref, 10, 255, cv2.THRESH_BINARY_INV)[1]
    cv_show("ref",ref)
    ######################################計(jì)算輪廓
    # cv2.findContours()函數(shù)接受的參數(shù)為二值圖,即黑白的(不是灰度圖)
    # cv2.RETR_EXTERNAL只檢測(cè)外輪廓,cv2.CHAIN_APPROX_SIMPLE只保留終點(diǎn)坐標(biāo)
    # 返回的list中每個(gè)元素都是圖像中的一個(gè)輪廓
    refCnts, hierarchy = cv2.findContours(ref.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    # 只需要輪廓resCnts
    cv2.drawContours(img, refCnts, -1, (0, 0, 255), 3)
    cv_show("img",img)
    refCnts = sorted(refCnts, key=cv2.contourArea, reverse=True)
    refCnts = sort_contours(refCnts, method="left-to-right")[0]  # 排序從左到右,從上到下
    # 遍歷每一個(gè)輪廓
    for (i, c) in enumerate(refCnts):
        # 計(jì)算外接矩形并且resize成合適大小
        (x, y, w, h) = cv2.boundingRect(c)
        # roi為外接矩形的區(qū)域
        roi = ref[y:y + h, x:x + w]
        roi = cv2.resize(roi, (57, 58))
        cv_show("ror",roi)
        # 每一個(gè)數(shù)字對(duì)應(yīng)一個(gè)模板
        digits[i] = roi
#####################################################選擇圖片并對(duì)銀行卡號(hào)識(shí)別######
def process_img(image):
    # 初始化卷積核
    rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
    sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
    # 讀取輸入圖像,預(yù)處理
    #image = cv2.imread(img)
    image = resize(image, width=300)
    # 轉(zhuǎn)灰度圖
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    cv_show("gray",gray)
    # 禮帽(頂帽)操作,過(guò)濾掉沒(méi)有用的東西,突出更明亮的區(qū)域   將核傳進(jìn)去
    tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)
    cv_show("tophat",tophat)
    # 計(jì)算  ...邊緣檢測(cè)
    gradX = cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=1) # Sobel算子
    gradX = np.absolute(gradX)    # 絕對(duì)值
    (minVal, maxVal) = (np.min(gradX), np.max(gradX))
    gradX = (255 * ((gradX - minVal) / (maxVal - minVal))) # 歸一化
    gradX = gradX.astype("uint8")
    # 通過(guò)閉操作,(先膨脹,在腐蝕)將數(shù)字連在一起
    gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel)
    cv_show("gardX",gradX)
    # THRESH_OTSU會(huì)自動(dòng)尋找合適的閾值,適合雙峰,需把閾值參數(shù)設(shè)置為0
    thresh = cv2.threshold(gradX, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
    # 再次閉操作,對(duì)縫隙進(jìn)行填充
    thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel)
    cv_show("thresh",thresh)
    # 計(jì)算輪廓
    threshCnts, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = threshCnts
    cur_img = image.copy()
    cv2.drawContours(cur_img, cnts, -1, (0, 0, 255), 3)
    cv_show('curimg', cur_img)
    # 想要的區(qū)域
    locs = []
    # 遍歷輪廓
    for (i, c) in enumerate(cnts):
        # 計(jì)算外接矩形
        (x, y, w, h) = cv2.boundingRect(c)
        ar = w / float(h)
        # 適合合適的區(qū)域,根據(jù)實(shí)際任務(wù)來(lái),這里的基本是四個(gè)數(shù)字一組
        if ar > 2.5 and ar < 4.0:
            if (w > 40 and w < 55) and (h > 10 and h < 20): # w = 46 h=13
                # 符合的輪廓留下來(lái)
                locs.append((x, y, w, h))
    # 將符合的輪廓從左到右排序
    locs = sorted(locs, key=lambda x: x[0])
    # output = []
    # 遍歷每一個(gè)輪廓中的數(shù)字
    for (i, (gX, gY, gW, gH)) in enumerate(locs):
        # 初始化列表
        groupOutput = []
        # 根據(jù)坐標(biāo)提取每一個(gè)組  多提取一些
        group = gray[gY - 5:gY + gH + 5, gX - 5:gX + gW + 5]
        # 預(yù)處理 輪廓檢測(cè)
        group = cv2.threshold(group, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
        cv_show("group",group)
        # 將每個(gè)分割的四位數(shù)字展示
        # 計(jì)算每一個(gè)輪廓
        digitCnts, hierarchy = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL,
                                                cv2.CHAIN_APPROX_SIMPLE)
        # 排序
        digitCnts = contours.sort_contours(digitCnts, method="left-to-right")[0]
        # 計(jì)算每一組總的每一個(gè)數(shù)值
        for c in digitCnts:
            # 找到當(dāng)前數(shù)值的輪廓,resize成合適的大小
            (x, y, w, h) = cv2.boundingRect(c)
            roi = group[y:y + h, x:x + w]
            roi = cv2.resize(roi, (57, 58))
            # 計(jì)算匹配得分
            scores = []
            # 在模板章中計(jì)算每一個(gè)得分
            for (digit, digiROI) in digits.items():
                # 模板匹配
                result = cv2.matchTemplate(roi, digiROI, cv2.TM_CCOEFF)
                (_, score, _, _) = cv2.minMaxLoc(result)
                scores.append(score)
            # 得到合適的數(shù)字
            groupOutput.append(str(np.argmax(scores)))
        # 畫(huà)出來(lái)四位數(shù)的框
        cv2.rectangle(image, (gX - 5, gY - 5), (gX + gW + 5, gY + gH + 5), (0, 0, 255), 1)
        # cv2.putText(image, "".join(groupOutput), (gX, gY - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)
        img_re=cv2.putText(image, "".join(groupOutput), (gX, gY - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)
        # 得到結(jié)果
        output.extend(groupOutput)
    return img_re
def main_run(img):
    process_template()
    img2 =process_img(img)
    # 避免再次識(shí)別卡號(hào)重復(fù)
    text = "銀行卡號(hào)為: {}".format("".join(output))[-16:]
    text2="銀行卡號(hào)為:"+text
    return img2,text2
if __name__ == '__main__':
    process_template()
    img=".\images\card04.png"
    #img = "card_01.png"
    process_img(img)
    print("銀行卡號(hào)為: {}".format("".join(output)))

UI文件代碼1:

# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'main_win.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Mainwindow(object):
    def setupUi(self, Mainwindow):
        Mainwindow.setObjectName("Mainwindow")
        Mainwindow.resize(900, 650)
        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)
        Mainwindow.setFont(font)
        Mainwindow.setStyleSheet("QPushButton{\n"
"    background-color:rgb(0,174,236);\n"
"    border:none;\n"
"    height:35px;\n"
"    border-radius:12px;\n"
"}\n"
"QPushButton::hover{\n"
"    background-color:rgb(65,184,131);\n"
"}\n"
"")
        self.frame_3 = QtWidgets.QFrame(Mainwindow)
        self.frame_3.setGeometry(QtCore.QRect(-10, 0, 901, 671))
        self.frame_3.setStyleSheet("QFrame{\n"
"    background-color:rgb(255,250,240);\n"
"    border:none;\n"
"    height:35px;\n"
"    border-radius:12px;\n"
"}")
        self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_3.setObjectName("frame_3")
        self.frame = QtWidgets.QFrame(self.frame_3)
        self.frame.setGeometry(QtCore.QRect(10, -10, 891, 391))
        self.frame.setStyleSheet("QFrame{\n"
"    background-color:rgb(191,239,255);\n"
"    border:none;\n"
"    height:35px;\n"
"    border-radius:12px;\n"
"}")
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.label = QtWidgets.QLabel(self.frame)
        self.label.setGeometry(QtCore.QRect(320, 130, 241, 151))
        font = QtGui.QFont()
        font.setFamily("Bahnschrift")
        font.setPointSize(23)
        self.label.setFont(font)
        self.label.setObjectName("label")
        self.pushButton1 = QtWidgets.QPushButton(self.frame_3)
        self.pushButton1.setGeometry(QtCore.QRect(380, 430, 110, 40))
        self.pushButton1.setStyleSheet("QPushButton{\n"
"    background-color:rgb(0,174,236);\n"
"    border:none;\n"
"    height:35px;\n"
"    border-radius:12px;\n"
"}\n"
"QPushButton::hover{\n"
"    background-color:rgb(65,184,131);\n"
"}")
        self.pushButton1.setObjectName("pushButton1")
        self.retranslateUi(Mainwindow)
        QtCore.QMetaObject.connectSlotsByName(Mainwindow)
    def retranslateUi(self, Mainwindow):
        _translate = QtCore.QCoreApplication.translate
        Mainwindow.setWindowTitle(_translate("Mainwindow", "銀行卡號(hào)識(shí)別"))
        self.label.setText(_translate("Mainwindow", "銀行卡號(hào)識(shí)別"))
        self.pushButton1.setText(_translate("Mainwindow", "選擇"))

UI文件代碼2:

# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'card_re.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Card_re_Window(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(900, 650)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label_daichuli = QtWidgets.QLabel(self.centralwidget)
        self.label_daichuli.setGeometry(QtCore.QRect(100, 70, 300, 189))
        self.label_daichuli.setObjectName("label_daichuli")
        self.label_jieguo = QtWidgets.QLabel(self.centralwidget)
        self.label_jieguo.setGeometry(QtCore.QRect(510, 70, 300, 189))
        self.label_jieguo.setObjectName("label_jieguo")
        self.pushButton_upload = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_upload.setGeometry(QtCore.QRect(220, 370, 100, 35))
        self.pushButton_upload.setStyleSheet("QPushButton{\n"
"    background-color:rgb(0,174,236);\n"
"    border:none;\n"
"    height:35px;\n"
"    border-radius:12px;\n"
"}\n"
"QPushButton::hover{\n"
"    background-color:rgb(65,184,131);\n"
"}")
        self.pushButton_upload.setObjectName("pushButton_upload")
        self.pushButton_save = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_save.setGeometry(QtCore.QRect(580, 370, 100, 35))
        self.pushButton_save.setStyleSheet("QPushButton{\n"
"    background-color:rgb(0,174,236);\n"
"    border:none;\n"
"    height:35px;\n"
"    border-radius:12px;\n"
"}\n"
"QPushButton::hover{\n"
"    background-color:rgb(65,184,131);\n"
"}")
        self.pushButton_save.setObjectName("pushButton_save")
        self.pushButton_card_re = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_card_re.setGeometry(QtCore.QRect(390, 440, 110, 40))
        self.pushButton_card_re.setStyleSheet("QPushButton{\n"
"    background-color:rgb(0,174,236);\n"
"    border:none;\n"
"    height:35px;\n"
"    border-radius:12px;\n"
"}\n"
"QPushButton::hover{\n"
"    background-color:rgb(65,184,131);\n"
"}")
        self.pushButton_card_re.setObjectName("pushButton_card_re")
        self.pushButton_return = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_return.setGeometry(QtCore.QRect(390, 540, 110, 40))
        self.pushButton_return.setStyleSheet("QPushButton{\n"
"    background-color:rgb(0,174,236);\n"
"    border:none;\n"
"    height:35px;\n"
"    border-radius:12px;\n"
"}\n"
"QPushButton::hover{\n"
"    background-color:rgb(65,184,131);\n"
"}")
        self.pushButton_return.setObjectName("pushButton")
        self.label_cardnum = QtWidgets.QLabel(self.centralwidget)
        self.label_cardnum.setGeometry(QtCore.QRect(510, 310, 411, 31))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.label_cardnum.setFont(font)
        self.label_cardnum.setObjectName("label_cardnum")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 900, 26))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "銀行卡識(shí)別系統(tǒng)"))
        self.label_daichuli.setText(_translate("MainWindow", "銀行卡"))
        self.label_jieguo.setText(_translate("MainWindow", "識(shí)別后"))
        self.pushButton_upload.setText(_translate("MainWindow", "選擇銀行卡"))
        self.pushButton_save.setText(_translate("MainWindow", "保存圖片"))
        self.pushButton_card_re.setText(_translate("MainWindow", "識(shí)別"))
        self.pushButton_return.setText(_translate("MainWindow", "返回"))
        self.label_cardnum.setText(_translate("MainWindow", "銀行卡號(hào):"))

四、運(yùn)行結(jié)果圖片

運(yùn)行結(jié)果主頁(yè)面圖

銀行卡識(shí)別結(jié)果頁(yè)面圖

到此這篇關(guān)于python 實(shí)現(xiàn)銀行卡號(hào)查詢銀行名稱和簡(jiǎn)稱的文章就介紹到這了,更多相關(guān)python銀行卡號(hào)查詢內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 快速一鍵生成Python爬蟲(chóng)請(qǐng)求頭

    快速一鍵生成Python爬蟲(chóng)請(qǐng)求頭

    這篇文章主要介紹了如何快速一鍵生成Python爬蟲(chóng)請(qǐng)求頭,幫助大家更好的理解和學(xué)習(xí)使用python爬蟲(chóng),感興趣的朋友可以了解下
    2021-03-03
  • python內(nèi)置函數(shù)zip詳解

    python內(nèi)置函數(shù)zip詳解

    這篇文章主要為大家介紹了python內(nèi)置函數(shù)zip,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • python捕獲警告的三種方法

    python捕獲警告的三種方法

    這篇文章主要介紹了python捕獲警告的三種方法,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下
    2021-03-03
  • 淺析python字符串前加r、f、u、l 的區(qū)別

    淺析python字符串前加r、f、u、l 的區(qū)別

    這篇文章主要介紹了淺析python字符串前加r、f、u、l 的區(qū)別,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • python?特有語(yǔ)法推導(dǎo)式的基本使用

    python?特有語(yǔ)法推導(dǎo)式的基本使用

    python中有一種特有的語(yǔ)法,就是推導(dǎo)式(又稱為解析式)。推導(dǎo)式是可以從一個(gè)數(shù)據(jù)序列構(gòu)建另一個(gè)新的數(shù)據(jù)序列的結(jié)構(gòu)體
    2022-03-03
  • Python如何判斷字符串是否僅包含數(shù)字

    Python如何判斷字符串是否僅包含數(shù)字

    在用Python進(jìn)行數(shù)據(jù)處理的時(shí)候,經(jīng)常會(huì)遇到DataFrame中的某一列本應(yīng)該是數(shù)值類(lèi)型,但由于數(shù)據(jù)不規(guī)范導(dǎo)致在字段中夾雜了非數(shù)值類(lèi)型,本文就介紹了Python如何判斷字符串是否僅包含數(shù)字,感興趣的可以了解一下
    2022-03-03
  • Python自動(dòng)化操作實(shí)現(xiàn)圖例繪制

    Python自動(dòng)化操作實(shí)現(xiàn)圖例繪制

    這篇文章主要介紹了Python自動(dòng)化操作實(shí)現(xiàn)圖例繪制,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Python常駐任務(wù)實(shí)現(xiàn)接收外界參數(shù)代碼解析

    Python常駐任務(wù)實(shí)現(xiàn)接收外界參數(shù)代碼解析

    這篇文章主要介紹了Python常駐任務(wù)實(shí)現(xiàn)接收外界參數(shù)代碼解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Django Sitemap 站點(diǎn)地圖的實(shí)現(xiàn)方法

    Django Sitemap 站點(diǎn)地圖的實(shí)現(xiàn)方法

    這篇文章主要介紹了Django Sitemap 站點(diǎn)地圖的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • 一篇文章帶你了解python標(biāo)準(zhǔn)庫(kù)--random模塊

    一篇文章帶你了解python標(biāo)準(zhǔn)庫(kù)--random模塊

    這篇文章主要給大家介紹了關(guān)于Python中random模塊常用方法的使用教程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08

最新評(píng)論