天天看點

Python 智能銀行卡識别系統的實作 — 系統的實作第一部分(一)PyQt5 的演變史(二)PyQt5 桌面 GUI 開發(三)一個登陸系統的實作第二部分(一)先看看系統的效果(二)系統實作的大緻思路(三)完整代碼

第一部分

jacky 的一貫理念,學東西不要學表面,而要學本質。技術之上,永遠都是哲學。

本文的視訊示範如下:

https://v.qq.com/x/page/v0890lmkjfo.html

(一)PyQt5 的演變史

要說清楚 PyQt5 是什麼,我們要先簡要說說 Qt 是什麼

1. Qt 是什麼

先抽象的說 Qt 是什麼?

  • Qt 是跨平台 C++ 圖形使用者界面應用程式開發架構,Qt 可以同時支援桌面應用程式開發、嵌入式開發和移動開發,覆寫了現在所有的主流平台。1991年由挪威奇趣科技開發;這個挪威的奇趣科技,jacky 再多說幾句,這家公司還有很多著名的産品,比如說 Linux 作業系統上最流行的桌面環境之一 KDE,有 Autodesk Maya , 有 WPS , 有 YY 語音,有 VirtualBox ,有 Opera 浏覽器,極品飛車,暴雪戰網用戶端等等,總之很牛X。
  • 還有 Qt 的開發宗旨,jacky 是比較喜歡的:"Code Less; Create More; Deploy Anywhere"

2. QT Designer 是什麼?

程式員制作程式 UI 界面,一般會有2種方法,利用 UI 制作工具和純代碼編寫,像移動開發中的 Android 和 iOS 都是這樣,在 PyQt5中,我們也有這麼2種方式。
  • QtDesinger 是專門用來制作 Qt 程式 UI 界面的工具,它使用起來非常簡單,隻要通過拖拽和點選就可以完成複雜的界面設計,而且還可以随時預覽檢視效果圖。

3. PyQt5 是什麼?

  • PyQt 是一個用于建立 GUI 應用程式的跨平台工具包,它将 Python 與 Qt 庫融為一體。也就是說,PyQt 允許使用Python語言調用 Qt 庫中的 API 。這樣做的最大好處就是在保留了 Qt 高運作效率的同時,大大提高了開發效率。因為,使用 Python 語言開發程式要比使用 C++ 語言開發程式快得多。 PyQt 對 Qt 做了完整的封裝,幾乎可以用 PyQt做 Qt 能做的任何事情。
  • 由于目前最新的 PyQt 版本是5.11,是以習慣上成為 PyQt 為 PyQt5 。
  • 下面解釋一個問題就是:是用 PyQt好,還是 QT 好???
    • 其實關注這個問題的朋友可能是真的想知道答案,但是這個問題其實是個僞命題。與其說是 PyQT 好還是 QT 好,倒不如說你更熟悉于 C++ 開始還是 Python 開發。熟悉 C++ 就用 QT ,熟悉 Python 就用 PyQt。

(二)PyQt5 桌面 GUI 開發

本部分 jacky 偷個懶,轉載一位網友的文章,我覺得很不錯,分享給大家
http://blog.sina.com.cn/s/blog_989218ad0102wz1k.html

先看效果:

Python 智能銀行卡識别系統的實作 — 系統的實作第一部分(一)PyQt5 的演變史(二)PyQt5 桌面 GUI 開發(三)一個登陸系統的實作第二部分(一)先看看系統的效果(二)系統實作的大緻思路(三)完整代碼

沒錯,學過C#的同學應該很熟悉這個界面,按鈕風格和界面風格很相似,萬萬沒想到,python也可以做出這樣的界面。

2.1 安裝python

為啥要說這個,我們打開pip,搜尋:PyQt5,或者直接打開下面的連接配接:

https://pypi.python.org/pypi/PyQt5/5.9.1
Python 智能銀行卡識别系統的實作 — 系統的實作第一部分(一)PyQt5 的演變史(二)PyQt5 桌面 GUI 開發(三)一個登陸系統的實作第二部分(一)先看看系統的效果(二)系統實作的大緻思路(三)完整代碼

可以看到,PyQt5所支援的python版本是從3.5開始的,這點很重要。

找一個python3.5以上的版本安裝:

https://www.python.org/downloads/windows/

2.2 安裝PyQt5

推薦使用pip安裝:

pip3 install PyQt5

