Labelme标注数据的一些操作

1、删除没有标注的图片

有些图片没有标注,只有图片没有json文件,需要将多余的图片删除,代码如下:

import glob
import  os
imagelist=glob.glob('../images/*.jpg')for i in range(len(imagelist)):if not os.path.exists(imagelist[i].replace("jpg","json")):os.remove(imagelist[i])

或者

import glob
import os
import time
# 获取所有JPEG图片文件
jpg_images = glob.glob('./data/*.jpg')
timestr = int(time.time())
# 遍历所有JPEG图片文件
for jpg_img in jpg_images:# 获取图片文件名(不包括扩展名)img_name = os.path.splitext(os.path.basename(jpg_img))[0]# 构造对应的JSON文件路径json_file_path = os.path.join('./data', img_name + '.json')# 检查JSON文件是否存在if os.path.exists(json_file_path):# 如果存在,则保留图片(实际上这里不需要做任何操作,因为图片没有被删除)print(f"保留图片: {jpg_img}, 因为存在对应的JSON文件: {json_file_path}")else:os.remove(jpg_img)print(f"删除图片: {jpg_img}, 因为不存在对应的JSON文件")print("处理完成。")

2、对图片重新命名

标注前,图片名字杂乱,需要对图片重新命名,我使用时间戳对图片重新命名,防止图片的名字重复,代码如下:

import glob
import os
import shutil
import time
import randomimaglist=glob.glob('data/*.jpg')
random.shuffle(imaglist)
print(imaglist)
os.makedirs('image_new',exist_ok=True
)
i=0
timesp=int(time.time())
for image_path in imaglist:print(image_path)shutil.copy(image_path,'image_new/'+str(timesp+i)+".jpg")i=i+1

3、对标注后的数据重新命名

数据标注完成后,对标注的数据统一命名,我这里使用时间戳命名,代码如下:


import glob
import os
import time
import jsonimag_dir = "../image_new2/"
# 获取所有JPEG图片文件
jpg_images = glob.glob(os.path.join(imag_dir, '*.jpg'))timestamp = int(time.time())# 将时间戳转换为字符串,以便在文件名中使用# 遍历所有JPEG图片文件
for jpg_img in jpg_images:timestamp=timestamp+1timestamp_str = str(timestamp)# 获取图片文件名(包括路径,但不包括扩展名)img_path, img_name_ext = os.path.split(jpg_img)img_name, img_ext = os.path.splitext(img_name_ext)print(img_ext)# 构造新的图片和JSON文件路径new_img_name = f"{timestamp_str}{img_ext}"new_img_path = os.path.join(img_path, new_img_name)new_json_name = f"{timestamp_str}.json"new_json_path = os.path.join(img_path, new_json_name)# 重命名图片文件os.rename(jpg_img, new_img_path)# 检查JSON文件是否存在,如果存在则更新它json_path = os.path.join(img_path, f"{img_name}.json")if os.path.exists(json_path):try:with open(json_path, 'r', encoding='utf-8') as json_file:json_data = json.load(json_file)# 更新JSON文件中的imagePath字段(假设它是相对于imag_dir的路径)if 'imagePath' in json_data:# 注意:这里需要处理imagePath是完整路径还是相对路径的情况# 如果imagePath是完整路径,则可能需要更复杂的逻辑来更新它# 这里假设imagePath只是文件名(不包括目录),因此直接替换json_data['imagePath'] = new_img_name# 将更新后的JSON数据写回文件with open(new_json_path, 'w', encoding='utf-8') as json_file:json.dump(json_data, json_file, ensure_ascii=False, indent=4)# 可选:删除旧的JSON文件(如果不需要保留的话)os.remove(json_path)except json.JSONDecodeError:print(f"Error decoding JSON file: {json_path}")except Exception as e:print(f"An error occurred while processing {json_path}: {e}")else:print(f"No JSON file found for image: {jpg_img}")print("Renaming completed.")

4、两个Labelme数据文件夹合并

图片由两个人共同标注,每个人关注不同的类别,这时候就需要对数据做合并,两个标注好的数据图片存在重叠,但是类别不存在重叠,需要将同一张图片的两个json文件合并,代码如下:

