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")

+ Recent posts