等待片刻,繼續安裝PyQt5-tools

pip install PyQt5-tools

2.3 配置pycharm

官網下載下傳安裝pycharm:

https://www.jetbrains.com/pycharm/

1、點選:File -》Settings

Python 智能銀行卡識别系統的實作 — 系統的實作第一部分(一)PyQt5 的演變史(二)PyQt5 桌面 GUI 開發(三)一個登陸系統的實作第二部分(一)先看看系統的效果(二)系統實作的大緻思路(三)完整代碼

2、Tools -》 External Tools -》點選“+”号

(ps:下面是我配置好的,你的軟體還沒有很正常,繼續往下看)

Python 智能銀行卡識别系統的實作 — 系統的實作第一部分(一)PyQt5 的演變史(二)PyQt5 桌面 GUI 開發(三)一個登陸系統的實作第二部分(一)先看看系統的效果(二)系統實作的大緻思路(三)完整代碼

3、設定Qt Designer

修改三個地方,其他地方預設:

Name:Qt Designer

Programs:D:Program FilesPython35Libsite-packagespyqt5-toolsdesigner.exe

Working directory:$ ProjectFileDir$

(ps:Programs參數需要修改為你電腦裡邊的“designer.exe”路徑)

Python 智能銀行卡識别系統的實作 — 系統的實作第一部分(一)PyQt5 的演變史(二)PyQt5 桌面 GUI 開發(三)一個登陸系統的實作第二部分(一)先看看系統的效果(二)系統實作的大緻思路(三)完整代碼

4、配置PyUIC

設定四個地方,其他可以預設(我也不知道怎麼改,那就預設吧)

Name:PyUIC

Programs:D:Program FilesPython35python.exe

Parameters:-m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py

(ps:Programs參數需要修改為你電腦裡邊的python“python.exe”路徑)

Python 智能銀行卡識别系統的實作 — 系統的實作第一部分(一)PyQt5 的演變史(二)PyQt5 桌面 GUI 開發(三)一個登陸系統的實作第二部分(一)先看看系統的效果(二)系統實作的大緻思路(三)完整代碼

2.4 使用Qt Designer

1、完成以上步驟之後,點選 Tools -》External Tools -》Qt Designer 啟動我們的Qt Designer

Python 智能銀行卡識别系統的實作 — 系統的實作第一部分(一)PyQt5 的演變史(二)PyQt5 桌面 GUI 開發(三)一個登陸系統的實作第二部分(一)先看看系統的效果(二)系統實作的大緻思路(三)完整代碼

2、啟動後選擇:Widget,建立空白的視窗,點選 Create,其他預設就行

Python 智能銀行卡識别系統的實作 — 系統的實作第一部分(一)PyQt5 的演變史(二)PyQt5 桌面 GUI 開發(三)一個登陸系統的實作第二部分(一)先看看系統的效果(二)系統實作的大緻思路(三)完整代碼

3、從左邊 1區 拖拽,注意是“拖拽”控件到 2區,在 3區 中修改對應屬性,很像vs有木有

Python 智能銀行卡識别系統的實作 — 系統的實作第一部分(一)PyQt5 的演變史(二)PyQt5 桌面 GUI 開發(三)一個登陸系統的實作第二部分(一)先看看系統的效果(二)系統實作的大緻思路(三)完整代碼

4、昨晚基本的界面設定之後,會看到同目錄下生成了一個“.ui”的檔案

Python 智能銀行卡識别系統的實作 — 系統的實作第一部分(一)PyQt5 的演變史(二)PyQt5 桌面 GUI 開發(三)一個登陸系統的實作第二部分(一)先看看系統的效果(二)系統實作的大緻思路(三)完整代碼

5、右鍵 External Tools -》PyUIC ,将“.ui”檔案轉為“.py”檔案

Python 智能銀行卡識别系統的實作 — 系統的實作第一部分(一)PyQt5 的演變史(二)PyQt5 桌面 GUI 開發(三)一個登陸系統的實作第二部分(一)先看看系統的效果(二)系統實作的大緻思路(三)完整代碼

6、這時,如果一切正常,沒有報錯的話,會在同目錄下生成對應的“.py”檔案

Python 智能銀行卡識别系統的實作 — 系統的實作第一部分(一)PyQt5 的演變史(二)PyQt5 桌面 GUI 開發(三)一個登陸系統的實作第二部分(一)先看看系統的效果(二)系統實作的大緻思路(三)完整代碼

