【関連情報】
json ファイルの紹介: データは名前と値のペアであり、データはカンマで区切られ、中括弧はオブジェクトを保存し、角括弧は配列を保存します。データの書き込み形式は次のとおりです: 名前: 値のペア; JSON 値は次のとおりです: 数値(整数または浮動小数点数)、文字列 (二重引用符内)、論理値 (true または false)、配列 (角括弧内)、オブジェクト (中括弧内)、null
方法 | 機能の実装 |
---|---|
json.ダンプ | Python オブジェクトを JSON 文字列にシリアル化します。 |
json.loads | JSON 文字列を Python オブジェクトに逆シリアル化する [文字列から読み取る] |
json.ダンプ | Python オブジェクトをファイルにシリアル化する |
json.load | ファイルストリーム内のJSON文字列をPythonオブジェクトに逆シリアル化します[ファイルから読み取り] |
json を読み取るロジック: パッケージをインポート => ファイルを読み取り専用で開く => ファイルを読み取る
Python は JSON ファイルを読み取ります。その形式を注意深く観察すると、JSON が実際には Python の辞書であることがわかります。したがって、Python による JSON の読み取りは非常に簡単で、JSON ファイルが json.load() を通過すると、Python の辞書になります。
Python は json ファイルを読み取ります。open を使用してファイルを読み取り、ループを実行し、各ループで json.loads() を使用して各 json を辞書に変換します。
ファイル ディレクトリ: ..\ は、上位レベルのディレクトリを開きます。
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、csv、excel)
txt ドキュメントを読み取ります: ① パスを指定します; ② 関数 open はファイルを表すオブジェクトを返し、そのオブジェクトは f に格納されます; アクセスする必要がない場合、キーワード with はファイルを自動的に閉じます。③読み取った内容を文字列として変数に格納します。
txt ドキュメントを 1 行ずつ読み取ると、ファイル全体を読み取る場合よりも行間隔がはるかに広いことがわかります。これは、各行の最後に目に見えない改行文字があり、print ステートメントでも改行文字が追加されるためです。これらの余分な空白行を削除するには、print ステートメントで line.rstrip() を使用します。
system キーワード with を使用する場合、open() によって返されるテキスト オブジェクトは with コード ブロック内でのみ使用されます。with ブロックの外側でファイルの内容にアクセスしたい場合は、with ブロック内のリストにファイル行を格納し、with ブロックの外側でそのリストを使用できます。
テキスト ファイルを読み取るとき、Python はそのファイル内のすべてのテキストを文字列として解釈します。数値を読み取り、それを数値として使用したい場合は、関数 int() を使用して整数に変換する必要があります。または、float() を使用して float に変換します。
a=c[0:3,:] 最初の 0,1,2 行
b = c[0,2:4] 列の添字も 0 から始まるため、行 0 の 2 列目と 3 列目には 4 列目は含まれません。
d = c[2:4,2:4] は、中央の 2 ~ 4 行と 2 ~ 4 列を取得します。
e = c[0,:] は行 0 のすべてのデータを取得します
f = c[:,1] は列 1 のすべてのデータを取得します
g = c[::2,::2] の後に 2 つのコロンが続く場合は、ステップ サイズが 2 であることを示します
Pythonの二次元リスト: 二次元リストとは、他のリストをリストの要素として1つのリストに入れることで、リストの入れ子になります。2次元リストは、複数の 1 次元リストで構成される多次元配列であり、各リストには任意の数の要素を含めることができます。バイナリリストは 2 つの要素で構成される 1 次元配列であり、各要素は任意の型の値にすることができます。
2 つの角括弧が続くリストの意味は、バイナリ リストli [i] ['key']です。 li[i] はアクセス リスト li の要素であり、li の要素はすべて辞書であり、辞書名です。キーを通じて値にアクセスするために使用されます。|| これはバイナリ リストです。リストには、キーワードまたはインデックスを通じてアクセスできる他のデータ構造があります。li_1.append(li[i]["key"]) #for ループを通じて、リストの埋め込み辞書のすべての値を li_1 リストに追加します。|| li[index] のインデックスはリスト内の埋め込み辞書の数を表し、次の li['key'] はキーに対応する値を取得するためのリスト内の埋め込み辞書の数を表します。
.extend() メソッドは、別のシーケンスの複数の値をリストの最後に一度に追加するために使用されます (元のリストを新しいリストで拡張します)。.append() メソッドは、新しいオブジェクトをリストに追加するために使用されます。リストの最後。違い: .extend() メソッドは別のシーケンスから複数の値を一度に追加できますが、.append() メソッドは 1 つの値しか追加できません。
パラメータの書き込み: 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 注釈ツールでは、円にラベルを付けるときに 2 つの点を取得します。最初の点は円の中心を表し、2 番目の点は円の半径を表します。したがって、キャリブレーションシーケンスが決定されたjsonドキュメントについては、txtに変換した後、2つの円の最初の座標を保持するだけで済みます(点の検出は、これから行う実験の最初のステップです) [書く前に判断を追加します] 】
# 将坐标写入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')
ただし、画像内にマークされたランドマークの順序は固定されていないため、最初に取得した10点の座標は固定されません ラベラーの順序が異なるため、マークされた点の座標位置は同じになりますtxtドキュメントが必要です。
バージョン番号、空のフラグ ディクショナリ、およびシェイプ リストが含まれる JSON ファイル。シェイプ リストには複数のシェイプ ディクショナリが含まれます。各シェイプ ディクショナリには、ラベル、ポイント リスト、group_id、shape_type、およびフラグ ディクショナリが含まれます。
JSON ファイルからシェイプ キーに対応する値、つまり複数のシェイプ ディクショナリを含むシェイプ リストを取得します。
形状リストから取得したポイント値を保存するために、長さ 17 の空のリストを作成します。
【最終コード】
# -*- 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])
以前のキャリブレーション ポイントに基づいてエラーは報告されませんでしたが、ラベルの合計数をチェックすると、3 つのポイントが欠落していることが判明しました。countPoint と countCircle のカウントには問題はありませんでした。=> 最終的に、45.json のアノテーションには繰り返しタグがあることが判明しました。そのため、最初のタグの選択は依然として非常に重要であり、その後の読み取りとタグの並べ替えに影響します。(背表紙の位置決定方法はなく、純粋なラベルソート)