背景:
因图片标记需要进行类型分类,目前将手掌图片做了若干个分类,然后通过labelme导入分类列表txt,对图片进行分类标注之后,目的是通过读取标注分类标签实现根据标签归类图片的功能。
关于分类标签:
目前已建立了分类类型种类并手工将相关的图片放在对应的文件夹里作为示例数据库。同时在labelme.exe所在目录中建立了分类标签文档,以flags.txt保存。
功能实现逻辑:
-
通过脚本读取flags.txt文件中的分类标签名,自动创建同名分类文件夹。
-
使用labelme手工对图片进行分类标签的标注,自动生成与图片同名的json文件,包含了分类标签信息(同一张图片可能有单个或多个分类标签)。
-
通过脚本读取json文件中的flags字段,选出值为True的分类标签并读取该文件对应的图片名称,找到该图片复制到对应的分类文件夹中。
代码记录:
import os, shutil
import json
# 基础目录
abspath = "/"
# 源目录
src_dir = "images"
src_path = f"{abspath}/{src_dir}"
# 过滤后输出的目录
dst_root_dir = "sorted_images"
dst_root_path = f"{abspath}/{dst_root_dir}"
# 读取flag.txt文件中的标签名并创建分类文件夹。
# Read flag.txt and create classification folders out of the flag names
def create_cls_folders(flags_txt_path):
# @ 读取flags.txt中的分类标签名并转换为列表。
# 定义分类标签列表
# Define the classification directory list
dirlist = []
with open(flags_txt_path, "r", encoding="utf-8") as f:
for line in f.readlines():
foldername = line.split("\n")[0]
if foldername not in dirlist:
dirlist.append(foldername)
# print(dirlist)
# 拼接分类文件夹路径
cls_path = f"{abspath}/{dst_root_dir}"
# 遍历分类标签列表中的分类名称
for folder in dirlist:
# 使用分类标签列表中所有的分类名称命名文件夹有,没有文件夹时则进行创建。
if folder in dirlist:
cls_folder = f"{cls_path}/{folder}"
# print(cls_folder)
print("Creating folder %s" % cls_folder)
if not os.path.exists(cls_folder):
os.mkdir(cls_folder)
def cp_files_to_cls_folders():
# 定义id文件夹列表
id_folder_list = sorted(os.listdir(src_path))
# print(id_folder_list)
# 遍历源路径的id文件夹列表
for i, id_folder in enumerate(id_folder_list, 1):
# print(i, id_folder)
src_folder = f"{src_path}/{id_folder}"
# 遍历id源文件夹中的文件,如果包含.json后缀的文件,则读取其中的flags标签内容。
# Traverse the id_folders and read the contents under the "flags" tag when coming across the files with the ".json" suffix.
for file in os.listdir(src_folder):
src_json_path = f"{src_folder}/{file}"
if '.json' in file:
with open(src_json_path, "r") as f:
r = json.load(f)
cls = r['flags']
# print(cls)
# 列表推导式:如果分类标签中值为True,则取出对应的分类标签键
t_cls = [x for x in cls if cls[x] is True]
# print(t_cls)
# 遍历目标路径的文件夹列表,创建True值分类标签同名文件夹,若路径中没有文件夹,则进行创建。
for t_cls_folder in os.listdir(dst_root_path):
if t_cls_folder in t_cls:
# print(t_cls_folder)
# 拼接值为True的目标分类文件夹路径
dst_t_cls_path = f"{dst_root_path}/{t_cls_folder}"
# 拼接源标签分类布尔值为True的文件(jpg和json文件)的路径
src_jpg_path = f"{src_folder}/{r['imagePath']}"
src_json_path = f"{src_folder}/{r['imagePath'][:-4]+'.json'}"
# 拼接标签分类布尔值为True的文件要复制过去的目标文件夹路径
dst_folder = f"{dst_t_cls_path}/{id_folder}"
# print(dst_folder)
# 若路径中没有文件夹则创建文件夹
if not os.path.exists(dst_folder):
os.mkdir(dst_folder)
# 拼接源文件(jpg和json文件)的路径
dst_jpg_path = f"{dst_folder}/{r['imagePath']}"
dst_json_path = f"{dst_folder}/{r['imagePath'][:-4]+'.json'}"
print("Copying image file to folder %s" % dst_jpg_path)
shutil.copy(src_jpg_path, dst_jpg_path)
print("Copying json file to folder %s" % dst_json_path)
shutil.copy(src_json_path, dst_json_path)
if __name__ == '__main__':
# 分类文件目录
flags_txt_path = "../flags.txt"
# create_cls_folders(flags_txt_path)
cp_files_to_cls_folders()
参考文献(视频):【实现Python筛选Json数据【Python】-哔哩哔哩】 https://b23.tv/WUd1xr4