JSON(JavaScript Object Notation)은 경량의 데이터 교환 형식 입니다.
JSON은 사람이 읽고 쓰기에 용이하고, 기계가 분석하고 생성 하기도 쉬워 많이 사용됩니다.
특히 웹에서 데이터를 주고받을 때 많이 사용되며, 대부분의 프로그래밍 언어에서 JSON 형식을 다룰 수 있습니다.
JSON은 키-값 쌍으로 이루어진 데이터 오브젝트를 저장합니다. 키(key)는 문자열이며, 값(value)은 문자열, 숫자, 불리언, 배열, 객체 등이 될 수 있습니다. 이러한 데이터 오브젝트들은 중첩될 수 있어 복잡한 데이터도 표현할 수 있습니다.
import json
# json 파일을 가져와야합니다.
json_data_path ="./data/instances_default.json"
with open(json_data_path, 'r', encoding="utf-8") as j : # 'r' read
json_data = json.load(j)
print(f"json type : {type(json_data)}")
print("json_data : ", json_data ) # 키, 밸류로 반환

다차원 딕셔너리 형태라 원하는 정보를 위해선 한차원 더 들어가야합니다.
# 변수 선언
categories_info = json_data['categories']
# [{'id': 1, 'name': 'cat', 'supercategory': ''}, {'id': 2, 'name': 'dog', 'supercategory': ''}]
images_info = json_data['images']
# [{'id': 1, 'width': 640, 'height': 480, 'file_name': '01.jpg', 'license': 0, 'flickr_url': '', 'coco_url': '', 'date_captured': 0}]
위의 정보를 이용하여 이미지 시각화 실습
import json
import os
import cv2
import matplotlib.pylab as plt
# json_path 경로 지정
json_path = "./data/instances_default.json"
# json 읽기
with open(json_path, 'r', encoding='utf-8') as j : # 'r' : read
json_data = json.load(j)
category_info = json_data['categories']
images_info = json_data['images']
annotations_info = json_data['annotations']
# 라벨 딕셔너리 선언
label_dict = {1: "cat", 2:"dog"} # 0 은 배경임
for image_json in images_info :
print(image_json)
# {'id': 1, 'width': 640, 'height': 480, 'file_name': '01.jpg', 'license': 0, 'flickr_url': '', 'coco_url': '', 'date_captured': 0}
file_name = image_json['file_name']
image_path = os.path.join("./data/", file_name)
image_id = image_json['id']
print(image_path)
# ./data/01.jpg
# image read
image = cv2.imread(image_path)
# iamge BGR -> RGB
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# bbox info
for anno_json in annotations_info :
if image_id == anno_json['image_id'] :
bbox = anno_json['bbox']
# 좌표 변수에 박스 좌표 저장 (int 형 변환 이유 : cv2.rectangle 좌표 값은 int 형태만 가능)
x = int(bbox[0])
y = int(bbox[1])
w = int(bbox[2])
h = int(bbox[3])
# 박스 좌표 확인
print("bbox 좌표 >> " , x, y, w, h)
# bbox 좌표 >> 468 92 171 248
# bbox 좌표 >> 3 183 200 214
# 박스 그리기
cv2.rectangle(image, (x,y), (x+w, y+h), (0,255,0),2)
# 라벨 표시
category_id = anno_json['category_id']
label_name = label_dict[category_id]
print(label_name)
# dog
# cat
image = cv2.putText(image, label_name, (x, y-10), # 위에 글자두려고 -10
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2, cv2.LINE_AA)
plt.imshow(image)
plt.show()

json format -> Yolo format 으로 변경하고 텍스트 파일로 저장하기
import json
import os
import cv2
import matplotlib.pylab as plt
# json_path 경로 지정
json_path = "./data/instances_default.json"
# json 읽기
with open(json_path, 'r', encoding='utf-8') as j :
json_data = json.load(j)
category_info = json_data['categories']
images_info = json_data['images']
annotations_info = json_data['annotations']
# 라벨 딕셔너리 선언
# 0 -> cat , 1 -> dog
label_dict = {1: 0, 2: 1}
for image_json in images_info :
print(image_json)
file_name = image_json['file_name']
image_path = os.path.join("./data/", file_name)
image_id = image_json['id']
print(image_path)
print("file name ", file_name)
# image read
image = cv2.imread(image_path)
# iamge BGR -> RGB
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# image size
img_height, img_width, img_channel = image.shape
# bbox info
for anno_json in annotations_info :
if image_id == anno_json['image_id'] :
bbox = anno_json['bbox']
# 좌표 변수에 박스 좌표 저장 (int 형 변환 이유 : cv2.rectangle 좌표 값은 int 형태만 가능)
x = int(bbox[0])
y = int(bbox[1])
w = int(bbox[2])
h = int(bbox[3])
# 박스 그리기
cv2.rectangle(image, (x,y), (x+w, y+h), (0,255,0),2)
# 라벨 표시
category_id = anno_json['category_id']
label_number = label_dict[category_id]
# xywh -> center_x, center_y, w, h 변경 하기
center_x = ((2*x + w)/(2*img_width))
center_y = ((2*y + h)/(2*img_height))
yolo_w = w/img_width
yolo_h = h/img_height
print("yolo 좌표 변경 값 >> ",label_number,center_x, center_y, yolo_w, yolo_h)
# 이미지 명과 라벨 파일 명이 동일해야합니다.
# 위에 file_name 경우는 01.jpg 우리가 필요한것은 01 이라는 이름 입니다.
#file_name_tmep = os.path.splitext(file_name)[0]
file_name_temp = file_name.replace(".jpg", "")
# 텍스트 파일 쓰기
with open(f"{file_name_temp}.txt", "a") as f: # "a" 는 덮어쓰기 말고 새로만듬
f.write(f"{label_number} {center_x} {center_y} {yolo_w} {yolo_h} \n")
'AI > [Preprocessing]' 카테고리의 다른 글
[전처리] 이미지 비율에 맞게 정사각형 만들기 (0) | 2023.06.15 |
---|---|
[전처리] 가져온 사진 정보 받기 (feat, xml) (1) | 2023.06.15 |
[전처리] 폴더에 있는 사진 가져오기 (0) | 2023.06.14 |
[전처리] 범주형 데이터 전처리 (0) | 2023.06.06 |
[전처리] 손글씨 데이터 PCA 적용예시 (1) | 2023.06.06 |