我正在尝试使用卷积神经网络构建一个手写数字识别系统。到目前为止,我已经开发了一个Tkinter窗口,其中包含一个画布,您可以在其上手写数字。在点击``识别''按钮后,我希望程序拍摄该数字的图像(即画布)并通过神经网络运行它以预测数字。以下是我在网上找到的一些代码的实现:
from tkinter import *
import win32gui
from PIL import ImageGrab, Image
cv = Canvas(width=400, height=400, bg='white', cursor='cross')
cv.grid(row=0, column=0, sticky=W)
hwnd = cv.winfo_id()
cv_rect = win32gui.GetWindoRect(hwnd)
img = ImageGrab.grab(cv_rect)
此代码能够捕获图像。但是,图像不是画布上的,而是屏幕上的其他位置,通常在画布的西北部。输出看起来像这样:
但是,如果我将Tkinter窗口移离计算机屏幕的左上角,则该图像甚至无法捕获Tkinter窗口的左上角,如上图所示。
为了进一步了解,这是我在其中构建该gui的文件的全部代码。
import numpy as np
from tkinter import *
from PIL import Image, ImageGrab
import win32gui
import tensorflow as tf
import matplotlib.pyplot as plt
import matplotlib
import win32api
cnn = tf.keras.models.load_model('\\Users\\hamza\\Documents\\VS Code\\mnist.h5py')
#---------------------------------------------------------------
'''
(X_train, y_train), (X_test, y_test) = tf.keras.datasets.mnist.load_data()
X_test = X_test.reshape(-1, 28, 28, 1)
X_test = X_test.astype('float32')
X_test /= 255
y_test = tf.keras.utils.to_categorical(y_test)
y_pred = cnn.predict(X_test)
print(y_pred[3700])
print(y_test[3700])
test_eval = cnn.evaluate(X_test, y_test, verbose=1)
print('Test loss:', test_eval[0])
print('Test accuracy:', test_eval[1])
'''
from pyscreenshot import grab
import pygetwindow as pgw
'''
im = grab(bbox=(500, 200, 800, 400))
im.show()
'''
def predict(img):
#img = img.resize((28, 28))
img = img.convert('L')
img = np.array(img)
#img.reshape(28, 28)
plt.imshow(img, cmap=matplotlib.cm.binary, interpolation='nearest')
plt.show()
#img = img.reshape(1, 28, 28, 1)/255
#pred = cnn.predict(img)[0]
#print(pred)
#print('---------------------')
#return np.argmax(pred), max(pred)
def classify():
'''
hwnd = cv.winfo_id()
print(hwnd)
cv_rect = win32gui.GetWindowRect(hwnd)
img = ImageGrab.grab(cv_rect)
'''
win = pgw.getWindowsWithTitle('tk')[0]
winleft = win.left+9
wintop = win.top+7
winright = win.right-9
winbottom = win.bottom-9
final_rect = (winleft,wintop,winright,winbottom)
img = ImageGrab.grab(final_rect)
digit, accuracy = predict(img)
print(digit)
print(accuracy)
#label.configure(str(digit) + ', ' + str(int(accuracy*100)) + '%')
def clear():
cv.delete('all')
def draw(event):
x = event.x
y = event.y
r = 8
cv.create_oval(x-r, y-r, x+r, y+r, fill='black')
root = Tk()
cv = Canvas(width=400, height=400, bg='white', cursor='cross')
cv.grid(row=0, column=0, pady=2, sticky=W)
label = Label(text='Welcome', font=('Helvetica', 32))
label.grid(row=0, column=1, padx=2, pady=2)
clear_button = Button(text='Clear', command=clear)
clear_button.grid(row=1, column=0, pady=2)
recognize_button = Button(text='Recognize', command=classify)
recognize_button.grid(row=1, column=1, padx=2, pady=2)
cv.bind("<B1-Motion>", draw)
mainloop()
有人,请帮忙。
答案 0 :(得分:1)
我在GUI中使用了类似的功能,起初我使用win32gui
,但意识到这样做太小了,相反,只需使用PyGetWindow
和PIL
。
首先安装模块,然后在终端中说出来。
pip install PyGetWindow
pip install Pillow
然后,此代码将在3秒后自动获取屏幕截图
from tkinter import *
from win32gui import FindWindow, GetWindowRect
import pygetwindow as gw
from PIL import ImageGrab
def ss():
win = gw.getWindowsWithTitle('Trial')[0]
winleft = win.left+9
wintop = win.top+38 #change 38 to 7 to not capture the titlebar
winright = win.right-9
winbottom = win.bottom-9
final_rect = (winleft,wintop,winright,winbottom)
img = ImageGrab.grab(final_rect)
img.save('Required Image.png')
#making the tkinter window
root = Tk()
root.title('Trial')
cv = Canvas(width=400, height=400, bg='white', cursor='cross')
cv.grid(row=0, column=0, sticky=W)
root.after(3000,ss)
root.mainloop()
在这里win = gw.getWindowsWithTitle('Title of the window')[0]
,您必须调用窗口名称,就像您设置的窗口名称一样,例如root.title('Hello World')
,然后'Title of the window'
将被{{1 }}。或默认情况下,它的标题为'Hello World'
。
或者,如果您仍然不愿意使用'tk'
,请替换为win32gui
,
ss()
额外提示:
这是我得到的图像:
希望这对您有所帮助,请让我知道是否有任何错误或疑问。
其他参考-ImageGrab not grabbing precise bbox image
欢呼