python进阶05 常用问题库(1)json os os.path模块

本文详细介绍了Python中JSON模块的使用方法,包括数据转换、文件操作等,并深入探讨了os模块在文件与路径操作方面的应用。

python进阶05 常用问题库(1)json os os.path模块

一、json模块(数据交互)

  web开发和爬虫开发都离不开数据交互,web开发是做网站后台的,要跟网站前端进行数据交互

  1、什么是json

#json全名叫JavaScript Object Notation(即 JavaScript对象标记语言)
#它是JavaScript字面量标记的子集
#前段与后端进行数据交互,其实就是JS和python进行交互;传输的时候只能传纯文本;json字符串是一个纯文本文件

  2、json注意事项

#1、名称必须用双引号("")来包括
#2、值可以是双引号包括的字符串、数字、true、false、null、JavaScript数组,或子对象

#python与json转换规则

python          json
字典              对象
列表或元组      数组
字符串           字符串
int或float        数字
True或False    true或false
None              null

  3、如何操作json

#需要导入一个模块
import json

#json模块API(API:应用程序接口)有下面4个接口 
json.dumps(obj)# 将obj这个对象变成json字符串
json.loads
json.dump
json.load

#如何知道该接口的含义:输入json.dumps,然后按住Ctrl+鼠标左键,可以看到基本说明

##json.dumps(obj)# 将obj这个对象变成json字符串,字典里面嵌套字典同样可以转换

import json

data={'name':'Tuple','age':18,'list':[1,2,3],'True':True,'False':False,'None':None}

json.data=json.dumps(data)#返回一个字符串
print(type(json.data))
print(json.data)
#输出{"name":'Tuple',"age":18,"list":[1,2,3],'"True":true,"False":false,"None":null}# 按照上面的规则转换


##json.loads(s)   #将json字符串s转化为python的数据类型,由于json不认识元组,转化回来的只能是列表,但数据是不会变的
py_dict=json.loads(json.data)
print(py_dict)
#输出{'name':'Tuple','age':18,'list':[1,2,3],'True':True,'False':False,'None':None}

二、文件与路径操作 

#网站上的文件其实是静态文件
#下载的时候需要通过python
#os模块 问题引入:
#python需要经常处理文件、目录及路径的问题
#对于文件与目录,我们必须要掌握哪些基本操作?基本的都会学习,不基本的需要自学
#对于路径,我们必须要能够处理哪些问题?基本操作
#如何用Python去做?

三、os模块的目录及文件操作

  1、显示当前路径 os.getcwd

import os

pwd=os.getcwd()  #相当于linux的pwd,显示当前路径

  2、展示当前目录内容 os.listdir(path)

import os

content=os.listdir()#展示当前目录内容,相当于linux 的ls -a

content=os.listdir('/home/pyvip/')#也可以看具体路径下的内容

  3、改变当前路径 os.chdir(path)

import os
print(os.chdir('..')) #相当于cd

  4、判断是否是一个目录os.path.isdir和文件os.path.isfile

#由于他不区分文件和目录,所有需要判断
print(os.path.isdir('/home/pyvip/.bashrc'))#判断是否是个目录,输出True
print(os.path.isfile('/home/pyvip/.bashrc'))#判断是否是个文件,输出False

  5、创建目录os.mkdir

import os
test=os.mkdir('test.txt')
print(test) #输出['test.txt'] None ,因为os.mkdir('test.txt')是一个函数,运行完了没有返回值,所以会输出None,而'test.txt'是一个目录,而不是一个txt文件

for i in os.listdir():
    print(i,os.path.isdir(i)) #通过这个循环来遍历这个目录下的所有文件是否是文件夹#输出test.txt True 是一个文件夹

  6、删除目录os.rmdir

os.rmdir(path) #输入一个目录即可

  7、删除文件os.remove

os.remove(parh)#输入一个目录即可

  8、重命名os.rename

os.rename(src,dst) 
os.rename('test.txt','../text.txt')


src:sourse #
dst:destination# 目的地

 

  路径操作os.path模块

  1、路径拼接 os.path.join

#我想看.bashrc这个东西是个文件还是文件夹,但是我只有一个完整路径,没有斜杠的路径,这就可以用os.path.join
print(os.path.join(os.getcwd(),'.bashrc'))#输出/home/pyvip/.bashrc

os.path.join('home','pyvip','US16')#中间不管有没有正斜杠,他都会帮你处理好
#输出 /home/pyvip//bashrc

print(os.path.join('home/','/pyvip','US16'))#/pyvip/US16 原因是pyvip前面加个/,他会认为这是根目录,前面会被忽略掉

  2、所在目录、父级目录 os.path.dirname