import os
import json
import shutildef merge_json_annotations(json_obj1, json_obj2, image_id):# 假设每个JSON对象都有一个'shapes'字段,包含所有的标注形状shapes1 = json_obj1.get('shapes', [])shapes2 = json_obj2.get('shapes', [])# 合并shapes数组merged_shapes = shapes1 + shapes2# 创建一个新的JSON对象,将合并后的shapes放入其中merged_json = {'version': json_obj1.get('version', '4.5.13'),  # 假设版本号是相同的,或者你可以根据需要选择'flags': {},  # 这个字段可能为空,根据你的JSON结构来决定是否保留或合并'shapes': merged_shapes,'imagePath': json_obj1.get('imagePath', json_obj2.get('imagePath', '')),  # 保留一个有效的imagePath'imageData': json_obj1['imageData'],  # 这个字段通常包含图像的Base64编码,但在合并时可能不需要'imageHeight': json_obj1.get('imageHeight', json_obj2.get('imageHeight', 0)),'imageWidth': json_obj1.get('imageWidth', json_obj2.get('imageWidth', 0)),'lineColor':json_obj1.get('lineColor'),'fillColor':json_obj1.get('fillColor'),# 可能还有其他字段需要合并,比如'type'(通常是'annotation'),这里省略了}# 如果JSON对象中有额外的字段需要合并,可以在这里添加逻辑# 比如合并'region_shape_attributes'等自定义字段# 为了确保唯一性,可以根据需要修改shape的ID或其他唯一标识符# 这个例子中没有处理ID冲突,因为具体的处理逻辑取决于你的需求return merged_jsondef copy_or_merge_files(src_dir1, src_dir2, dst_dir, image_extension='.jpg', json_extension='.json'):if not os.path.exists(dst_dir):os.makedirs(dst_dir)# 使用一个集合来跟踪已经处理的图片文件名,以避免重复处理processed_images = set()for src_dir in [src_dir1, src_dir2]:print(src_dir)for root, dirs, files in os.walk(src_dir):for file in files:print(file)file_extension = os.path.splitext(file)[1]if file_extension == json_extension:base_name = os.path.splitext(file)[0]image_file = os.path.join(root, base_name + image_extension)# 确保图片文件存在,因为JSON文件是基于图片文件的if os.path.exists(image_file):# 读取JSON文件with open(os.path.join(root, file), 'r', encoding='utf-8') as f:json_obj = json.load(f)# 在目标目录中查找同名的图片和JSON文件dst_image_file = os.path.join(dst_dir, base_name + image_extension)dst_json_file = os.path.join(dst_dir, base_name + json_extension)# 如果目标目录中已经有同名的图片文件if os.path.exists(dst_image_file):# 检查是否存在同名的JSON文件,并合并内容if os.path.exists(dst_json_file):with open(dst_json_file, 'r', encoding='utf-8') as f:existing_json_obj = json.load(f)# 合并JSON对象merged_json_obj = merge_json_annotations(existing_json_obj, json_obj, base_name)# 写入合并后的JSON文件with open(dst_json_file, 'w', encoding='utf-8') as f:json.dump(merged_json_obj, f, ensure_ascii=False, indent=4)print(f"Merged JSON file: {dst_json_file}")else:# 如果目标目录中没有同名的JSON文件,则直接复制新的JSON文件shutil.copy2(os.path.join(root, file), dst_json_file)print(f"Copied JSON file: {os.path.join(root, file)} to {dst_json_file}")else:# 如果目标目录中没有同名的图片文件,则复制图片和JSON文件shutil.copy2(image_file, dst_image_file)shutil.copy2(os.path.join(root, file), dst_json_file)print(f"Copied image and JSON files: {image_file} and {os.path.join(root, file)} to {dst_dir}")elif file_extension == image_extension:# 如果只遇到图片文件而没有对应的JSON文件,可以选择跳过或根据需要处理print(f"Skipped image file without corresponding JSON: {file}")def main():src_dir1 = 'image_new1'src_dir2 = 'image_new'dst_dir = 'image_new2'copy_or_merge_files(src_dir1, src_dir2, dst_dir)if __name__ == "__main__":main()