7、将下面的代碼,放到生成的“.py”檔案,放到最後就行(注意縮進)

if __name__=="__main__":
    import sys
    from PyQt5.QtGui import QIcon
    app=QtWidgets.QApplication(sys.argv)
    widget=QtWidgets.QWidget()
    ui=Ui_Form()
    ui.setupUi(widget)
    widget.setWindowIcon(QIcon('web.png'))#增加icon圖示,如果沒有圖檔可以沒有這句
    widget.show()
    sys.exit(app.exec_())           

8、運作啟動,好了,恭喜你,開啟了pythonGUI

Python 智能銀行卡識别系統的實作 — 系統的實作第一部分(一)PyQt5 的演變史(二)PyQt5 桌面 GUI 開發(三)一個登陸系統的實作第二部分(一)先看看系統的效果(二)系統實作的大緻思路(三)完整代碼

(三)一個登陸系統的實作

3.1 前面的補充

  • 對于上面我轉載網友的内容,jacky 這裡補充幾點:
  1. 我們下載下傳 PyQt5 的時候,建議使用豆瓣源(什麼是豆瓣源可以看我之前的文章)
pip install -i https://pypi.douban.com/simple/ PyQt5
pip install -i https://pypi.douban.com/simple/ PyQt5-tools           
  1. 關于進階學習我們還可以看以下資料

《PyQt5 教程》

http://code.py40.com/pyqt5/

3.2 Python 智能銀行卡識别系統實作-登陸功能

  • 完整代碼
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'login.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(380, 245)
        self.widget = QtWidgets.QWidget(Form)
        self.widget.setGeometry(QtCore.QRect(50, 30, 291, 165))
        self.widget.setObjectName("widget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.widget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.label = QtWidgets.QLabel(self.widget)
        self.label.setObjectName("label")
        self.verticalLayout.addWidget(self.label)
        self.lineEdit = QtWidgets.QLineEdit(self.widget)
        self.lineEdit.setObjectName("lineEdit")
        self.verticalLayout.addWidget(self.lineEdit)
        self.label_2 = QtWidgets.QLabel(self.widget)
        self.label_2.setObjectName("label_2")
        self.verticalLayout.addWidget(self.label_2)
        self.lineEdit_2 = QtWidgets.QLineEdit(self.widget)
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.verticalLayout.addWidget(self.lineEdit_2)
        self.pushButton = QtWidgets.QPushButton(self.widget)
        self.pushButton.setObjectName("pushButton")
        self.verticalLayout.addWidget(self.pushButton)
        self.pushButton_2 = QtWidgets.QPushButton(self.widget)
        self.pushButton_2.setObjectName("pushButton_2")
        self.verticalLayout.addWidget(self.pushButton_2)

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "智能銀行卡識别系統 v1.0 login"))
        self.label.setText(_translate("Form", "使用者名:"))
        self.label_2.setText(_translate("Form", "密碼:"))
        self.pushButton.setText(_translate("Form", "登入"))
        self.pushButton_2.setText(_translate("Form", "退出"))

        # 登入按鈕
        self.pushButton.clicked.connect(self.onclick)
        #退出按鈕
        self.pushButton_2.clicked.connect(quit)


    def onclick(self):
        if self.lineEdit.text() == 'jacky':
            if self.lineEdit_2.text() == '666666':
                MainWindow.close(widget)
            else:
                self.lineEdit_2.setText('密碼錯誤請重新輸入')
        else:
            self.lineEdit.setText('使用者錯誤請重新輸入')


if __name__=="__main__":
    import sys
    from PyQt5.QtGui import QIcon
    app=QtWidgets.QApplication(sys.argv)
    MainWindow=QtWidgets.QMainWindow
    widget=QtWidgets.QWidget()
    ui=Ui_Form()
    ui.setupUi(widget)
    #widget.setWindowIcon(QIcon('web.png'))#增加icon圖示,如果沒有圖檔可以沒有這句
    widget.show()
    sys.exit(app.exec_())           

第二部分

本文适合于所有層次的Python學習者,包括AI愛好者和技術愛好者來學習。誠然,人工智能是個有着深刻數學邏輯的知識體系,包括機器學習,搜尋問題,知識表示等等等等的理論。本文,嚴禁的說,我們隻是簡單調用了百度AI的成果,jacky通過本文希望給大家一個啟發吧,畢竟理論是理論,實際是實際,賺錢是賺錢,就這樣。