import os
pwd=os.getcwd()
print(pwd) #当前目录
print(os.path.dirname(pwd)) #父级目录

  3、基本短路径 os.path.basename

#有个完整路径,想看看最底层的文件名
import os
print(os.path.basename('/home/pyvip/.bashrc'))#输出.bashrc

  4、绝对路径os.path.abspath

import os
os.path.abspath('myproject/ttt.py')#想知道ttt.py的绝对路径,给的是相对路径
#输出的是/home/pyvip/Us16/myprojext/ttt.py(绝对路径)

  5、相对路径os.path.relpath

  6、规范化路径os.path.normpath

print(os.path.normpath('/home/vip/../pyvip'))#输出/home/pyvip

  7、是否是绝对路径 os.path.isabs

  8、资源大小os.path.getsize

os.path.getsize('ttt.py')# 输出158  这个158是字节,bit是位,byte是字节,1字节是8位,其他都是1024的翻倍

  9、资源时间os.path.getctime

os.path.getatime('ttt.py') #access 访问
os.path.getatime('ttt.py') #create 创建
os.path.getatime('ttt.py') #modify 修改

#输出 1519823306.8060257 这是时间戳,即从1970.1.1经过的秒数

 

  10、资源是否存在os.path.exists

import os
print(os.path.exists('/home/pyvip/us10'))#如果不存在,那么久创建一个文件夹

 三、补充

  1、json.dump 与json.load

#作用:将一个字典,转化成一个json文件(里面存的就是一个字符串,就是那个json)

import json

data={'name':'tuple','age':18}
with open('xx.json','w') as fp:
    json.dump(data,fp)

#实际工作中,是不会去生成文件的,在框架里面,直接返回给一个浏览器

with open('xx.json','r') as fp
    py_dict=json.load(fp)#直接读出文件的内容

print(py_dict)

  2、如何查资料

#打开docs.python.org/3/
#其中Library Reference是 内置库
#Tutoral 入门教程(不适合我们)

#打开内置库,按下Ctrl+F,输入需要找的内容

 

  

 

 

    

 

转载于:https://www.cnblogs.com/xuchengcheng1215/p/8483026.html

