KT 에이블스쿨 37일차(1)

박기범·2023년 3월 23일
0

에이블스쿨

목록 보기
43/95
post-custom-banner

오늘은 새로운 주제로 CNN 프로젝트를 시작했습니다.



문제 정의

오늘의 주제는 동전과 지폐 단위를 알아내는 Detection 모델을 만드는 것입니다. 오늘 포스팅은 전처리까지만 하고 내일 모델링을 진행하면 내일 포스팅에 모델링까지 작성하도록 하겠습니다.



환경설정

이제는 코랩에서 구글드라이브 연결이 매우 익숙해졌습니다.

	from google.colab import drive
    drive.mount('/content/drive/')

다음으로는 압축파일을 해제해주었습니다.

	import zipfile
money_data = zipfile.ZipFile( '/content/drive/MyDrive/경로/money_dataset.zip' )
money_data.extractall('/content/drive/MyDrive/경로/Dataset/')




전처리 시작


	import os
    import shutil

    val_path = '/content/drive/MyDrive/경로/Dataset/'
    folders = ['10', '50', '100', '500', '1000', '5000', '10000', '50000']

    destination_path = '/content/drive/MyDrive/경로/Dataset/images/train/'

    for folder in folders:
        folder_path = os.path.join(val_path, folder)
        for file_name in os.listdir(folder_path):
            if file_name.endswith('.jpg'):
                file_path = os.path.join(folder_path, file_name)
                shutil.move(file_path, destination_path)

해당 코드를 통해서 이미지 데이터를 모두 입력한 경로로 이동하는 코드입니다. 일단 저는 먼저 train데이터 셋으로 만들고 거기서 랜덤으로 또 val데이터 셋으로 보낼 예정입니다.

다음으로 .json 파일을 마저 옮겨주겠습니다.

    import os
    import shutil

    val_path = '/content/drive/MyDrive/경로/Dataset/'
    folders = ['10', '50', '100', '500', '1000', '5000', '10000', '50000']

    destination_path = '/content/drive/MyDrive/경로/Dataset/labels/train/'

    for folder in folders:
        folder_path = os.path.join(val_path, folder)
        for file_name in os.listdir(folder_path):
            if file_name.endswith('.json'):
                file_path = os.path.join(folder_path, file_name)
                shutil.move(file_path, destination_path)

다음으로 이제 train 데이터 셋중에서 랜덤하게 20%를 val 데이터 셋으로 이동해주겠습니다.

	import os
    import random
    import shutil

    # 이동할 파일 비율 설정
    split_ratio = 0.2

    # train 폴더 경로
    train_path = '/content/drive/MyDrive/경로/Dataset/images/train/'

    # val 폴더 경로
    val_path = '/content/drive/MyDrive/경로/Dataset/images/val/'

    # train 폴더 안에 있는 파일 리스트
    file_list = os.listdir(train_path)

    # 이동할 파일 개수
    num_files = int(len(file_list) * split_ratio)

    # 랜덤하게 파일 선택
    move_files = random.sample(file_list, num_files)

    # 선택된 파일 이동
    for file_name in move_files:
        src_path = os.path.join(train_path, file_name)
        dst_path = os.path.join(val_path, file_name)
        shutil.move(src_path, dst_path)

마찬가지로 json파일도 진행해줍니다.

	import os
    import random
    import shutil

    # 이동할 파일 비율 설정
    split_ratio = 0.2

    # train 폴더 경로
    train_path = '/content/drive/MyDrive/경로/Dataset/labels/train/'

    # val 폴더 경로
    val_path = '/content/drive/MyDrive/경로/Dataset/labels/val/'

    # train 폴더 안에 있는 파일 리스트
    file_list = os.listdir(train_path)

    # 이동할 파일 개수
    num_files = int(len(file_list) * split_ratio)

    # 랜덤하게 파일 선택
    move_files = random.sample(file_list, num_files)

    # 선택된 파일 이동
    for file_name in move_files:
        src_path = os.path.join(train_path, file_name)
        dst_path = os.path.join(val_path, file_name)
        shutil.move(src_path, dst_path)

이제 조건에 따라 json파일을 파싱해서 필요한 정보인 라벨과 위치정보만 저장한 .txt파일로 변환하여 저장해주도록 하겠습니다.

    # txt 파일로 변환할 json 파일 경로
    val_path = '/content/drive/MyDrive/경로/Dataset/labels/train/'

    # 클래스 매핑
    class_mapping = {
        'Ten_front': 0,
        'Ten_back': 0,
        'Fifty_front': 1,
        'Fifty_back': 1,
        'Hundred_front': 2,
        'Hundred_back': 2,
        'Five_Hundred_front': 3,
        'Five_Hundred_back': 3,
        'Thousand_front': 4,
        'Thousand_back': 4,
        'Five_Thousand_front': 5,
        'Five_Thousand_back': 5,
        'Ten_Thousand_front': 6,
        'Ten_Thousand_back': 6,
        'Fifty_Thousand_front': 7,
        'Fifty_Thousand_back': 7
    }

    # 각 json 파일에서 정보 추출하여 txt 파일 생성
    for json_file in os.listdir(val_path):
        # .json 파일인 경우에만 처리
        if json_file.endswith('.json'):
            # json 파일 불러오기
            with open(os.path.join(val_path, json_file), 'r') as f:
                data = json.load(f)

            # YOLO label 형식으로 변환하여 저장할 리스트
            labels_yolo = []

            # 각 객체에 대한 정보 추출
            for obj in data['shapes']:

                shape_type = obj['shape_type']
                label = obj['label']
                x1, y1 = obj['points'][0]
                x2, y2 = obj['points'][1]
                width = data['imageWidth']
                height = data['imageHeight']

                # 클래스명 매핑 (앞뒤면 구분 없애기)
                label = class_mapping[label]

                # 위치 정보를 YOLO 형식으로 변환
                x_center = (((x1 + x2) / 2) * 0.2)/(width*0.2)
                y_center = (((y1 + y2) / 2) * 0.2) /(height*0.2)
                width_norm = ((x2 - x1) * 0.2) /(width*0.2)
                height_norm = ((y2 - y1) * 0.2) / (height*0.2)

                # YOLO label 형식에 맞게 리스트에 추가
                labels_yolo.append([label, x_center, y_center, width_norm, height_norm])

            # txt 파일로 저장
            txt_file = json_file.split('.')[0] + '.txt'
            with open(os.path.join(val_path, txt_file), 'w') as f:
                for label in labels_yolo:
                    line = ' '.join([str(l) for l in label])
                    f.write(line + '\n')

마지막으로 yaml파일의 코드를 작성했습니다.

	path: /content/drive/MyDrive/경로/Dataset/
    train: images/train/
    val: images/val/

    nc: 8

    names:
      0: '10'
      1: '50'
      2: '100'
      3: '500'
      4: '1000'
      5: '5000'
      6: '10000'
      7: '50000'

내일 마저 모델링을 진행하겠습니다.







모델링이 문제가 아니라...전처리가 더 문제였다..라고 느낀 하루였습니다!!




※공부하고 있어 다소 틀린점이 있을 수 있습니다. 언제든지 말해주시면 수정하도록 하겠습니다.
※용어에 대해 조금 공부 더 해서 수정하겠습니다.

profile
개발자가 되기 위한 한걸음
post-custom-banner

0개의 댓글