5、其他格式的图片转jpg

文件夹中存到多种图片,将其他格式的图片转为jpg,如果转换失败则删除,代码如下:

# 将其他格式的图片转为jpg格式的图片,如果不能转换则删除。
import os
from PIL import Imagedef convert_images_to_jpg(directory):# 遍历目录中的所有文件for root, dirs, files in os.walk(directory):for file in files:# 获取文件的完整路径file_path = os.path.join(root, file)# 获取文件的扩展名_, file_extension = os.path.splitext(file)file_extension = file_extension.lower()  # 转换为小写进行比较# 判断文件是否为非 JPG 图像文件if file_extension in ['.png', '.bmp', '.gif', '.tiff', '.jpeg'] and file_extension != '.jpg':try:# 打开图像文件with Image.open(file_path) as img:# 构造新的 JPG 文件路径(将原文件的扩展名替换为 .jpg)jpg_file_path = os.path.splitext(file_path)[0] + '.jpg'# 保存为 JPG 格式img.save(jpg_file_path, 'JPEG')print(f"Converted {file_path} to {jpg_file_path}")os.remove(file_path)except Exception as e:os.remove(file_path)print(f"Failed to convert {file_path}: {e}")# 指定要处理的目录路径
directory_path = 'data'
convert_images_to_jpg(directory_path)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/13542.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【C语言】程序性能优化——除法运算符

【C语言】程序性能优化——除法运算符 文章目录 [TOC](文章目录) 前言一、牛顿迭代法1、数学基础2、C代码3、实验 二、二分法1、数学基础2、C代码3、实验 三、参考资料总结 前言 提示:以下是本篇文章正文内容,下面案例可供参考 一、牛顿迭代法 1、数学…

每日计划-1109