jpgs_path = "datasets/JPEGImages" pngs_path = "datasets/SegmentationClass" classes = ["_background_", "new_corse","old_corse","black"] count = os.listdir("./datasets/before/") for i in range(0, len(count)): path = os.path.join("./datasets/before", count[i]) if os.path.isfile(path) and path.endswith('json'): data = json.load(open(path)) if data['imageData']: imageData = data['imageData'] else: imagePath = os.path.join(os.path.dirname(path), data['imagePath']) with open(imagePath, 'rb') as f: imageData = f.read() imageData = base64.b64encode(imageData).decode('utf-8') img = utils.img_b64_to_arr(imageData) label_name_to_value = {'_background_': 0} for shape in data['shapes']: label_name = shape['label'] if label_name in label_name_to_value: label_value = label_name_to_value[label_name] else: label_value = len(label_name_to_value) label_name_to_value[label_name] = label_value # label_values must be dense label_values, label_names = [], [] for ln, lv in sorted(label_name_to_value.items(), key=lambda x: x[1]): label_values.append(lv) label_names.append(ln) assert label_values == list(range(len(label_values))) lbl = utils.shapes_to_label(img.shape, data['shapes'], label_name_to_value) PIL.Image.fromarray(img).save(osp.join(jpgs_path, count[i].split(".")[0] + '.jpg')) new = np.zeros([np.shape(img)[0], np.shape(img)[1]]) for name in label_names: index_json = label_names.index(name) index_all = classes.index(name) new = new + index_all * (np.array(lbl) == index_json) # utils.lblsave(osp.join(pngs_path, count[i].split(".")[0]+'.png'), new) # print('Saved ' + count[i].split(".")[0] + '.jpg and ' + count[i].split(".")[0] + '.png') utils.lblsave(osp.join(pngs_path, count[i].split(".")[0] + '.png'), new) print('Saved ' + count[i].split(".")[0] + '.jpg and ' + count[i].split(".")[0] + '.png')
最新发布
05-13
<think>好的,我现在需要解决用户的问题:如何用PythonJSON文件中的图像数据转换为JPG和PNG格式,并保存到指定路径,同时生成带有分类标签的分割图。首先,我得理清楚用户的场景和需求。用户提到的JSON文件可能是通过labelme这样的标注工具生成的,里面包含了图像数据和分割标签的信息。用户需要提取这些数据,转换成常见的图像格式,并且生成对应的分割标签图,不同的类别用不同的值表示。 首先,我需要确定JSON文件的结构。通常,labelme生成的JSON文件包括图像数据(可能是Base64编码的字符串)、图像尺寸、形状标注(比如多边形、矩形等),以及每个形状对应的标签名称。用户的目标是从这些JSON文件中提取图像数据保存为JPG或PNG,同时根据标注信息生成分割标签图,通常是PNG格式,每个像素的值对应类别。 接下来,我需要考虑如何解析JSON文件。Python中有json模块可以处理JSON数据。首先,读取JSON文件,解析出图像数据。图像数据可能存储为Base64字符串,所以需要解码。使用base64模块的b64decode函数将字符串转换为二进制数据,然后用PIL的Image.open或者cv2.imdecode来读取图像数据,保存为JPG或PNG文件。 然后是生成分割标签图。这一步比较复杂。需要根据JSON中的shapes字段,每个形状的信息(比如点坐标、标签名)来创建对应的掩膜。不同的标签需要赋予不同的整数值,比如背景是0,类别11,类别2是2,以此类推。需要遍历所有的形状,根据它们的坐标在空白画布上绘制对应的区域,并填充对应的类别值。这里可能需要用到OpenCV或者PIL的图像处理函数。例如,使用cv2.fillPoly来绘制多边形区域,或者用PIL的ImageDraw模块来绘制形状。 另外,用户提到需要处理多类标签,所以需要建立一个标签名称到整数值的映射。比如,可以将标签名存储在一个字典中,自动分配数值,或者用户预先定义好。例如,{"background":0, "cat":1, "dog":2}。这样,在生成分割图时,每个像素的位置根据标注的形状填充对应的数值。 接下来,需要考虑如何处理多个JSON文件。用户可能需要批量处理,遍历指定目录下的所有JSON文件,逐个处理。同时,保存路径需要用户指定,可能需要检查路径是否存在,不存在则创建,使用os.makedirs函数。 现在,整合这些步骤,编写Python代码的大致流程: 1. 导入必要的json, base64, os, PIL.Image, numpy, cv2等。 2. 定义函数处理单个JSON文件: a. 读取JSON文件内容。 b. 解析图像数据,Base64解码,保存为JPG/PNG。 c. 创建空白的分割标签图(尺寸与原图相同)。 d. 遍历每个形状,根据标签名分配数值,绘制到分割图上。 e. 保存分割图到指定路径。 3. 处理批量文件,遍历输入目录中的所有JSON文件,逐个处理。 4. 处理标签映射,可能需要用户提供标签到值的字典,或者自动生成。 需要注意的是,图像数据在JSON中可能存储为Base64字符串,也可能直接是文件路径。但根据用户的问题,应该是直接存储在JSON中的情况,比如通过labelme保存的JSON包含图像数据。因此需要正确解析这部分。 可能的难点包括正确解析Base64数据,处理不同的形状类型(比如多边形、矩形、圆形等),以及高效地生成分割图。例如,多边形需要正确的坐标点处理,而矩形可能需要转换为四个顶点坐标。 另外,分割图的保存格式通常是单通道的PNG,每个像素的值是整数,代表类别。需要确保保存时是单通道,并且数据类型正确(如uint8)。 现在,我需要验证这些步骤是否正确。例如,解析Base64字符串是否正确,生成的分割图是否正确覆盖所有标注区域,标签值是否正确分配。可能需要测试代码,处理一个示例JSON文件,查看输出图像和标签图是否符合预期。 可能的错误点包括:Base64解码错误,坐标转换错误(比如原图尺寸与标签图尺寸不一致),标签值未正确分配,或者多边形的绘制方式不正确。因此,在代码中需要确保正确获取原图的尺寸,并且在绘制时使用正确的坐标点。 总结,代码的大致结构如下: - 读取JSON文件,获取图像数据和标注信息。 - 解码图像数据并保存为JPG/PNG。 - 初始化一个全零的分割图(背景为0)。 - 遍历每个shape,根据标签名获取对应的值,绘制对应的区域到分割图。 - 保存分割图为PNG格式。 最后,用户可能需要生成对应的标签文件,比如将标签名称和对应的数值保存为一个文本文件,方便后续处理。这可以通过维护一个字典,并在处理所有文件后保存该字典来实现。 此外,用户提到的引用中,引用[2]提到可以用代码批量处理JSON转换,而不是手动处理。因此,代码需要支持批量处理,遍历目录下的所有JSON文件。 可能的代码示例: 使用PIL和numpy处理图像,用json和base64解析数据。对于每个shape,根据类型(比如多边形)绘制到分割图上。 现在,编写具体的代码步骤: 1. 加载JSON文件: import json with open(json_path, 'r') as f: data = json.load(f) 2. 解码图像数据: image_data = base64.b64decode(data['imageData']) image = Image.open(io.BytesIO(image_data)) image.save(image_path) 3. 创建分割图: width = data['imageWidth'] height = data['imageHeight'] seg = np.zeros((height, width), dtype=np.uint8) 4. 遍历shapes: label_map = {'background':0, 'class1':1, ...} # 需要用户定义或自动生成 for shape in data['shapes']: label_name = shape['label'] if label_name not in label_map: # 处理新标签,分配新值 label_map[label_name] = len(label_map) points = shape['points'] # 根据形状类型绘制 if shape['shape_type'] == 'polygon': # 将点转换为整数坐标 pts = np.array(points, dtype=np.int32) # 使用cv2.fillPoly绘制 cv2.fillPoly(seg, [pts], label_map[label_name]) 5. 保存分割图: seg_img = Image.fromarray(seg) seg_img.save(seg_path) 可能还需要处理不同的形状类型,比如矩形、圆形等,但labelme主要支持多边形、矩形等。对于矩形,可能需要将其转换为四个点的多边形。 此外,需要确保坐标点正确,因为labelme的坐标是相对于原图的,所以不需要缩放。 最后,将上述步骤整合到函数中,处理批量文件,并保存到指定路径。 可能还需要处理文件名,例如根据JSON文件名生成对应的图像和分割图文件名。 综上,这就是解决问题的思路。接下来需要将这些步骤转化为具体的Python代码,并测试其正确性。</think>根据您的需求,我将分步骤说明如何使用Python实现JSON到JPG/PNG图像和分割标签图的转换: ### 一、环境准备 安装所需依赖: ```bash pip install labelme numpy opencv-python pillow ``` ### 二、核心代码实现 ```python import os import json import base64 import numpy as np from PIL import Image import cv2 from io import BytesIO def json_to_images(json_path, output_dir, label_map=None): # 创建输出目录 os.makedirs(output_dir, exist_ok=True) os.makedirs(os.path.join(output_dir, "seg"), exist_ok=True) # 初始化标签映射 label_map = label_map or {"_background_": 0} # 处理单个JSON文件 with open(json_path, 'r') as f: data = json.load(f) # 解码图像数据 image_data = base64.b64decode(data['imageData']) img = Image.open(BytesIO(image_data)) # 保存原始图像 base_name = os.path.splitext(os.path.basename(json_path))[0] img.save(os.path.join(output_dir, f"{base_name}.jpg")) # 或.png # 创建分割标签图 seg = np.zeros((data['imageHeight'], data['imageWidth']), dtype=np.uint8) # 处理所有标注形状 for shape in data['shapes']: label = shape['label'] if label not in label_map: label_map[label] = len(label_map) points = np.array(shape['points'], dtype=np.int32) # 根据形状类型绘制 if shape['shape_type'] == 'polygon': cv2.fillPoly(seg, [points], label_map[label]) elif shape['shape_type'] == 'rectangle': x1, y1 = points[0] x2, y2 = points[1] cv2.rectangle(seg, (x1,y1), (x2,y2), label_map[label], -1) # 保存分割图 cv2.imwrite(os.path.join(output_dir, "seg", f"{base_name}_seg.png"), seg) return label_map # 批量处理示例 input_dir = "input_jsons" output_dir = "output_images" label_map = {} for filename in os.listdir(input_dir): if filename.endswith(".json"): json_path = os.path.join(input_dir, filename) label_map = json_to_images(json_path, output_dir, label_map) # 保存标签映射关系 with open(os.path.join(output_dir, "label_map.txt"), 'w') as f: for name, idx in label_map.items(): f.write(f"{name}:{idx}\n") ``` ### 三、关键步骤说明 1. **Base64解码**:从JSON文件中提取并解码图像数据[^2] 2. **标签动态映射**:自动为每个类别分配唯一整数值(背景默认0) 3. **形状绘制**:支持多边形和矩形两种常见标注类型[^1] 4. **批量处理**:遍历指定目录下所有JSON文件 5. **输出结构**: ``` output_images/ ├── image1.jpg ├── image2.png └── seg/ ├── image1_seg.png └── image2_seg.png ``` ### 四、进阶功能建议 1. **颜色映射**:添加可视化颜色表用于标签预览 ```python def apply_colormap(seg): cmap = np.zeros((256, 3), dtype=np.uint8) cmap[0] = [0,0,0] # 背景-黑色 cmap[1] = [255,0,0] # 类别1-红色 cmap[2] = [0,255,0] # 类别2-绿色 return cv2.applyColorMap(seg, cmap) ``` 2. **多线程处理**:使用`concurrent.futures`加速批量转换
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值