代码拉取完成,页面将自动刷新
from tkinter import *
import cv2
from PIL import Image, ImageTk
from math import cos, sin, pi
class Application(Frame) :
def __init__(self , master = None) :
Frame.__init__(self , master = None)
self.pack()
self.createWidgets()
##############################################
# 上传图片接口 具体过程为 : 读取图片路径 -> 获得图片 -> 展示图片
def uploadPicture(self) :
self.imagePath = self.entry.get()
# 异常处理 , 用户输入路径不正确则要提示用户,直到用户输入正确为止,不要让人觉得云里雾里
try :
self.image = Image.open(self.imagePath)
input_width = self.canvasChild.winfo_width()
input_height = self.canvasChild.winfo_width()
self.image = self.image.resize((input_width , input_height) , Image.ANTIALIAS)
photo = ImageTk.PhotoImage(self.image)
self.canvasChild.create_image(0, 0, anchor=NW, image=photo)
self.canvasChild.image = photo
except FileNotFoundError :
self.uploadLable = Label(self , text = "上传路径不正确,请检查:)~")
self.uploadLable.config(foreground="red")
self.canvas.create_window(300 , 80 , window=self.uploadLable)
self.after(1000 , lambda: self.uploadLable.destroy())
return
# 下载图像接口
def downloadPicture(self) :
# 异常处理 用户没有上传图片则要下载,此时要提醒用户上传图片
try:
self.image.save("result.jpg")
self.downloadLable = Label(self , text = "恭喜您下载图片成功,图片存放在同级目录下~")
self.downloadLable.config(foreground="green")
self.canvas.create_window(1250 , 80 , window=self.downloadLable)
except AttributeError :
self.downloadLable = Label(self , text = "您还没有上传图片QAQ~")
self.downloadLable.config(foreground="red")
self.canvas.create_window(1200 , 80 , window=self.downloadLable)
# 1秒后销毁提示信息
# lambda表达式是定义了一个简单的函数,这种函数我们只需要使用一次,单独定义会让整个项目难管理,所以采用匿名函数形式
self.after(1000 , lambda: self.downloadLable.destroy())
##############################################
# 创建第一级按钮的位置(回退后调用)
def btn_1_create(self) :
self.btn1 = Button(self , text = "几何变换" , width=10 , height=2 , command=self.btn1_click)
self.canvas.create_window(850 , 140 , window=self.btn1)
self.btn2 = Button(self , text = "像素变换" , width=10 , height=2 , command=self.btn2_click)
self.canvas.create_window(850 , 220 , window=self.btn2)
self.btn3 = Button(self , text = "图像去噪" , width=10 , height=2 , command=self.btn3_click)
self.canvas.create_window(850 , 300 , window=self.btn3)
self.btn4 = Button(self , text = "图像锐化" , width=10 , height=2 , command=self.btn4_click)
self.canvas.create_window(850 , 380 , window=self.btn4)
self.btn5 = Button(self , text = "边缘检测" , width=10 , height=2 , command=self.btn5_click)
self.canvas.create_window(850 , 460 , window=self.btn5)
self.btn6 = Button(self , text = "图像分割" , width=10 , height=2 , command=self.btn6_click)
self.canvas.create_window(850 , 540 , window=self.btn6)
self.btn7 = Button(self , text = "图像分类" , width=10 , height=2 , command=self.btn7_click)
self.canvas.create_window(850 , 620 , window=self.btn7)
# 删除第一级原位置的按钮(进入子目录时调用)
def btn_1_delete(self) :
self.btn1.destroy()
self.btn2.destroy()
self.btn3.destroy()
self.btn4.destroy()
self.btn5.destroy()
self.btn6.destroy()
self.btn7.destroy()
############################################################################################
# 第一任务方法回退到上一级目录(销毁按钮)
def btn1_back(self) :
self.btn_back.destroy()
self.btn1_1.destroy()
self.btn1_2.destroy()
self.btn1_3.destroy()
self.btn1_4.destroy()
self.btn1_5.destroy()
self.btn1_6.destroy()
self.btn_1_create()
# 第一任务方法 -- 几何变换
def btn1_click(self) :
self.btn_1_delete()
self.btn_back = Button(self , text="<- 回退到上一级" , width=20 , height=2 , command=self.btn1_back)
self.canvas.create_window(850 , 40 , window=self.btn_back)
self.btn1_1 = Button(self , text = "缩放" , width=10 , height=2 , command=self.btn1_1_click)
self.canvas.create_window(850 , 160 , window=self.btn1_1)
self.btn1_2 = Button(self , text = "平移" , width=10 , height=2 , command=self.btn1_2_click)
self.canvas.create_window(850 , 240 , window=self.btn1_2)
self.btn1_3 = Button(self , text = "旋转" , width=10 , height=2 , command=self.btn1_3_click)
self.canvas.create_window(850 , 320 , window=self.btn1_3)
self.btn1_4 = Button(self , text = "翻转" , width=10 , height=2 , command=self.btn1_4_click)
self.canvas.create_window(850 , 400 , window=self.btn1_4)
self.btn1_5 = Button(self , text = "剪切" , width=10 , height=2 , command=self.btn1_5_click)
self.canvas.create_window(850 , 480 , window=self.btn1_5)
self.btn1_6 = Button(self , text = "自由旋转" , width=10 , height=2)
self.canvas.create_window(850 , 560 , window=self.btn1_6)
print(1)
#第一任务几何变换的缩放(默认缩放比例为0.8)
def btn1_1_click(self):
#默认缩放比例为0.8
scale_ratio = 0.8
# 获取图像的原始宽度和高度
width, height = self.image.size
# 计算缩放后的图像宽度和高度
new_width = (int)(width * scale_ratio)
new_height = (int)(height * scale_ratio)
# 创建新的空白图像,模式与原图像一致
new_image = Image.new(self.image.mode, (width, height))
# 遍历新图像的每个像素点
for new_y in range(new_height):
for new_x in range(new_width):
# 根据缩放比例计算对应原图像中的坐标
old_x = int(new_x / scale_ratio)
old_y = int(new_y / scale_ratio)
# 获取原图像中对应坐标的像素值
pixel = self.image.getpixel((old_x, old_y))
# 将像素值设置到新图像对应的坐标位置
new_image.putpixel((new_x, new_y), pixel)
self.image = new_image
#把变换后的图像显示到窗口
photo = ImageTk.PhotoImage(self.image)
self.canvasChild.create_image(0, 0, anchor=NW, image=photo)
self.canvasChild.image = photo
#第一任务几何变换的平移(默认向右100,向下50)
def btn1_2_click(self):
offset_x = 100
offset_y = 50
# 获取图像的宽度和高度
width, height = self.image.size
# 创建新的空白图像,尺寸与原图像相同,模式也相同
new_image = Image.new(self.image.mode, (width, height))
# 遍历原图像的每个像素点
for y in range(height):
for x in range(width):
# 计算平移后在新图像中的坐标位置
new_x = x + offset_x
new_y = y + offset_y
# 判断新坐标是否在新图像范围内,如果不在则不设置像素即默认黑色
if 0 <= new_x < width and 0 <= new_y < height:
# 获取原图像中当前像素点的像素值
pixel = self.image.getpixel((x, y))
# 将像素值设置到新图像对应的坐标位置
new_image.putpixel((new_x, new_y), pixel)
self.image = new_image
# 把变换后的图像显示到窗口
photo = ImageTk.PhotoImage(self.image)
self.canvasChild.create_image(0, 0, anchor=NW, image=photo)
self.canvasChild.image = photo
#第一任务几何变换的旋转(默认九十度)
def btn1_3_click(self):
#默认旋转角度为90度
angle = 90
# 获取图像的宽度和高度
width, height = self.image.size
# 计算图像中心点坐标
center_x, center_y = width / 2, height / 2
# 将角度转换为弧度
radian_angle = angle * pi / 180
# 计算旋转后的图像的尺寸(取整数),以确保能容纳旋转后的整个图像
new_width = int(abs(width * cos(radian_angle)) + abs(height * sin(radian_angle)))
new_height = int(abs(width * sin(radian_angle)) + abs(height * cos(radian_angle)))
# 创建新的空白图像,尺寸为计算出的新尺寸,模式与原图像相同
new_image = Image.new(self.image.mode, (new_width, new_height))
# 遍历新图像的每个像素点
for y in range(new_height):
for x in range(new_width):
# 将新图像坐标转换到以原图像中心点为原点的坐标系下
dx = x - new_width / 2
dy = y - new_height / 2
# 根据旋转公式进行坐标变换,绕中心点旋转
rotated_dx = dx * cos(radian_angle) - dy * sin(radian_angle)
rotated_dy = dx * sin(radian_angle) + dy * cos(radian_angle)
# 再将坐标转换回原图像的坐标系
old_x = int(rotated_dx + center_x)
old_y = int(rotated_dy + center_y)
# 判断坐标是否在原图像范围内
if 0 <= old_x < width and 0 <= old_y < height:
# 获取原图像中对应坐标的像素值
pixel = self.image.getpixel((old_x, old_y))
# 将像素值设置到新图像对应的坐标位置
new_image.putpixel((x, y), pixel)
self.image = new_image
# 把变换后的图像显示到窗口
photo = ImageTk.PhotoImage(self.image)
self.canvasChild.create_image(0, 0, anchor=NW, image=photo)
self.canvasChild.image = photo
#第一任务几何变换的翻转
def btn1_4_click(self):
width, height = self.image.size
# 创建新的空白图像,尺寸与原图像相同,模式也相同
new_image = Image.new(self.image.mode, (width, height))
# 遍历原图像的每个像素点
for y in range(height):
for x in range(width):
# 计算水平翻转后在新图像中的对应坐标
new_x = width - 1 - x
new_y = y
# 获取原图像中当前像素点的像素值
pixel = self.image.getpixel((x, y))
# 将像素值设置到新图像对应的坐标位置
new_image.putpixel((new_x, new_y), pixel)
self.image = new_image
# 把变换后的图像显示到窗口
photo = ImageTk.PhotoImage(self.image)
self.canvasChild.create_image(0, 0, anchor=NW, image=photo)
self.canvasChild.image = photo
#第一任务几何变换的剪切
#默认剪切的图片左边界的横坐标为100,上边界的纵坐标为100,右边界的横坐标为500,下边界的纵坐标为500
def btn1_5_click(self):
left = 100
right = 500
top = 100
bottom = 500
# 获取图像的宽度和高度
width, height = self.image.size
# 检查剪切区域参数是否合法,确保在图像范围内
if left < 0 or top < 0 or right > width or bottom > height or left >= right or top >= bottom:
#手动引发异常
raise ValueError("剪切区域参数不合法")
# 计算剪切后图像的宽度和高度
cut_width = right - left
cut_height = bottom - top
# 创建新的空白图像,尺寸为剪切区域大小,模式与原图像相同
new_image = Image.new(self.image.mode, (cut_width, cut_height))
# 遍历剪切区域内的每个像素点
for y in range(cut_height):
for x in range(cut_width):
# 计算在原图像中的对应坐标
old_x = x + left
old_y = y + top
# 获取原图像中对应坐标的像素值
pixel = self.image.getpixel((old_x, old_y))
#将像素值设置到新图像对应的坐标位置
new_image.putpixel((x, y), pixel)
self.image = new_image
# 把变换后的图像显示到窗口
photo = ImageTk.PhotoImage(self.image)
self.canvasChild.create_image(0, 0, anchor=NW, image=photo)
self.canvasChild.image = photo
############################################################################################
# 第二任务方法回退到上一级目录(销毁按钮)
def btn2_back(self) :
self.btn_back.destroy()
self.btn2_1.destroy()
self.btn2_2.destroy()
self.btn2_3.destroy()
self.btn2_4.destroy()
self.btn_1_create()
######################################################################################################################################
# 第三级目录回到上一级
def btn2_back_back(self) :
self.btn3_1.destroy()
self.btn3_2.destroy()
self.btn3_3.destroy()
self.btn3_4.destroy()
self.btn3_5.destroy()
self.btn3_6.destroy()
self.btn_back.destroy()
self.btn_back = Button(self , text="<- 回退到上一级" , width=20 , height=2 , command=self.btn2_back)
self.canvas.create_window(850 , 40 , window=self.btn_back)
self.btn2_1 = Button(self , text="图像间运算" , width=10 , height=2 , command=self.btn2_1_click)
self.canvas.create_window(850 , 200 , window=self.btn2_1)
self.btn2_2 = Button(self , text = "灰度变换" , width=10 , height=2)
self.canvas.create_window(850 , 300 , window=self.btn2_2)
self.btn2_3 = Button(self , text = "直方图计算" , width=10 , height=2)
self.canvas.create_window(850 , 400 , window=self.btn2_3)
self.btn2_4 = Button(self , text = "直方图均衡" , width=10 , height=2)
self.canvas.create_window(850 , 500 , window=self.btn2_4)
self.canvasChild.destroy()
self.canvasChild_copy.destroy()
self.btnUpload_copy.destroy()
self.entry_copy.destroy()
self.canvasChild = Canvas(self , width = 600 , height=600 , bg="gray")
self.canvas.create_window(400 , 400 , window=self.canvasChild)
# 第二个输入框的上传逻辑
def uploadPicture_copy(self) :
self.imagePath_copy = self.entry_copy.get()
# 异常处理 , 用户输入路径不正确则要提示用户,直到用户输入正确为止,不要让人觉得云里雾里
try :
self.image_copy = Image.open(self.imagePath_copy)
input_width = self.canvasChild.winfo_width()
input_height = self.canvasChild.winfo_width()
self.image_copy = self.image_copy.resize((input_width , input_height) , Image.ANTIALIAS)
photo = ImageTk.PhotoImage(self.image_copy)
self.canvasChild_copy.create_image(0, 0, anchor=NW, image=photo)
self.canvasChild_copy.image = photo
except FileNotFoundError :
self.uploadLable_copy = Label(self , text = "上传路径不正确,请检查:)~")
self.uploadLable_copy.config(foreground="red")
self.canvas.create_window(300 , 440 , window=self.uploadLable_copy)
self.after(1000 , lambda: self.uploadLable_copy.destroy())
return
def btn2_1_click(self) :
self.btn_back.destroy()
self.btn2_1.destroy()
self.btn2_2.destroy()
self.btn2_3.destroy()
self.btn2_4.destroy()
self.btn_back = Button(self , text="<- 回退到上一级" , width=20 , height=2 , command=self.btn2_back_back)
self.canvas.create_window(850 , 40 , window=self.btn_back)
# 创建第三级目录
self.btn3_1 = Button(self , text = "图像加" , width=10 , height=2)
self.canvas.create_window(850 , 180 , window=self.btn3_1)
self.btn3_2 = Button(self , text = "图像减" , width=10 , height=2)
self.canvas.create_window(850 , 260 , window=self.btn3_2)
self.btn3_3 = Button(self , text = "图像与" , width=10 , height=2)
self.canvas.create_window(850 , 340 , window=self.btn3_3)
self.btn3_4 = Button(self , text = "图像或" , width=10 , height=2)
self.canvas.create_window(850 , 420 , window=self.btn3_4)
self.btn3_5 = Button(self , text = "图像补" , width=10 , height=2)
self.canvas.create_window(850 , 500 , window=self.btn3_5)
self.btn3_6 = Button(self , text = "图像异或" , width=10 , height=2)
self.canvas.create_window(850 , 580 , window=self.btn3_6)
# 移动第一个展示框的位置 (销毁后创造,因为移动会提高耦合性)
self.canvasChild.destroy()
self.canvasChild = Canvas(self , width = 300 , height=300 , bg="gray")
self.canvas.create_window(400 , 250 , window=self.canvasChild)
# 创建第二个展示框 (同时要创建上传按钮和上传输入框)
self.canvasChild_copy = Canvas(self , width = 300 , height=300 , bg="gray")
self.canvas.create_window(400 , 600 , window=self.canvasChild_copy)
self.btnUpload_copy = Button(self , text = "上传图片" , width=10 , height=2 , command=self.uploadPicture_copy)
self.canvas.create_window(150 , 420 , window=self.btnUpload_copy)
self.entry_copy = Entry(self , fg="gray")
self.entry_copy.insert(0 , "请输入图片的完整路径~")
self.canvas.create_window(300 , 420 , window=self.entry_copy)
######################################################################################################################################
# 第二任务方法 -- 像素变换
def btn2_click(self) :
self.btn_1_delete()
self.btn_back = Button(self , text="<- 回退到上一级" , width=20 , height=2 , command=self.btn2_back)
self.canvas.create_window(850 , 40 , window=self.btn_back)
self.btn2_1 = Button(self , text="图像间运算" , width=10 , height=2 , command=self.btn2_1_click)
self.canvas.create_window(850 , 200 , window=self.btn2_1)
self.btn2_2 = Button(self , text = "灰度变换" , width=10 , height=2)
self.canvas.create_window(850 , 300 , window=self.btn2_2)
self.btn2_3 = Button(self , text = "直方图计算" , width=10 , height=2)
self.canvas.create_window(850 , 400 , window=self.btn2_3)
self.btn2_4 = Button(self , text = "直方图均衡" , width=10 , height=2)
self.canvas.create_window(850 , 500 , window=self.btn2_4)
############################################################################################
# 第三任务方法回退到上一级目录(销毁按钮)
def btn3_back(self) :
self.btn_back.destroy()
self.btn3_1.destroy()
self.btn3_2.destroy()
self.btn3_3.destroy()
self.btn3_4.destroy()
self.btn_1_create()
# 第三任务方法 -- 图像去噪
def btn3_click(self) :
self.btn_1_delete()
self.btn_back = Button(self , text="<- 回退到上一级" , width=20 , height=2 , command=self.btn3_back)
self.canvas.create_window(850 , 40 , window=self.btn_back)
self.btn3_1 = Button(self , text = "中值滤波" , width=10 , height=2)
self.canvas.create_window(850 , 100 , window=self.btn3_1)
self.btn3_2 = Button(self , text = "均值滤波" , width=10 , height=2)
self.canvas.create_window(850 , 200 , window=self.btn3_2)
self.btn3_3 = Button(self , text = "组合空域滤波" , width=10 , height=2)
self.canvas.create_window(850 , 300 , window=self.btn3_3)
self.btn3_4 = Button(self , text = "频率滤波" , width=10 , height=2)
self.canvas.create_window(850 , 400 , window=self.btn3_4)
return
############################################################################################
# 第四任务方法回退到上一级目录(销毁按钮)
def btn4_back(self) :
self.btn_back.destroy()
self.btn4_1.destroy()
self.btn4_2.destroy()
self.btn_1_create()
# 第四任务方法 -- 图像锐化
def btn4_click(self) :
self.btn_1_delete()
self.btn_back = Button(self , text="<- 回退到上一级" , width=20 , height=2 , command=self.btn4_back)
self.canvas.create_window(850 , 40 , window=self.btn_back)
self.btn4_1 = Button(self , text = "线性锐化滤波" , width=20 , height=4)
self.canvas.create_window(850 , 150 , window=self.btn4_1)
self.btn4_2 = Button(self , text = "非线性锐化滤波" , width=20 , height=4)
self.canvas.create_window(850 , 300 , window=self.btn4_2)
return
############################################################################################
# 第五任务方法回退到上一级目录(销毁按钮)
def btn5_back(self) :
self.btn_back.destroy()
self.btn5_1.destroy()
self.btn5_2.destroy()
self.btn5_3.destroy()
self.btn5_4.destroy()
self.btn_1_create()
# 第五任务方法 -- 边缘检测
def btn5_click(self) :
self.btn_1_delete()
self.btn_back = Button(self , text="<- 回退到上一级" , width=20 , height=2 , command=self.btn5_back)
self.canvas.create_window(850 , 40 , window=self.btn_back)
self.btn5_1 = Button(self , text = "第一种算子边缘检测" , width=20 , height=2)
self.canvas.create_window(850 , 100 , window=self.btn5_1)
self.btn5_2 = Button(self , text = "第二种算子边缘检测" , width=20 , height=2)
self.canvas.create_window(850 , 200 , window=self.btn5_2)
self.btn5_3 = Button(self , text = "第三种算子边缘检测" , width=20 , height=2)
self.canvas.create_window(850 , 300 , window=self.btn5_3)
self.btn5_4 = Button(self , text = "第四种算子边缘检测" , width=20 , height=2)
self.canvas.create_window(850 , 400 , window=self.btn5_4)
return
############################################################################################
# 第六任务方法回退到上一级目录(销毁按钮)
def btn6_back(self) :
self.btn_back.destroy()
self.btn6_1.destroy()
self.btn6_2.destroy()
self.btn6_3.destroy()
self.btn_1_create()
# 第六任务方法 -- 图像分割
def btn6_click(self) :
self.btn_1_delete()
self.btn_back = Button(self , text="<- 回退到上一级" , width=20 , height=2 , command=self.btn6_back)
self.canvas.create_window(850 , 40 , window=self.btn_back)
self.btn6_1 = Button(self , text = "阈值法" , width=20 , height=4)
self.canvas.create_window(850 , 120 , window=self.btn6_1)
self.btn6_2 = Button(self , text = "区域生长法" , width=20 , height=4)
self.canvas.create_window(850 , 240 , window=self.btn6_2)
self.btn6_3 = Button(self , text = "区域分裂与合并" , width=20 , height=4)
self.canvas.create_window(850 , 360 , window=self.btn6_3)
return
############################################################################################
# 第七任务方法回退到上一级目录(销毁按钮)
def btn7_back(self) :
self.btn_back.destroy()
self.btn7_1.destroy()
self.btn7_2.destroy()
self.btn_1_create()
# 第七任务方法 -- 图像分类
def btn7_click(self) :
self.btn_1_delete()
self.btn_back = Button(self , text="<- 回退到上一级" , width=20 , height=2 , command=self.btn7_back)
self.canvas.create_window(850 , 40 , window=self.btn_back)
self.btn7_1 = Button(self , text = "自建卷积网络" , width=20 , height=4)
self.canvas.create_window(850 , 120 , window=self.btn7_1)
self.btn7_2 = Button(self , text = "经典神经网络" , width=20 , height=4)
self.canvas.create_window(850 , 240 , window=self.btn7_2)
return
##############################################
# 用来绘制窗体中的内容
def createWidgets(self) :
self.canvas = Canvas(self , width=1700 , height=800)
self.canvas.pack()
# 上传按钮
self.btnUpload = Button(self , text = "上传图片" , width=10 , height=2 , command=self.uploadPicture)
self.canvas.create_window(150 , 50 , window=self.btnUpload)
# 下载按钮
self.btnDownload = Button(self , text = "下载图片" , width=10 , height=2 , command=self.downloadPicture)
self.canvas.create_window(1050 , 50 , window=self.btnDownload)
# 构建一个输入框用来输入图片的本地地址
self.entry = Entry(self , fg="gray")
self.entry.insert(0 , "请输入图片的完整路径~")
# 后面要点击时自动清除文本
# self.entry.bind("<FocusIn>" , self.on_entry_click)
# self.entry.bind("<FocusOut>" , self.on_focusout)
self.canvas.create_window(300 , 50 , window=self.entry)
self.btn_1_create()
self.canvasChild = Canvas(self , width = 600 , height=600 , bg="gray")
self.canvas.create_window(400 , 400 , window=self.canvasChild)
self.canvasRightChild = Canvas(self , width = 600 , height=600 , bg="gray")
self.canvas.create_window(1300 , 400 , window=self.canvasRightChild)
app = Application()
app.master.title('Final Project of Computer Image')
app.mainloop()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。