1. 完成 104. 二叉树的最大深度 class Solution { public:// 计算二叉树的最大深度的函数int maxDepth(TreeNode* root) {// 如果根节点为空,说明已经到达叶子节点的下一层,返回0(这里代码中 return false 应该是错误的,应该是 r…

基于YOLOv5的人群密度检测系统设计与实现

大家好,本文将介绍基于改进后的YOLOv5目标检测模型,设计并实现人群密度检测系统。 使用YOLOv5的源代码,在此基础上修改和训练模型, 数据集选用crowdhuman数据集。对yolov5源码中的文件进行修改,更换主干网络、改进损失…

鸿蒙入门——ArkUI 自定义组件间的父子双向同步状态装饰器@Link语法(四)

文章大纲 引言一、组件间状态装饰器Link 父子双向同步1、使用规则2、支持的观察变化的场景和ArkUI 刷新UI3、Link变量值初始化和更新机制3.1、初始渲染:执行父组件的build()函数后将创建子组件的新实例。3.2、Link的数据源的更新:即父组件中状态变量更新…

【Android、IOS、Flutter、鸿蒙、ReactNative 】启动页

Android 设置启动页 自定义 splash.xml 通过themes.xml配置启动页背景图 IOS 设置启动页 LaunchScreen.storyboard 设置为启动页 storyboard页面绘制 Assets.xcassets 目录下导入图片 AppLogo Flutter 设置启动页 Flutter Android 设置启动页 自定义 launch_background.xm…

[SaaS] 数禾科技 AIGC生成营销素材

https://zhuanlan.zhihu.com/p/923637935https://zhuanlan.zhihu.com/p/923637935

前端开发中常用的包管理器(npm、yarn、pnpm、bower、parcel)

文章目录 1. npm (Node Package Manager)2. Yarn (Yarn Package Manager)3. pnpm4. Bower5. Parcel总结 前端开发中常用的包管理器主要有以下几个: 1. npm (Node Package Manager) 简介: npm 是 Node.js 的默认包管理器,也是最广泛使用的包…

【go从零单排】Random Numbers、Number Parsing

🌈Don’t worry , just coding! 内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。 📗概念 这里是引用 💻代码 Random Numbers package mainimport ("fmt…

qt移植到arm报错动态库找不到

error while loading shared libraries: libAlterManager.so.1: cannot open shared object file: No such file or directory 通过设置环境变量 LD_LIBRARY_PATH就行了。 LD_LIBRARY_PATH是一个用于指定动态链接器在运行时搜索共享库的路径的环境变量。 例如: 前…

GoogleMIT:多智能体医疗决策框架MDAgents

|记昨日与国内某Top 1&2 医院科室老师及团队探讨技术、医学、信仰与责任而有感而发。 生成式基础大模型正在成为临床辅助甚至医学探索领域的宝贵工具。尽管我们在国内看到了很多企业或实验室联合医疗机构在如医疗记录生成、临床表型辅助诊疗、医疗知识问答交互、医院管理决…

【数据库】深入解析慢 SQL 的识别与优化策略

文章目录 什么是慢 SQL?慢 SQL 的危害如何检测分析慢 SQL使用 MySQL 慢查询日志利用 EXPLAIN 分析执行计划通过 Profiling 获取详细执行信息借助慢 SQL 收集分析平台 实际案例解析:600秒的慢 SQL 优化之旅问题描述初步分析优化步骤1. 优化 SQL 语句结构2…

高校大数据人工智能教学沙盘分享

大数据教学实训沙盘(TipDM-SP)是根据企业实际项目建设而成,并提供沙盘配套装置、软件以及教学实训资源。沙盘的作用主要有3个: 1、采集真实数据,解决教学中缺少真实数据的困扰; 2、形成从数据…

【C++】string模拟实现

各位读者老爷好,俺最近在学习string的一些知识。为了更好的了解string的结构,俺模拟实现了一个丐版string,有兴趣的老爷不妨垂阅!!! 目录 1.string类的定义 2.模拟实现成员函数接口 2.1.constructor&am…

c_str()函数 string类型转换成char*类型 C++实现

问题:在 class 的构造函数中,如果我们在类中初始化了 char * 类型,在调用构造函数时,如果直接传入字符串( string )类型,编译器会提出如下警告: 想要消除这个警告,就需要将 string 类型的变量转…

【vue3文件上传同时出现两个提示框,一个提示成功,一个提示失败,一个是用写死的,一个是接口返回的】

文件上传同时出现两个提示框,一个提示成功,一个提示失败,一个是用写死的,一个是接口返回的 原因: 接口返回的是字符串code200" 把判断的code码改为字符串的就好了

选择哪种Facebook广告目标更有效

在Facebook广告投放中,广告目标的选择决定了投放效果和转化率,但很多人往往忽略了这一步的细节。今天,我们来一起看看Facebook广告目标有哪些,以及如何精准选择! 1. 广告目标在投放中的重要性 广告目标不仅仅是一…

matlab实现主成分分析方法图像压缩和传输重建

原创 风一样的航哥 航哥小站 2024年11月12日 15:23 江苏 为了研究图像的渐进式传输技术,前文提到过小波变换,但是发现小波变换非常适合传输缩略图,实现渐进式传输每次传输的数据量不一样,这是因为每次变换之后低频成分大约是上一…

【缓存策略】你知道 Cache Aside(缓存旁路)这个缓存策略吗

👉博主介绍: 博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家,WEB架构师,阿里云专家博主,华为云云享专家,51CTO 专家博主 ⛪️ 个人社区&#x…

稀疏视角CBCT重建的几何感知衰减学习|文献速递-基于深度学习的病灶分割与数据超分辨率

Title 题目 Geometry-Aware Attenuation Learning forSparse-View CBCT Reconstruction 稀疏视角CBCT重建的几何感知衰减学习 01 文献速递介绍 稀疏视角锥形束计算机断层扫描(CBCT)重建的几何感知学习方法 锥形束计算机断层扫描(CBCT&a…

电子应用产品设计方案-3:插座式自动温控器设计

一、设计 插座式自动温控器作为一种便捷的温度控制设备,在日常生活和工业应用中发挥着重要作用。它能够根据环境温度的变化自动控制连接设备的电源通断,实现对温度的精确调节和节能控制。本设计旨在提供一种功能强大、易于使用、安全可靠的插座式自动温控…