【代码 | 数据读取】读取jason中的坐标到txt

【相关知识】

json文件介绍:数据在名称/值对中、数据由逗号分隔、花括号保存对象、方括号保存数组;        数据的书写格式是:名称:值对;        JSON 值可以是:数字(整数或浮点数)、字符串(在双引号中)、逻辑值(true 或 false)、数组(在方括号中)、对象(在花括号中)、null

方法 实现功能
json.dumps 将python对象序列化为JSON字符串
json.loads 将JSON字符串反序列化为python对象【从字符串中读取】
json.dump 将python对象序列化到文件中
json.load 将文件流中的JSON字符串反序列化为python对象【从文件中读取】

读取json的逻辑:导包 => 只读打开文件 => 读取文件

Python读取JSON文件:仔细观察其格式发现JSON其实就是Python中的字典。因此,Python对JSON的读取非常简单,一个JSON文件经过json.load()以后,就变成了Python中的字典。

python读取json文件:用open读取文件,然后进行一个循环,并在每个循环里边用json.loads()把每个json转成字典

读取方式汇总

jason2txt

json关键字驱动

python目录和文件操作★:

python文件路径

文件目录:  ..\是打开上一级目录;

python获取当前目录路径和文件★:用os.getcwd()可以获取当前工作目录的路径,而使用os.path.abspath()可以获取指定路径的绝对路径。os.path.join函数可以用来拼接路径,它可以接受多个参数,每个参数都是一个路径片段,最终会将这些路径片段拼接成一个完整的路径。例如:os.path.join('/home/user', 'Documents', 'file.txt'),最终生成一个完整的路径:/home/user/Documents/file.txt

# print(path) # 打印相对路径 # print(os.path.abspath(path)) # 打印绝对路径

os.listdir函数可以用来获取指定目录下的所有文件名,并将这些文件名存储在一个列表中返回。

在建好的txt文档内进行写入

将列表数据写入文件(txt, csv, excel)

python处理txt

读取txt文档:①指定path;②函数open返回一个表示文件的对象,对象存储在f中;其中关键字with在不需要访问文件时将其自动关闭。③读取出的内容以字符串形式保存在变量里。

逐行读取txt文档时发现行间距比读取整个文件时大了很多,因为每一行都有末尾都有一个看不见的换行符,而print语句也会加上换行符。要消除这些多余空白行,可以在print语句中使用line.rstrip()

使用系统关键字with时,open()返回的文本对象只在with代码块内使用。如果要在with代码块之外访问文件的内容,可以在with代码块中将文件各行存储在一个列表中,并在with代码块外使用该列表。

读取文本文件时,python将其中的所有文本都解读为字符串。如果读取的是数字,并要将其作为数值使用,就必须使用函数int()将其转化为整数。或使用float()将其转换为浮点数。

a=c[0:3,:] 前0,1,2行

b = c[0,2:4] 第0行的第2和第3列不包括第4列,因为列下标也是从0开始的

d = c[2:4,2:4] 取中间的2-4行的2-4列

e = c[0,:] 取第0行所有数据

f = c[:,1] 取第1列所有数据

g = c[::2,::2] 两个冒号后面表示步长为2

python中二维列表:二维列表是将其他列表当做列表的元素放在一个列表当中,也就是列表的嵌套。二列表是一个多维数组,它由多个一维列表组成,每个一维列表可以包含任意数量的元素。而二列表是一个一维数组,它由两个元素组成,每个元素可以是任意类型的值。

列表后跟两个中括号的含义二元列表li [i] ['key']:li[i]是访问列表li的元素,而li的元素都是字典,用字典名通过其键来访问值。 || 这是二元列表,列表里面还有其他的可以通过关键字或者索引访问的数据结构。 li_1.append(li[i]["key"]) #通过for循环将列表内嵌字典所有的value添加到li_1列表。 || li[index]中的index代表列表第几个内嵌字典,后面紧跟的li['key']代表从列表第几个内嵌字典取出与key相对应的value || 

.extend() 方法用于在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表).append() 方法用于在列表末尾添加新的对象。区别:.extend() 方法可以一次性追加另一个序列中的多个值,而 .append() 方法只能添加一个值。

写入参数:a是不断叠加;w写入,比较好

字典排序

【代码过程】
 

保留指定小数位:

for point in points:
	# 去掉坐标中的“[ ]”符号
	point = str(point).replace('[', '').replace(']', '')
	# 以逗号隔开两个坐标
	point_list = point.split(',')
	# 将字符串转换为浮点数
	point_list = [float(x) for x in point_list]
	# 保留3位小数
	point_list = [format(x, '.3f') for x in point_list]
	# 将两个坐标拼接成字符串
	point = ','.join(point_list)
	f.write(point + '\n')


一行搞定:
 # 以逗号隔开两个坐标,并将两个坐标都转换成float形式并保留3位小数
point = ','.join(map(lambda x: format(float(x), '.3f'), point.split(',')))
            f.write(point + '\n')
    

在labelme标注工具中,标注circle的时候,会得到两个点,第一个点表示圆心,第二个点表示圆的半径。所以对于标定顺序确定的json文档,转成txt后我只要保留两个circle中的第一个坐标(以点检测为现在要做的第一步实验内容)【写入之前加个判断】

# 将坐标写入txt文档 【所有坐标全部写入】
with open(file_name.replace('.json', '.txt'), 'w') as f:
	for point in points:
		point = str(point).replace('[', '').replace(']', '')    # 字符串
		point = ','.join(map(lambda x: format(float(x), '.3f'), point.split(',')))
		f.write(point + '\n')
		# f.write(str(point) + '\n')
# 将坐标写入txt文档 【删除不需要的行】
with open(file_name.replace('.json', '.txt'), 'w') as f:
	for index, point in enumerate(points):
		if index == 7 or index == 9:
			pass
		else:
			point = str(point).replace('[', '').replace(']', '')    # 字符串
			point = ','.join(map(lambda x: format(float(x), '.3f'), point.split(',')))
			f.write(point + '\n')
结果查看 done!

但是图像标记的landmark的顺序不是固定的,所以我开始得到的10个点坐标并不是固定的,标记人员各自的顺序不同,所以需要同一txt文档中标记点的坐标位置。

一个JSON文件,它包含了一个版本号、一个空的flags字典和一个shapes列表,shapes列表中包含了多个shape字典,每个shape字典中包含了一个label、一个points列表、一个group_id、一个shape_type和一个flags字典。

从JSON文件中获取shapes键对应的值,即shapes列表,该列表包含了多个shape字典。

创建一个长度为17的空列表,用于存储从shapes列表中获取的points值。

对x-y坐标进行排序

【最终代码】

# -*- coding:utf8 -*-
import os
import json
from pprint import pprint

def json_filelist(jsonpath):
    """获取json文件路径"""
    jsons_path = []
    json_list = os.listdir(jsonpath)
    for json in json_list:
        if json.endswith('.json'):  # 对文件格式进行判断
            jsons_path.append(os.path.join(jsonpath, json))
    return jsons_path

def load_json(jsonpath):
    # 获取所有jason文件的文件名
    # file_list = os.listdir(jsonpath)  # 列表(文件名)
    # 遍历每个jason文件
    # for file_name in jsonpath:
    #     # 解析jason文件
    with open(jsonpath, 'r') as f:
        data = json.load(f)
    data_save = dict()
    for i in range(8):
        label = data['shapes'][i]['label']
        if label =='4-1' or '4-2':
            data_save[label]=data['shapes'][i]['points'][0]
        else:
            data_save[label] = data['shapes'][i]['points']

    data_save = sorted(data_save.items())

    savepath= os.path.join('labelstxt',os.path.basename(jsonpath)).replace('.json','.txt')
    # print(savepath)
    with open(savepath,'w',encoding='utf-8') as f:
        for i in range(8):
            point = str(data_save[i][1]).replace('[', '').replace(']', '')
            f.write(point)
            f.write('\n')

if __name__ == '__main__':
    jsonpath = json_filelist('labels')
    # pprint(jsonpath)
    for i in range(len(jsonpath)):
        load_json(jsonpath[i])

用之前标定点判定没有报错,但在Lable总数检查的时候发现少了3个点;统计countPoint和countCircle的时候也都没有问题。 =>最后发现是标注里45.json中重复标记,所以一开始标签的选择还是挺重要的,影响后面的读取、标签排序。(没有采取脊柱的位置判定方法,纯标签排序)

猜你喜欢

转载自blog.csdn.net/sinat_40759442/article/details/129094015