1 Star 0 Fork 256

忍战小李/doc_scanner_homework

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
app.py 4.49 KB
一键复制 编辑 原始数据 按行查看 历史
gbu23 提交于 2025-05-30 10:50 +08:00 . Initial commit
'''
- "app.py" 文件是一个文档扫描仪应用程序的主要入口点。
- 它提供了一个可视化的用户界面,用于加载图片、调整文档角落位置、裁剪文档并显示结果。
- 它的作用是提供一个简单易用的界面,使用户能够方便地进行文档扫描操作。
'''
import tkinter as tk
from tkinter import filedialog
from PIL import Image, ImageTk
import cv2 as cv
from doc_scanner import DocScanner
import numpy as np
class DocScannerApp:
def __init__(self):
self.doc_scanner = DocScanner()
self.corners = None
self.dragging_idx = -1
self.img = None
self.root = tk.Tk()
self.canvas = tk.Canvas(self.root, width=600, height=400)
self.canvas.pack()
self.canvas.bind("<Button-1>", self.mouse_callback)
self.canvas.bind("<ButtonRelease-1>", self.mouse_callback)
self.canvas.bind("<B1-Motion>", self.mouse_callback)
btn_select = tk.Button(self.root, text="Select Image", command=self.select_image)
btn_select.pack(side=tk.LEFT)
self.show_mouse_move = tk.BooleanVar()
chk_show_mouse_move = tk.Checkbutton(self.root, text="Show Mouse Move", variable=self.show_mouse_move)
chk_show_mouse_move.pack(side=tk.LEFT)
btn_crop = tk.Button(self.root, text="Crop", command=self.crop)
btn_crop.pack(side=tk.RIGHT)
def select_image(self):
"""选择图片并加载图片和角落。"""
file_path = filedialog.askopenfilename()
self.img, self.corners = self.doc_scanner.load_image(file_path)
img_height, img_width, _ = self.img.shape
if img_height > 600 or img_width > 800:
scale = min(600/img_height, 800/img_width)
self.img = cv.resize(self.img, (int(img_width*scale), int(img_height*scale)))
self.corners = self.corners * scale
img_height, img_width, _ = self.img.shape
self.canvas.config(width=img_width, height=img_height)
self.canvas.pack()
self.root.geometry(f"{img_width+50}x{img_height+50}")
self.redraw()
def mouse_callback(self, event):
"""鼠标回调函数,处理鼠标按下、释放和移动事件。"""
x, y = event.x, event.y
if event.type == tk.EventType.ButtonPress:
print(f"鼠标在({x},{y})按下")
for idx, corner in enumerate(self.corners):
if np.linalg.norm(np.array([x, y]) - corner) < 10:
self.dragging_idx = idx
print(f"要开始拖动角落: corners[{idx}]={corner} , 所以变量: dragging_idx 别设置为 {idx}")
break
elif event.type == tk.EventType.ButtonRelease:
print(f"鼠标在({x},{y})释放")
self.dragging_idx = -1
elif event.type == tk.EventType.Motion:
if self.show_mouse_move.get():
print(f"鼠标在({x},{y})移动")
if self.dragging_idx != -1:
self.corners[self.dragging_idx] = np.array([x, y])
self.redraw()
def redraw(self):
"""重新绘制图片和角落。"""
img_copy = self.img.copy()
for idx, corner in enumerate(self.corners):
cv.circle(img_copy, tuple(corner.astype(int)), 5, (0, 255, 0), -1)
cv.polylines(img_copy, [self.corners.astype(int)], True, (0, 255, 0), 2)
img_tk = self.cv2image_to_tkinter_image(img_copy)
self.canvas.create_image(0, 0, anchor=tk.NW, image=img_tk)
self.canvas.image = img_tk
def cv2image_to_tkinter_image(self, cv2_image):
"""将 OpenCV 图片转换为 Tkinter 图片。"""
cv2_image_rgb = cv.cvtColor(cv2_image, cv.COLOR_BGR2RGB)
pil_image = Image.fromarray(cv2_image_rgb)
return ImageTk.PhotoImage(pil_image)
def crop(self):
"""裁剪图片。"""
cropped_img = self.doc_scanner.crop_image(self.img, self.corners)
cropped_img_tk = self.cv2image_to_tkinter_image(cropped_img)
cropped_image_window = tk.Toplevel(self.root)
cropped_image_window.title("Cropped Image")
img_label = tk.Label(cropped_image_window, image=cropped_img_tk)
img_label.pack()
btn_close = tk.Button(cropped_image_window, text="Close", command=cropped_image_window.destroy)
btn_close.pack()
img_label.image = cropped_img_tk
def run(self):
"""运行应用程序。"""
self.root.mainloop()
if __name__ == "__main__":
app = DocScannerApp()
app.run()
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/ren-zhan-xiao-li/doc_scanner_homework.git
git@gitee.com:ren-zhan-xiao-li/doc_scanner_homework.git
ren-zhan-xiao-li
doc_scanner_homework
doc_scanner_homework
master

搜索帮助