本文視訊示範如下(由于環境因素的限制,這段示範視訊是無聲的,後期jacky 在Gitchat ,阿裡雲以及抖音都會有直播的分享,請大家關注):

視訊示範連結

(一)先看看系統的效果

Python 智能銀行卡識别系統的實作 — 系統的實作第一部分(一)PyQt5 的演變史(二)PyQt5 桌面 GUI 開發(三)一個登陸系統的實作第二部分(一)先看看系統的效果(二)系統實作的大緻思路(三)完整代碼
Python 智能銀行卡識别系統的實作 — 系統的實作第一部分(一)PyQt5 的演變史(二)PyQt5 桌面 GUI 開發(三)一個登陸系統的實作第二部分(一)先看看系統的效果(二)系統實作的大緻思路(三)完整代碼

(二)系統實作的大緻思路

系統開發環境要求:

1.開發工具:Pycharm 、PyQt5

2.開發子產品: urllib、urllib.request、Base64、json、PyQt5

3.API 接口:百度API

2.1 圖檔識别工具界面

  • PyQt5 桌面 GUI 開發
    • 這部分,是 jacky 上次主要的分享内容,不是很熟悉的朋友可以參見《Python 智能銀行卡識别系統的實作 (1)— PyQt5 實作登陸功能》,也可以配合本次視訊前面的操作示範來看。

2.2 選擇識别類型

  • 我們要設定識别的銀行卡,信用卡還是身份證等等

2.3 選擇要識别的圖檔

  • 這裡的主要難點就是要搞懂這句代碼:self.label_3.setPixmap(scarePixmap),具體的代碼注解可以參見第三部分的完整代碼,其他的技巧點都是Qt 裡東西,關于QPixmap的用法等等,因為不是邏輯性的東西,大家可以自行百度。

2.4 識别結果

  • 這裡用到的就是百度的AI 接口,
    Python 智能銀行卡識别系統的實作 — 系統的實作第一部分(一)PyQt5 的演變史(二)PyQt5 桌面 GUI 開發(三)一個登陸系統的實作第二部分(一)先看看系統的效果(二)系統實作的大緻思路(三)完整代碼

2.5 複制到粘貼闆

  • 這是PyQt5 的一些小功能,我們自行百度即可。

(三)完整代碼

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'ocr.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!

