现TK界面中选择输入单张图片进行基于基于连通区域的字符分割方法分割单张图片多个数字以及图像预处理,处理过程显示并保存的界面设计,以完整的Python代码实现
时间: 2023-07-14 18:11:46 浏览: 103
下面是一个基于Tkinter的图像处理界面,可以进行图像预处理和字符分割,并将处理过程显示并保存。该程序使用基于连通区域的字符分割方法对单张图片中的多个数字进行分割,代码中使用了OpenCV库和PIL库。
```python
import tkinter as tk
from tkinter import filedialog
from tkinter import messagebox
from PIL import Image, ImageTk
import cv2
import numpy as np
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.pack()
self.create_widgets()
def create_widgets(self):
# 选择文件按钮
self.select_button = tk.Button(self)
self.select_button["text"] = "选择图片"
self.select_button["command"] = self.select_image
self.select_button.pack(side="top")
# 预处理按钮
self.preprocess_button = tk.Button(self)
self.preprocess_button["text"] = "图像预处理"
self.preprocess_button["state"] = "disabled"
self.preprocess_button["command"] = self.preprocess_image
self.preprocess_button.pack(side="top")
# 分割字符按钮
self.segment_button = tk.Button(self)
self.segment_button["text"] = "分割字符"
self.segment_button["state"] = "disabled"
self.segment_button["command"] = self.segment_characters
self.segment_button.pack(side="top")
# 保存结果按钮
self.save_button = tk.Button(self)
self.save_button["text"] = "保存结果"
self.save_button["state"] = "disabled"
self.save_button["command"] = self.save_result
self.save_button.pack(side="top")
# 图片显示区域
self.image_label = tk.Label(self)
self.image_label.pack(side="top")
def select_image(self):
# 打开文件选择对话框
self.filename = filedialog.askopenfilename(title="选择图片",
filetypes=(("JPEG files", "*.jpg"),
("PNG files", "*.png"),
("All files", "*.*")))
if self.filename:
self.load_image()
self.preprocess_button["state"] = "normal"
def load_image(self):
# 加载图片并显示
img = Image.open(self.filename)
self.img_orig = np.array(img)
img = ImageTk.PhotoImage(img)
self.image_label.config(image=img)
self.image_label.image = img
def preprocess_image(self):
# 图像预处理
img_gray = cv2.cvtColor(self.img_orig, cv2.COLOR_BGR2GRAY)
img_blur = cv2.GaussianBlur(img_gray, (5, 5), 0)
img_thresh = cv2.adaptiveThreshold(img_blur, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY_INV, 11, 2)
img_thresh = cv2.medianBlur(img_thresh, 3)
img_thresh = cv2.copyMakeBorder(img_thresh, 10, 10, 10, 10,
cv2.BORDER_CONSTANT, value=255)
self.img_processed = img_thresh
self.show_image(self.img_processed)
self.segment_button["state"] = "normal"
def segment_characters(self):
# 分割字符
img_contours, contours, hierarchy = cv2.findContours(
self.img_processed, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
img_out = np.zeros_like(self.img_processed)
digits = []
for i, cnt in enumerate(contours):
if hierarchy[0][i][3] == -1:
x, y, w, h = cv2.boundingRect(cnt)
if w > 5 and h > 5:
digit = self.img_processed[y:y+h, x:x+w]
digit = cv2.resize(digit, (28, 28))
digit = np.pad(digit, ((4, 4), (4, 4)), mode='constant',
constant_values=255)
digits.append(digit)
cv2.rectangle(img_out, (x, y), (x+w, y+h), 255, 1)
self.img_segmented = img_out
self.show_image(self.img_segmented)
self.digits = digits
self.save_button["state"] = "normal"
def save_result(self):
# 保存结果
for i, digit in enumerate(self.digits):
filename = self.filename[:-4] + '_{}.png'.format(i)
cv2.imwrite(filename, digit)
messagebox.showinfo("保存成功", "分割结果已保存!")
def show_image(self, img):
# 显示图片
img = Image.fromarray(img)
img = ImageTk.PhotoImage(img)
self.image_label.config(image=img)
self.image_label.image = img
root = tk.Tk()
app = Application(master=root)
app.mainloop()
```
在上述代码中,我们定义了一个Application类,并在其中创建了四个按钮和一个图片显示区域。其中,select_button用于选择图片,preprocess_button用于进行图像预处理,segment_button用于分割字符,save_button用于保存处理结果。当用户选择了一张图片后,我们将在图片显示区域中显示该图片,并启用preprocess_button按钮。当用户点击preprocess_button按钮后,我们将对原始图像进行预处理,并在图片显示区域中显示处理结果,并启用segment_button按钮。当用户点击segment_button按钮后,我们将使用基于连通区域的字符分割方法对处理后的图像进行分割,并在图片显示区域中显示分割结果,并启用save_button按钮。当用户点击save_button按钮后,我们将保存处理结果并弹出一个提示框。
在图像预处理中,我们首先将彩色图像转换为灰度图像,并进行高斯滤波和自适应阈值处理,然后进行中值滤波和边框填充。在字符分割中,我们使用cv2.findContours函数查找连通区域,并使用层次信息判断是否为顶层轮廓,然后使用cv2.boundingRect函数获取包围矩形,并进行筛选和调整大小,最后使用cv2.rectangle函数在输出图像中绘制包围矩形。
注意:上述代码中使用的字符识别模型不在本文范围内,请读者自行实现或引用已有模型。
阅读全文