赞
踩
python利用百度文字识别功能,实现对上传的名片进行扫描,并获取名片信息;可查看名片原图,也可以保存信息到Excel。
开发环境:Windows7+python3.7+pycharm2018.2.4(开发工具);
目录机构:
最终效果:
创建过程参考《微信小程序利用百度AI实现扫描身份证获取信息功能》(把“图像识别”换为“文字识别”)。
一、阅读器UI设计
1. 安装模块和配置工具,参考《python实现小说阅读器》;
2. 运行工具QtDesigner,利用QtDesigner工具箱设计出界面效果(所需要的控件可查看右边区域),保存效果为文件bc.ui;
3. 对文件bc.ui执行pyUIC(ui转化为py代码),执行完生成文件bc.py。
二、代码设计
1. 新建文件bc_main.py,该文件为项目主文件,初始化页面并显示;
2. 添加内置模块(下面代码使用)和主方法(用于运行后弹出界面);
Tips:由于是引入bc(bc.py),而未对其修改,所以开发过程中可以随时修改设计重新生成bc.py,不会覆盖掉自己编写的代码;但要注意如果修改了表单属性和名称等,编写的代码要跟着修改;
- from PyQt5.QtWidgets import *
- from PyQt5.QtGui import *
-
- # 引入自定义模块
- import bc
- # 引入内置模块
- import sys
- import os
- # 引入第三方模块
- import pandas as pd
- import requests, base64
- from PIL import Image
- import phone
- # 文字识别sdk所需要模块
- from aip import AipOcr
- class parentWindow(QWidget,bc.Ui_Form):
- # 初始化方法
- def __init__(self):
- # 找到父类 首页面
- super(parentWindow, self).__init__()
- # 初始化页面方法
- self.setupUi(self)
- # 点击选择名片
- self.selectCard.clicked.connect(self.openfile)
- # 点击查看名片
- self.viewButton.clicked.connect(self.viewbtn)
- # 点击保存按钮
- self.saveButton.clicked.connect(self.saveData)
- if __name__=='__main__':
- # 每一个PyQt5应用都必须创建一个应用对象
- app=QApplication(sys.argv)
- # 初始化页面
- window=parentWindow()
- # 显示首页
- window.show()
- sys.exit(app.exec_())
3. 添加公共代码,用来判断“名片信息表.xlsx”是否存在,不存在则新建该文件并定义好列名;
- # 获取当前路径
- cdir = os.getcwd()
- # 文件路径
- path = cdir+'/名片信息表.xlsx'
- # 读取路径 判断是否创建了文件
- if not os.path.exists(path):
- # 根据路径建立文件夹
- # os.makedirs(path)
- # 姓名 手机 电话 邮箱 网址 公司 地址 城市
- cardfile = pd.DataFrame(columns=['name', 'mobile', 'tel', 'email', 'url', 'comp', 'addr', 'city'])
- # 生成xlsx文件
- cardfile.to_excel(path, sheet_name='data', index=None)
4. 添加图片识别函数recgImg,用来扫描图片获取图片信息;而文字识别百度给了两种方法选择,一种使用API(本文使用),详细参考名片识别 - 文字识别OCR;另一种是使用SDK,详细参考名片识别 - 文字识别OCR
- # 识别名片图片
- def recgImg(self):
- # 获取baiduToken
- apikey = '你的apikey'
- seckey = '你的seckey'
- tokenUrl = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=' + apiKey + '&client_secret=' + seckey
- res = requests.get(url=tokenUrl, headers={'content-type': 'application/json; charset=UTF-8'}).json()
- baiduToken = res['access_token']
-
- '''
- 名片识别(API)
- '''
- request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/business_card"
- # 二进制方式打开图片文件
- f = open(self.download_path[0], 'rb')
- img = base64.b64encode(f.read())
-
- params = {"image": img}
- # access_token = '[调用鉴权接口获取的token]'
- request_url = request_url + "?access_token=" + baiduToken
- headers = {'content-type': 'application/x-www-form-urlencoded'}
- response = requests.post(request_url, data=params, headers=headers)
- if response:
- print(response.json())
- return response.json()
-
- # """ 你的 APPID AK SK(SDK) """
- # APP_ID = '你的APP_ID'
- # API_KEY = '你的API_KEY'
- # SECRET_KEY = '你的SECRET_KEY'
- #
- # client = AipOcr(APP_ID, API_KEY, SECRET_KEY)
- # """ 读取图片 """
- # def get_file_content(filePath):
- # with open(filePath, 'rb') as fp:
- # return fp.read()
- #
- # image = get_file_content(self.download_path[0])
- #
- # """ 如果有可选参数 """
- # options = {}
- # options["language_type"] = "CHN_ENG"
- # options["detect_direction"] = "true"
- # options["detect_language"] = "true"
- # options["probability"] = "false"
- #
- # """ 调用api"""
- # picture_result = client.basicAccurate(image, options) # 返回识别结果
- # words_result = picture_result['words_result']
- # print(words_result)
- # return words_result
5. 实现点击“选择名片”功能,用来扫描选择的名片,并把名片和获取到的名片信息显示到界面;
- # 选择名片按钮执行方法
- def openfile(self):
- # 启动选择文件对话空,查找jpg以及png图片
- self.download_path = QFileDialog.getOpenFileName(self, "选择要识别的图片", os.getcwd(), "Image Files(*.jpg *.png)")
- # 判断是否选择图片
- if not self.download_path[0].strip():
- QMessageBox.information(self, '提示信息', '没有选择名片图片')
- pass
- else:
- # pixmap解析图片
- pixmap = QPixmap(self.download_path[0])
- # 设置图片
- self.imgLable.setPixmap(pixmap)
- # 让图片自适应label大小
- self.imgLable.setScaledContents(True)
- try:
- # 识别名片图片返回识别结果
- content = self.recgImg()
- except:
- QMessageBox.information(self, '提示信息', '识别错误请重新选择图片')
-
- # 识别图片的数据赋值
- words_result = content['words_result']
- for key in words_result:
- textValue = words_result[key][0]
- if key == 'NAME':
- self.usLineEdit.setText(textValue)
- elif key == 'MOBILE':
- self.phoneLineEdit.setText(textValue)
- elif key == 'TEL':
- self.telLineEdit.setText(textValue)
- elif key == 'EMAIL':
- self.emailLineEdit.setText(textValue)
- elif key == 'URL':
- self.urlLineEdit.setText(textValue)
- elif key == 'COMPANY':
- self.companyLineEdit.setText(textValue)
- elif key == 'ADDR':
- self.addrLineEdit.setText(textValue)
6. 实现点击“查看名片”功能,用来全屏显示名片图片;
- # 点击查看名片显示大图功能
- def viewbtn(self):
- if self.download_path:
- # 使用电脑中的看图工具打开图片
- img = Image.open(self.download_path[0])
- # 显示图片
- img.show()
- else:
- QMessageBox.information(self, '提示信息', '先选择名片图片')
7. 添加公共函数clearCardData,用来在保存成功后清除图片和名片信息;
- # 清理名片数据
- def clearCardData(self):
- # 去掉历史图片路径
- self.download_path = ''
- # 移除控件上图片
- self.imgLable.setPixmap(QPixmap(""))
- # 移除输入框内容
- self.usLineEdit.setText("")
- self.phoneLineEdit.setText("")
- self.telLineEdit.setText("")
- self.emailLineEdit.setText("")
- self.urlLineEdit.setText("")
- self.companyLineEdit.setText("")
- self.addrLineEdit.setText("")
8. 实现点击“保存”功能,用来把获取的信息保存到Excel;
- # 保存名片信息到文档
- def saveData(self):
- pi_table = pd.read_excel(path, sheet_name='data')
- # 获取输出框内容
- name = self.usLineEdit.text()
- mobile = self.phoneLineEdit.text()
- tel = self.telLineEdit.text()
- email = self.emailLineEdit.text()
- url = self.urlLineEdit.text()
- comp = self.companyLineEdit.text()
- addr = self.addrLineEdit.text()
- # 判断手机号是否为空
- if mobile.strip():
- # 根据手机号判断区域
- try:
- info = phone.Phone().find(int(mobile))
- except Exception as e:
- QMessageBox.critical(self, "错误:", "手机号码不正确!", QMessageBox.Ok) # 弹出提示对话框
- self.phoneLineEdit.setFocus() # 让手机文本框获得焦点
- return
- # 判断手机号是否正确返回信息
- if info == None:
- city = '其他'
- else:
- # 正确返回信息获取省
- city = info['province']
- else:
- city = '其他'
- # 判断姓名是否为空
- if name.strip():
- # 添加数据
- data = pi_table.append({'name': name,
- 'mobile': mobile,
- 'tel': tel,
- 'email': email,
- 'url': url,
- 'comp': comp,
- 'addr': addr,
- 'city': city,
- }, ignore_index=True)
- # 更新xlsx文件
- pd.DataFrame(data).to_excel(path, sheet_name='data', index=False)
- # 保存成功
- QMessageBox.information(self, '提示信息', '保存成功')
-
- self.clearCardData()
- else:
- QMessageBox.information(self, '提示信息', '姓名不能为空')
- pass
9. 最终合并代码:
- from PyQt5.QtWidgets import *
- from PyQt5.QtGui import *
-
- # 引入自定义模块
- import bc
- # 引入内置模块
- import sys
- import os
- # 引入第三方模块
- import pandas as pd
- import requests, base64
- from PIL import Image
- import phone
- # 文字识别sdk所需要的模块
- from aip import AipOcr
-
- # 获取当前路径
- cdir = os.getcwd()
- # 文件路径
- path = cdir+'/名片信息表.xlsx'
- # 读取路径 判断是否创建了文件
- if not os.path.exists(path):
- # 根据路径建立文件夹
- # os.makedirs(path)
- # 姓名 手机 电话 邮箱 网址 公司 地址 城市
- cardfile = pd.DataFrame(columns=['name', 'mobile', 'tel', 'email', 'url', 'comp', 'addr', 'city'])
- # 生成xlsx文件
- cardfile.to_excel(path, sheet_name='data', index=None)
-
- class parentWindow(QWidget,bc.Ui_Form):
- # 初始化方法
- def __init__(self):
- # 找到父类 首页面
- super(parentWindow, self).__init__()
- # 初始化页面方法
- self.setupUi(self)
- # 点击选择名片
- self.selectCard.clicked.connect(self.openfile)
- # 点击查看名片
- self.viewButton.clicked.connect(self.viewbtn)
- # 点击保存按钮
- self.saveButton.clicked.connect(self.saveData)
-
- #选择名片按钮执行方法
- def openfile(self):
- # 启动选择文件对话空,查找jpg以及png图片
- self.download_path = QFileDialog.getOpenFileName(self, "选择要识别的图片", os.getcwd(), "Image Files(*.jpg *.png)")
- # 判断是否选择图片
- if not self.download_path[0].strip():
- QMessageBox.information(self, '提示信息', '没有选择名片图片')
- pass
- else:
- # pixmap解析图片
- pixmap = QPixmap(self.download_path[0])
- # 设置图片
- self.imgLable.setPixmap(pixmap)
- # 让图片自适应label大小
- self.imgLable.setScaledContents(True)
- try:
- # 识别名片图片返回识别结果
- content=self.recgImg()
- except:
- QMessageBox.information(self, '提示信息', '识别错误请重新选择图片')
-
- # 识别图片的数据赋值
- words_result = content['words_result']
- for key in words_result:
- textValue = words_result[key][0]
- if key == 'NAME':
- self.usLineEdit.setText(textValue)
- elif key == 'MOBILE':
- self.phoneLineEdit.setText(textValue)
- elif key == 'TEL':
- self.telLineEdit.setText(textValue)
- elif key == 'EMAIL':
- self.emailLineEdit.setText(textValue)
- elif key == 'URL':
- self.urlLineEdit.setText(textValue)
- elif key == 'COMPANY':
- self.companyLineEdit.setText(textValue)
- elif key == 'ADDR':
- self.addrLineEdit.setText(textValue)
-
- # 识别名片图片
- def recgImg(self):
- # 获取baiduToken
- apikey = '你的apikey'
- seckey = '你的seckey'
- tokenUrl = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id='+apikey+'&client_secret='+seckey
- res = requests.get(url=tokenUrl, headers={'content-type': 'application/json; charset=UTF-8'}).json()
- baiduToken = res['access_token']
-
- '''
- 名片识别(API)
- '''
- request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/business_card"
- # 二进制方式打开图片文件
- f = open(self.download_path[0], 'rb')
- img = base64.b64encode(f.read())
-
- params = {"image": img}
- # access_token = '[调用鉴权接口获取的token]'
- request_url = request_url + "?access_token=" + baiduToken
- headers = {'content-type': 'application/x-www-form-urlencoded'}
- response = requests.post(request_url, data=params, headers=headers)
- if response:
- print(response.json())
- return response.json()
-
- # """ 你的 APPID AK SK(SDK) """
- # APP_ID = '你的APP_ID'
- # API_KEY = '你的API_KEY'
- # SECRET_KEY = '你的SECRET_KEY'
- #
- # client = AipOcr(APP_ID, API_KEY, SECRET_KEY)
- # """ 读取图片 """
- # def get_file_content(filePath):
- # with open(filePath, 'rb') as fp:
- # return fp.read()
- #
- # image = get_file_content(self.download_path[0])
- #
- # """ 如果有可选参数 """
- # options = {}
- # options["language_type"] = "CHN_ENG"
- # options["detect_direction"] = "true"
- # options["detect_language"] = "true"
- # options["probability"] = "false"
- #
- # """ 调用api"""
- # picture_result = client.basicAccurate(image, options) # 返回识别结果
- # words_result = picture_result['words_result']
- # print(words_result)
- # return words_result
-
- # 点击查看名片显示大图功能
- def viewbtn(self):
- if self.download_path:
- # 使用电脑中的看图工具打开图片
- img = Image.open(self.download_path[0])
- # 显示图片
- img.show()
- else:
- QMessageBox.information(self, '提示信息', '先选择名片图片')
-
- # 保存名片信息到文档
- def saveData(self):
- pi_table = pd.read_excel(path, sheet_name='data')
- # 获取输出框内容
- name =self.usLineEdit.text()
- mobile = self.phoneLineEdit.text()
- tel = self.telLineEdit.text()
- email = self.emailLineEdit.text()
- url = self.urlLineEdit.text()
- comp = self.companyLineEdit.text()
- addr = self.addrLineEdit.text()
- # 判断手机号是否为空
- if mobile.strip():
- # 根据手机号判断区域
- try:
- info = phone.Phone().find(int(mobile))
- except Exception as e:
- QMessageBox.critical(self,"错误:","手机号码不正确!",QMessageBox.Ok) # 弹出提示对话框
- self.phoneLineEdit.setFocus() # 让手机文本框获得焦点
- return
- # 判断手机号是否正确返回信息
- if info==None:
- city = '其他'
- else:
- # 正确返回信息获取省
- city = info['province']
- else:
- city = '其他'
- # 判断姓名是否为空
- if name.strip():
- # 添加数据
- data = pi_table.append({'name': name,
- 'mobile': mobile,
- 'tel': tel,
- 'email': email,
- 'url': url,
- 'comp': comp,
- 'addr': addr,
- 'city': city,
- }, ignore_index=True)
- # 更新xlsx文件
- pd.DataFrame(data).to_excel(path, sheet_name='data', index=False)
- # 保存成功
- QMessageBox.information(self, '提示信息', '保存成功')
-
- self.clearCardData()
- else:
- QMessageBox.information(self, '提示信息', '姓名不能为空')
- pass
-
- # 清理名片数据
- def clearCardData(self):
- # 去掉历史图片路径
- self.download_path = ''
- # 移除控件上图片
- self.imgLable.setPixmap(QPixmap(""))
- # 移除输入框内容
- self.usLineEdit.setText("")
- self.phoneLineEdit.setText("")
- self.telLineEdit.setText("")
- self.emailLineEdit.setText("")
- self.urlLineEdit.setText("")
- self.companyLineEdit.setText("")
- self.addrLineEdit.setText("")
-
- if __name__=='__main__':
- # 每一个PyQt5应用都必须创建一个应用对象
- app=QApplication(sys.argv)
- # 初始化页面
- window=parentWindow()
- # 显示首页
- window.show()
- sys.exit(app.exec_())
本文利用python+百度文字识别,实现上传名片的扫描,并把图片和获取的信息显示到界面,可点击“查看名片”全屏浏览图片,也可点击“保存”,把信息保存到Excel。
扫描公众号,了解更多实例分享
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。