- 应用场景:单独识别图片中某个区域的数字或者/数值,然后做数据处理。
首先是导入我们需要的库(如下),这里识别图片上数字或者数值的原理是,首先截图(截取屏幕),然后截取我们需要的图片上的数字/数值区域,方便第三方库识别图片区域内的数字/数值/文字,这样做准确率也会相对高一些。
import easyocr #识别图片上的数字/数值/文字方法
from PIL import Image #打开图片,传输图片信息
import re #正则表达式
# import pytesseract #识别图片上的数字/数值方法
- 下面是截取屏幕图片的代码,可以自行更改所需的图片截取范围:
'''1、窗口截图,截取整个屏幕'''
def window_capture(self,filename):
hwnd = 0 # 窗口的编号,0号表示当前活跃窗口
# 根据窗口句柄获取窗口的设备上下文DC(Divice Context)
hwndDC = win32gui.GetWindowDC(hwnd)
# 根据窗口的DC获取mfcDC
mfcDC = win32ui.CreateDCFromHandle(hwndDC)
# mfcDC创建可兼容的DC
saveDC = mfcDC.CreateCompatibleDC()
# 创建bigmap准备保存图片,及设置图片截图的大小
saveBitMap = win32ui.CreateBitmap()
datas = [1920,1080]
w = int(datas[0])
h = int(datas[1])
# 为bitmap开辟空间
saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)
# 高度saveDC,将截图保存到saveBitmap中
saveDC.SelectObject(saveBitMap)
# 截取从左上角(0,0)长宽为(w,h)的图片
saveDC.BitBlt((0, 0), (w, h), mfcDC, (0, 0), win32con.SRCCOPY)
saveBitMap.SaveBitmapFile(saveDC, filename)
return True
- 下面代码块是对上面屏幕图片做分割提取处理,截取我们需要数据的图片:(方法是通过画图工具,打开屏幕图片,记录对应区域图片的起始点坐标,以及区域的长,宽)
def jietu(self):
'''2、截取图片中的一部分'''
# 打开一张图
img = Image.open("./save_img/jietu.jpg")
# 图片尺寸
img_size = img.size
h = img_size[1] # 图片高度
print(h)
w = img_size[0] # 图片宽度
print(w)
#设置左上角的为起始点,起始点坐标,然后设置长,宽,(通过屏幕图片得知该信息。)
data_1 = =[536,1012,70,20]
x = int(data_1[0])
y = int(data_1[1])
w = int(data_1[2])
h = int(data_1[3])
# 开始截取
region = img.crop((x, y, x + w, y + h))
# 保存图片
region.save("./save_img/jiequ.png") #保存图片路径自行设置。
return True
- 识别上面保存的图片上的数值/数字/文字。(方法分为pytesseract和easyocr识别,其中pytesseract在程序打包后可能无法使用(指在未连接网络的电脑上,无法下载模型,easyocr在打包程序中可用,需注意模型文件的移植))
def shibie_data(self):
'''3、识别图片中的数字'''
# text = pytesseract.image_to_string(Image.open("./save_img/test11.png",lang="eng"))
#第一中方法
# pytesseract.pytesseract.tesseract_cmd = "./Tesseract/tesseract.exe"
# text = pytesseract.image_to_string(Image.open("./save_img/jiequ.png"))
#第二种方法
text = easyocr.Reader(['ch_sim', 'en'])
shuju = text.readtext('./save_img/jiequ.png', detail=0)
print(shuju)
print("返回坐标信息:",shuju)
print("返回坐标信息:",text)
return shuju
完整代码如下(注意更改对应自己需要存放图片或者保存图片的路径):
class Shibie(QMainWindow):
msgs = pyqtSignal(list)
def __init__(self):
super().__init__()
'''1、窗口截图'''
def window_capture(self,filename):
hwnd = 0 # 窗口的编号,0号表示当前活跃窗口
# 根据窗口句柄获取窗口的设备上下文DC(Divice Context)
hwndDC = win32gui.GetWindowDC(hwnd)
# 根据窗口的DC获取mfcDC
mfcDC = win32ui.CreateDCFromHandle(hwndDC)
# mfcDC创建可兼容的DC
saveDC = mfcDC.CreateCompatibleDC()
# 创建bigmap准备保存图片
saveBitMap = win32ui.CreateBitmap()
datas = [1920,1080]
w = int(datas[0])
h = int(datas[1])
# 为bitmap开辟空间
saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)
# 高度saveDC,将截图保存到saveBitmap中
saveDC.SelectObject(saveBitMap)
# 截取从左上角(0,0)长宽为(w,h)的图片
saveDC.BitBlt((0, 0), (w, h), mfcDC, (0, 0), win32con.SRCCOPY)
saveBitMap.SaveBitmapFile(saveDC, filename)
return True
def jietu(self):
'''2、截取图片中的一部分'''
# 打开一张图
img = Image.open("./save_img/jietu.jpg")
# 图片尺寸
img_size = img.size
h = img_size[1] # 图片高度
print(h)
w = img_size[0] # 图片宽度
print(w)
#设置左上角的为起始点,起始点坐标,然后设置长,宽
data_1 = =[536,1012,70,20]
x = int(data_1[0])
y = int(data_1[1])
w = int(data_1[2])
h = int(data_1[3])
# 开始截取
region = img.crop((x, y, x + w, y + h))
# 保存图片
region.save("./save_img/jiequ.png")
return True
def shibie_data(self):
'''3、识别图片中的数字'''
# text = pytesseract.image_to_string(Image.open("./save_img/test11.png",lang="eng"))
#第一中方法
# pytesseract.pytesseract.tesseract_cmd = "./Tesseract/tesseract.exe"
# text = pytesseract.image_to_string(Image.open("./save_img/jiequ.png"))
#第二种方法
text = easyocr.Reader(['ch_sim', 'en'])
shuju = text.readtext('./save_img/jiequ.png', detail=0)
print(shuju)
print("返回坐标信息:",shuju)
print("返回坐标信息:",text)
return shuju
def start(self):
ret = self.window_capture("./save_img/jietu.jpg")
# delate_zifuchuan = ["[","]","'","(",")","Vall","Valt"," ","=","Valu"]
if ret == True:
ret_s = self.jietu()
if ret_s == True:
# data = str(self.shibie_data()) #第一中方法
#返回列表
data = str(self.shibie_data())
print("识别的坐标:%s" % data)
print(type(data))
if "(" in data or "]" in data:
if data == "[]":
self.msgs.emit(["读取坐标值错误","未读取到坐标值!"])
return
else:
#第一种方法
# text = re.compile(r'[(](.*?)[)]', re.S)
# texts = re.findall(text,data)
# texts = "".join(texts)
#优化识别方法,正则表达式,自行更改。
texts = re.findall(r"\d+\,\d*",data)
print(texts)
if texts == []:
self.msgs.emit(["读取坐标值错误","未读取到坐标值!"])
return
else:
self.msgs.emit(["%s"%texts[0]])
else:
self.msgs.emit(["读取坐标值错误","未读取到坐标值!"])
else:
print("读取数据错误")
asd = Shibie()
asd.start()