写在前面:
第一次写博客,仅仅是将自己实现功能的过程和遇到的问题记录下来,因此文章质量难以保障,还请见谅。在这个 过程中遇到了许多问题,如果没有前辈们的分享和记录,我实现功能的过程也将举步维艰,于是将自己遇到的问题记录下来,希望可以帮到有需要的人。
问题描述:
因为要筛选图像数据集,筛选需要根据原图和其标签图从中选择出自己需要的图像数据,因为每张图片要挨个看和找对其对应的标签图,六千张的照片看一会就头疼,还得挨个对应,移动到相应的文件夹,太痛苦了,因此为提高效率写个简单的脚本帮助自己。
开始动手操作:
第一步:显示图片:
因为要在同一界面显示两张图片,因此需要UI界面,这里使用tkinter模块,UI设置如下:
root = tk.Toplevel()
root.title('筛选数据集程序') #窗口标题
root.resizable(False, False) #固定窗口大小
windowWidth = 800 #获得当前窗口宽
windowHeight = 600 #获得当前窗口高
screenWidth,screenHeight = root.maxsize() #获得屏幕宽和高
geometryParam = '%dx%d+%d+%d'%(windowWidth, windowHeight, (screenWidth-windowWidth)/2, (screenHeight - windowHeight)/2)
root.geometry(geometryParam) #设置窗口大小及偏移坐标
root.wm_attributes('-topmost',1)#窗口置顶
因为要提高效率,所以界面粗糙一些,实用即可。这里 遇了一个小问题,
创建UI的时候最开始使用的
root = tk.Tk()
但这里会出现一个问题,好像是窗口不显示还是什么,记不清了,查阅资料,使用
root = Toplevel()
第二步:显示图片:
需要显示两张图片,因为每张图片尺寸不一,因此在显示的时候重置其尺寸,刚开始上下显示太丑了,也不方便筛选,因此改为左右显示:
img2 = Image.open(image_path + all_list[idx])
img2 = img2.resize((300,300)) #规定图片大小
photo2 = ImageTk.PhotoImage(img2)
label_img2 = tk.Label(root, image=photo2)
label_img2.pack(side='left') #横向显示
# label 图片
img = Image.open(label_path + all_list[idx][:-4] + '_gt.png')
img = img.resize((300,300)) #规定图片大小
photo = ImageTk.PhotoImage(img)
label_img = tk.Label(root, image=photo)
label_img.pack(side='left')
这里遇到了一个问题,因为tk.Label()函数无法直接读取jpg文件,因此借用Image.open()和ImageTk.PhotoImage(),顺利打开并显示原图和标签图。
第三步:读取相应文件夹所有图片,获取目录列表:
image_path = r"原图所在位置" #文件夹目录
label_path = '标签图所在位置'
all_list = os.lisdir(image_path) #得到文件夹下的所有文件名称 所有图像文件,一个列表
idx = 0 # 初始值设置为0
这里需要设置一个index,指到当前图片位置,为后续切换图片做准备。
第四步、设置按键,链接相应的函数
设置两个按钮,这里主要是为了测试函数功能是否满足要求,有没有bug,为接下来链接键盘做准备。连接相应的功能:
button_left = tk.Button(root, text = '左键',command = left)
button_left.pack(side='bottom')
button_right = tk.Button(root, text = '右键',command = right)
button_right.pack(side='bottom')
这里左键将当前图片放到不需要的文件夹,右键将图片放到需要的文件夹。函数设置如下:
def left():
global idx,label_img2,temp1,temp,label_img
idx += 1
temp1 = Image.open(image_path + all_list[idx])
temp1 = temp1.resize((400,400))
temp1 = ImageTk.PhotoImage(temp1)
label_img2.configure(image=temp1)
temp = Image.open(label_path + all_list[idx][:-4] + '_gt.png')
temp = temp.resize((400,400))
temp = ImageTk.PhotoImage(temp)
label_img.configure(image=temp)
shutil.move(image_path + all_list[idx-1],r'D:\Users\another') #左移到另一个文件夹,
# os.remove(label_path + all_list[idx-1][:-4] + '_gt.png') # 删除标签图
def right():
global idx,label_img2,temp1,temp,label_img
idx += 1
temp1 = Image.open(image_path + all_list[idx])
temp1 = temp1.resize((400,400))
temp1 = ImageTk.PhotoImage(temp1)
label_img2.configure(image=temp1)
temp = Image.open(label_path + all_list[idx][:-4] + '_gt.png')
temp = temp.resize((400,400))
temp = ImageTk.PhotoImage(temp)
label_img.configure(image=temp)
shutil.move(image_path + all_list[idx-1],r'D:\Users\new_data') # 右移至背景图
# os.remove(label_path + all_list[idx-1][:-4] + '_gt.png') # 删除标签图
函数功能介绍:这里要实现将当前文件移动到相应的文件夹,此外还需要切换到下一张图片,此前设置的全局变量作用到了,这样可以一次切换到每一张图片,注释的部分是删除标签图,这里可删可不删,我根据自己需要删除了许多。这里我的标签图和原图文件并不一致,因此对此做出了一些改变,读者可不理。遇到的问题:
刚开始切换时不显示图片。查阅资料发现需要将图片和图片标签等都设置为全局变量,如代码中所示。
第五步:链接键盘,进一步提高效率:
鼠标左右键的电还是太累手和慢了,为此读取键盘按键,找到方向键左右按键的ASCII码,分别为37和39。当这两个按键触发时分别执行移动和切换图片的操作。
def buttX(event):
if event.keycode == 37:
print('左按键,保存至背景图')
left()
elif event.keycode == 39:
print('右按键,保存至物体图')
right()
else:
print('其他按键')
root.bind("<Key>", buttX)
全部代码
import os
import shutil
import numpy as np
import tkinter as tk
from PIL import Image, ImageTk
root = tk.Toplevel()
root.title('筛选数据集程序')
root.resizable(False, False)
windowWidth = 800
windowHeight = 600
screenWidth,screenHeight = root.maxsize()
geometryParam = '%dx%d+%d+%d'%(windowWidth, windowHeight, (screenWidth-windowWidth)/2, (screenHeight - windowHeight)/2)
root.geometry(geometryParam)
root.wm_attributes('-topmost',1)
image_path = r"原图所在位置"
label_path = r'标签图所在位置'
all_list = os.listdir(image_path)
idx = 0
# image 图片
img2 = Image.open(image_path + all_list[idx])
img2 = img2.resize((300,300))
photo2 = ImageTk.PhotoImage(img2)
label_img2 = tk.Label(root, image=photo2)
label_img2.pack(side='left')
# label 图片
img = Image.open(label_path + all_list[idx][:-4] + '_gt.png')
img = img.resize((300,300))
photo = ImageTk.PhotoImage(img)
label_img = tk.Label(root, image=photo)
label_img.pack(side='left')
def left():
global idx,label_img2,temp1,temp,label_img
idx += 1
temp1 = Image.open(image_path + all_list[idx])
temp1 = temp1.resize((400,400))
temp1 = ImageTk.PhotoImage(temp1)
label_img2.configure(image=temp1)
temp = Image.open(label_path + all_list[idx][:-4] + '_gt.png')
temp = temp.resize((400,400))
temp = ImageTk.PhotoImage(temp)
label_img.configure(image=temp)
shutil.move(image_path + all_list[idx-1],r'D:\Users\another')
# os.remove(label_path + all_list[idx-1][:-4] + '_gt.png')
def right():
global idx,label_img2,temp1,temp,label_img
idx += 1
temp1 = Image.open(image_path + all_list[idx])
temp1 = temp1.resize((400,400))
temp1 = ImageTk.PhotoImage(temp1)
label_img2.configure(image=temp1)
temp = Image.open(label_path + all_list[idx][:-4] + '_gt.png')
temp = temp.resize((400,400))
temp = ImageTk.PhotoImage(temp)
label_img.configure(image=temp)
shutil.move(image_path + all_list[idx-1],r'D:\Users\new_data')
# os.remove(label_path + all_list[idx-1][:-4] + '_gt.png')
button_left = tk.Button(root, text = '左键',command = left)
button_left.pack(side='bottom')
button_right = tk.Button(root, text = '右键',command = right)
button_right.pack(side='bottom')
def buttX(event):
if event.keycode == 37:
print('左按键,保存至背景图')
left()
elif event.keycode == 39:
print('右按键,保存至物体图')
right()
else:
print('其他按键')
root.bind("<Key>", buttX)
root.mainloop()
结果展示:
运行UI如下:
此时用鼠标点击相应的按钮,或者按键盘的左右方向键都会将当前图片保存到相应的文件夹,并切换当前图片与其标签图。
最后:
小白第一次写博客,仅仅是将自己学习的过程和遇到的问题记录下来,如有不当或者错误的地方,还请见谅。查阅了许多资料,网址已经找不到了,侵删。
补一句:这样看六千多张图片,还是看一会就头疼,而且莫名的内核挂掉,手动处理几张图片就好了,应该是图像数据的问题,影响不大。