使用tinkter制作打标软件 检测数据集制作–左键拖动事件 分割数据集制作-左键单击事件绑定,在终点处于起点一定范围内完成闭合 设置显示模式:1.固定大小(1.同比例缩放、2.纯固定
使用tinkter制作打标软件
检测数据集制作–左键拖动事件
分割数据集制作-左键单击事件绑定,在终点处于起点一定范围内完成闭合
设置显示模式:1.固定大小(1.同比例缩放、2.纯固定大小、3.同画布大小) 2.原图大小
Tkinter的三种布局方式,frame碎片组合
/ipady: 填充表格框,让表格框在X/Y方向上变胖
padx/pady: 决定组件跟邻近表格线或窗体边界的距离
rowspan: 组件跨多少列表格框,默认1个组件占用1行1列
columnspan :组件跨多少行表格框,默认1个组件占用1行1列
sticky :当表格框大小组件的大小,组件默认居中显示,那这个表格框周围的空白部分,如何分配,这就由sticky来决定。具体规定如下:
默认组件在表格框中是居中对齐显示的,但通过sticky可以设定N/S/W/E 即上/下/左/右 对齐,N/S/W/E 也可以组件使用,如:
sticky=N+S 拉高组件,让组件上下填充到表格框的顶端和底端。
sticky=N+S+E 拉高组件,让组件上下填充到表格框的顶端和底端,同时,让组件靠右对齐。
sticky=N+W+W+E 拉高并拉长组件,让组件填充满一个表格框。
from tkinter import *
init_window = Tk()
# 实例一个主窗口
init_window.title('grid frames')
init_window.geometry('1000x600')
'''
在设计程序界面时,有时窗体是可以调节尺寸的,我们希望有些表格框的尺寸可以跟随窗体的尺寸一起变化,这就要讲解一下这2个方法:
rowconfigure(表格框的行,缩放权重)
columnconfigure(表格框的列,缩放权重)
rowconfigure(1, weight=1) row为1的行(即第2行),缩放权重为1
columnconfigure(0, weight=1) column为0的列(第1列),缩放权重为1
weight默认为0,即窗体尺寸变化时,某行或某列的尺寸不会跟随变化
'''
# 第一行权重
init_window.grid_rowconfigure(0, weight=10)
# 第二行权重
init_window.grid_rowconfigure(1, weight=1)
# 第一列权重
init_window.grid_columnconfigure(0, weight=1)
# 第二列权重
init_window.grid_columnconfigure(1, weight=10)
# 只有对每一行每一列都设置了grid_row/columnconfigure才能实现frame大小的扩充,其中weight参数可以设置每一块的权重
frame_1 = Frame(init_window,padx=5,pady=5,bg='red')
frame_2 = Frame(init_window,padx=5,pady=5,bg='pink')
frame_3 = Frame(init_window,padx=5,pady=5,bg='peachpuff')
frame_4 = Frame(init_window,padx=5,pady=5,bg='green')
frame_1_label = Label(frame_1,text='frame1')
frame_2_label = Label(frame_2,text='frame2')
frame_3_label = Label(frame_3,text='frame3')
frame_4_label = Label(frame_4,text='frame4')
frame_1_label.pack()
frame_2_label.pack()
frame_3_label.pack()
frame_4_label.pack()
frame_1.grid(row=0,column=0,sticky=NSEW)
# frame_1.grid(row=0,column=0,columnspan=2,sticky=NSEW)
# columnspan参数代表frame占几列的网格长度若设置为2就横跨2格
# rowspan组件跨多少列表格框
frame_2.grid(row=0,column=1,sticky=NSEW)
frame_3.grid(row=1,column=0,columnspan=2,sticky=NSEW)
# 这里的sticky参数也是必须的,相当于允许frame在什么方向扩充NSEW分别就是 北南东西
init_window.mainloop()
读取图像,随画布大小改变
绘制矩形框(用线段绘制),记录位置,保存label进json文件
绘制多边形框(用线段绘制),记录位置,保存labeo进json文件
import Image, ImageTk
from tkinter import Tk, Label, Button, Frame, Menu,PhotoImage,Canvas,LEFT,RAISED,NSEW,Scrollbar
from tkinter import *
from tkinter.filedialog import askopenfilename, asksaveasfilename
from os import listdir, mkdir, remove
from os.path import split as path_split
from os.path import exists
from tkinter import messagebox
from PIL import ImageGrab
'''
全局参数
'''
bg_img_path = ""
image = None
file_path = "label.txt"
label_rect = []
label_polygon = []
# 矩形框左上点
start_point_x = 0
start_point_y = 0
# 矩形框右上点
end_point_x = 0
end_point_y = 0
# 工作流:分割、检测、传统算法检测
work_flow_type = 0
# existed_label_list
existed_label_list = []
'''
设置函数
'''
# 检测数据集制作流
def DetDatasetFlow(event=None):
global work_flow_type
work_flow_type = 0
window.title("检测数据集制作流")
# messagebox.showinfo("Message","callback1")
# 分割数据集制作流
def SegDatasetFlow(event=None):
global work_flow_type
work_flow_type = 1
window.title("分割数据集制作流")
# messagebox.showinfo("Message","callback2")
# 清除画布
def clear_all(event=None):
canvas.delete("all")
generate()
# 右击事件
def RightClicked(event):
menu.post(event.x_root, event.y_root)
# 检测-记录起点,分割构建label
def draw_begin_point(event):
global work_flow_type
if work_flow_type == 0:
global start_point_x
start_point_x= event.x
global start_point_y
start_point_y = event.y
elif work_flow_type == 1:
canvas.unbind("<B1-Motion>")
generate()
label_polygon.append(event.x)
label_polygon.append(event.y)
canvas.create_line(label_polygon,fill="red")
# 画label
def draw_label(event):
# 清图
generate()
# -
canvas.create_line(start_point_x,start_point_y,event.x,start_point_y,fill="red")
# |
canvas.create_line(event.x,start_point_y,event.x,event.y,fill="red")
# _
canvas.create_line(event.x,event.y,start_point_x ,event.y ,fill="red")
# |
canvas.create_line(start_point_x ,event.y,start_point_x,start_point_y,fill="red" )
# 清除所有
def delete():
canvas.delete("all")
generate()
'''
generate: 刷新,显示
'''
def generate():
# global 引用全局变量
global image , bg_img_path
image = PhotoImage(file=bg_img_path)
# 配置画图长宽
canvas.config(width=max(image.width(), 800), height=max(image.height(), 600))
# 显示图像
canvas.create_image((0, 0), image=image, anchor="nw")
canvas.pack()
# if work_flow_type == 0:
# canvas.bind("<B1-Motion>",draw_label)
# 保存label数据到本地
def save_label(event):
generate()
global work_flow_type
# 检测数据集制作流
if work_flow_type == 0:
# 记录右下角坐标
global end_point_x
end_point_x = event.x
global end_point_y
end_point_y = event.y
pic = ImageGrab.grab((start_point_x,start_point_y,end_point_x,end_point_y))
pic.save("trrrtr.png",format=None)
print(start_point_x,start_point_y,end_point_x,end_point_y)
# 保存label坐标至本地
with open(file=file_path, mode="a") as fd:
fd.write(str(start_point_x)+","+str(start_point_y)+","+str(end_point_x)+","+str(end_point_y))
fd.write("\n")
# 显示已画label
with open(file=file_path, mode="r") as fd:
# 读取第一行
current_line = fd.readline()
while current_line:
temp_list = current_line.split(",")
print(temp_list)
rec = []
for i in temp_list:
rec.append(int(i))
print(rec)
canvas.create_rectangle(rec,fill="")
# 读取下一行
current_line = fd.readline()
elif work_flow_type == 1:
pass
'''
打开图像文件路径
'''
def open_imgfile():
img_path = askopenfilename(
title='请选择图片文件',
# 筛选常见图片文件
filetypes=[('图片', '.jpg .png .gif .bmp .jpeg')],
)
if img_path and img_path.endswith(('.jpg', '.png', '.gif', '.jpeg', '.bmp')):
# 图像路径
path = img_path
# 图像文件夹路径
dir = path_split(path)[0]
print("message",path,dir)
# canvas.delete("all")
global bg_img_path
bg_img_path = path
image = PhotoImage(file=bg_img_path)
canvas.create_image((0, 0), image=image, anchor="nw")
'''
创建主窗口
'''
window = Tk()
window.title("创建画布")
window.geometry("1000x600+260+100")
'''
设置界面布局
'''
# 第一行权重
window.grid_rowconfigure(0, weight=10)
# 第二行权重
window.grid_rowconfigure(1, weight=1)
# 第一列权重
window.grid_columnconfigure(0, weight=1)
# 第二列权重
window.grid_columnconfigure(1, weight=10)
frame_left = Frame(window,padx=5,pady=5,bg='red')
frame_right = Frame(window,padx=5,pady=5,bg='pink')
frame_bottom = Frame(window,padx=5,pady=5,bg='peachpuff')
'''
界面组件
'''
# 按钮
btn_choose_pic = Button(frame_bottom,text="选择图像路径",font=30,bg="#666666",command=open_imgfile)
# 画布
canvas = Canvas(frame_right, width=800, height=600, bg="#AAAAAA")
# 图像
image = PhotoImage(file="test1.png")
# 配置画图长宽
canvas.config(width=max(image.width(), 800), height=max(image.height(), 600))
# 显示图像
canvas.create_image((0, 0), image=image,anchor="nw")
# 弹出菜单
menu = Menu(frame_right,tearoff=False)
# 建立工具栏
menubar = Menu(window) # 建立最上层菜单
# 建立菜单类别对象,并将此菜单类别命名为File
filemenu = Menu(menubar,tearoff=False)
menubar.add_cascade(label="File",menu=filemenu)
filemenu.add_command(label="Exit",command=window.destroy)
# 滚动条
scrollbar = Scrollbar(frame_left) # 创建滚动条
scrollbar.pack(side=RIGHT,fill=Y)
# 创建Listbox,yscrollcommand指向scrollbar.set方法
lb = Listbox(frame_left,yscrollcommand=scrollbar.set) # 建立Listbox
for i in range(50):
lb.insert(END,"Line " + str(i))
lb.pack(side=LEFT,fill=BOTH,expand=True)
canvas.pack()
btn_choose_pic.pack()
# toolbar = Frame(window,relief=RAISED,borderwidth=3)
frame_left.grid(row=0,column=0,sticky=NSEW)
frame_right.grid(row=0,column=1,sticky=NSEW)
frame_bottom.grid(row=1,column=0,columnspan=2,sticky=NSEW)
'''
绑定事件
'''
# 点击左键
canvas.bind("<Button-1>",draw_begin_point)
# 拖到左键
canvas.bind("<B1-Motion>",draw_label)
# 左键释放
canvas.bind("<ButtonRelease-1>",save_label)
# 点击右击
canvas.bind("<Button-3>", RightClicked)
# 菜单栏绑定事件
menu.add_command(label="检测数据集制作", command=DetDatasetFlow)
menu.add_command(label="分割数据集制作", command=SegDatasetFlow)
menu.add_command(label="缺陷检测", command=clear_all)
menu.add_command(label="清除所有", command=clear_all)
'''
运行程序
'''
window.config(menu=menubar)
window.mainloop()
'''
说明记录:
传统算法检测的来源分截屏和原图数据
'''
'''
说明记录:
传统算法检测的来源分截屏和原图数据
'''
'''
说明记录:
传统算法检测的来源分截屏和原图数据
'''
'''
说明记录:
传统算法检测的来源分截屏和原图数据
'''