# 原創:朱元祿(jacky)首發:資料分析部落(datashuju)

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import json
# 我們是Python3 ,在調用百度AI token 的時候不用官方文檔中的urllib2,替換成 urllib.request
import urllib, urllib.request, sys
import ssl
import base64
# 這裡輸入自己擷取的AK以及SK
API_KEY = "jacky提醒你,這裡要輸入你自己申請的AK,不要忘記"
SECRET_KEY = "jacky提醒你,這裡要輸入你自己申請的AK,不要忘記"

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(793, 452)
        self.widget = QtWidgets.QWidget(Form)
        self.widget.setGeometry(QtCore.QRect(80, 41, 631, 371))
        self.widget.setObjectName("widget")
        self.gridLayout = QtWidgets.QGridLayout(self.widget)
        self.gridLayout.setContentsMargins(0, 0, 0, 0)
        self.gridLayout.setObjectName("gridLayout")
        self.pushButton = QtWidgets.QPushButton(self.widget)
        self.pushButton.setObjectName("pushButton")
        self.gridLayout.addWidget(self.pushButton, 2, 2, 1, 1)
        self.lineEdit = QtWidgets.QLineEdit(self.widget)
        self.lineEdit.setObjectName("lineEdit")
        self.gridLayout.addWidget(self.lineEdit, 2, 1, 1, 1)
        self.label_2 = QtWidgets.QLabel(self.widget)
        self.label_2.setObjectName("label_2")
        self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
        self.label_3 = QtWidgets.QLabel(self.widget)
        self.label_3.setObjectName("label_3")
        self.label_3.setStyleSheet("background-color:gray")
        self.gridLayout.setObjectName("label_3")
        self.gridLayout.addWidget(self.label_3, 3, 0, 1, 3)
        self.lineEdit_2 = QtWidgets.QLineEdit(self.widget)
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.gridLayout.addWidget(self.lineEdit_2, 7, 0, 1, 2)
        self.pushButton_2 = QtWidgets.QPushButton(self.widget)
        self.pushButton_2.setObjectName("pushButton_2")
        self.gridLayout.addWidget(self.pushButton_2, 7, 2, 1, 1)
        self.label = QtWidgets.QLabel(self.widget)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
        self.comboBox = QtWidgets.QComboBox(self.widget)
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItem("")
        self.gridLayout.addWidget(self.comboBox, 0, 1, 1, 1)

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "智能銀行卡識别系統_v1.0"))
        self.pushButton.setText(_translate("Form", "選擇"))
        self.label_2.setText(_translate("Form", "選擇要識别的圖檔"))
        self.label_3.setText(_translate("Form", ""))
        self.lineEdit_2.setText(_translate("Form", "顯示識别結果"))
        self.pushButton_2.setText(_translate("Form", "複制"))
        self.label.setText(_translate("Form", "需要識别的類型:"))
        self.comboBox.setItemText(0, _translate("Form", "銀行卡"))
        self.comboBox.setItemText(1, _translate("Form", "身份證"))
        self.comboBox.setItemText(2, _translate("Form", "車牌号"))
        # 第一步,我們要讓系統可以點選選擇來擷取我們要上傳的圖檔
        self.pushButton.clicked.connect(self.openfile)

    # 第二步,設定選擇圖檔的路徑
    def openfile(self):
        self.download_path = QFileDialog.getOpenFileName(self.widget,"請選擇需要識别的圖檔","/","Image File(*.jpg *.png)")
        # 判斷是否選擇了圖檔
        if not self.download_path[0].strip():
            pass
        else:
            self.lineEdit.setText(self.download_path[0])
            # 自動解析圖像
            pixmap = QPixmap(self.download_path[0])
            # 選擇圖檔,圖檔可能有大有小,我們簡單的處理一下圖檔
            scarePixmap = pixmap.scaled(QSize(629,271),aspectRatioMode=Qt.KeepAspectRatio)
            # 把圖檔設定到我們的控件裡
            self.label_3.setPixmap(scarePixmap)
            self.typeTp()

    # 第三步:選擇類型

    def typeTp(self):
        if self.comboBox.currentIndex()==0:
            self.get_token()
            self.get_bankcard(self.get_token())


    def get_token(self):
        # client_id 為官網擷取的AK, client_secret 為官網擷取的SK
        host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id='+API_KEY+'&client_secret='+SECRET_KEY
        request = urllib.request.Request(host)
        request.add_header('Content-Type', 'application/json; charset=UTF-8')
        response = urllib.request.urlopen(request)
        content = response.read()
        if (content):
            print(content)
            # 解釋傳回的 token 資料
            self.access_token = json.loads(content)['access_token']
            return self.access_token

    def get_bankcard(self,access_token):
        url = 'https://aip.baidubce.com/rest/2.0/ocr/v1/bankcard?access_token=' + access_token
        f = open(self.download_path[0], 'rb')  # 二進制方式打開圖檔案
        img = base64.b64encode(f.read())
        params = {"image": img}
        # 百度AI給的示例是Python2
        # params = urllib.urlencode(params)
        params = urllib.parse.urlencode(params).encode('utf-8')
        request = urllib.request.Request(url, params)
        request.add_header('Content-Type', 'application/x-www-form-urlencoded')
        response = urllib.request.urlopen(request)
        content = response.read()
        if (content):
            print(content)
            bankcards = json.loads(content)
            stover = '識别結果:\n'

            try:
                if bankcards['result']['bank_card_type'] == 0:
                    bank_card_type = "不能識别"
                elif bankcards['result']['bank_card_type'] == 1:
                    bank_card_type = "借記卡"
                elif bankcards['result']['bank_card_type'] == 2:
                    bank_card_type = "信用卡"
                stover += '卡号: {}\n 銀行:{}\n 類型:{}'.format(bankcards['result']['bank_card_number'],bankcards['result']['bank_name'],bank_card_type)
            except BaseException:
                stover += '解析錯誤'
            self.lineEdit_2.setText(stover)
if __name__ == "__main__":
    import sys
    from PyQt5.QtGui import QIcon
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow
    widget = QtWidgets.QWidget()
    ui = Ui_Form()
    ui.setupUi(widget)
    # widget.setWindowIcon(QIcon('web.png'))#增加icon圖示,如果沒有圖檔可以沒有這句
    widget.show()
    sys.exit(app.exec_())