본문 바로가기
DataScience/Python

파이썬 원본 폴더에 이미지 파일 여러개를 일정비율로 나눠서, 랜덤으로 파일의 순서를 바꾼다음, 새로운폴더를 생성하여 넣는 방법

by leopard4 2022. 12. 30.

환경 : 리눅스 ( 윈도우도 됨)

 

PetImages 라는 원본폴더 안에

Cat 폴더 안에는 고양이 사진이 12500장

Dog 폴더 안에는 개사진이 12500장 있다고 해보자

 

새로운 cats-v-dogs 라는 폴더를 생성하고

그안에 testing 폴더, training 폴더를 생성

testing 안에 cats, dogs  

training 안에 cats, dogs  

폴더를 생성한다음

원본에 있는 사진을 일정 비율로 나눠서

(예를들면 9대1로 나누면 11250장, 1250장)

testing 안에 cats 폴더에 1250장

testing 안에 dogs 폴더에 1250장

training 안에 cats 폴더에 11250장

training 안에 dogs 폴더에 11250장

이렇게 옮길것이다.

 

1.필요한 라이브러리를 임포트하고,

import os

import random

from shutil import copyfile

 

2. 디렉토리를 만든다.

# /tmp 디렉토리 안에다, 학습을 위한 데이터를 분류하기 위해
# cats-v-dogs 디렉토리를 만들고, 
# 그 아래 training 과 testing 디렉토리 만든 후
# 각각 디렉토리 안에  cats 와 dogs 디렉토리를 만든다.
try:
    #YOUR CODE GOES HERE
   os.mkdir('/tmp/cats-v-dogs')
   os.mkdir('/tmp/cats-v-dogs/training')
   os.mkdir('/tmp/cats-v-dogs/testing')
   os.mkdir('/tmp/cats-v-dogs/training/cats')
   os.mkdir('/tmp/cats-v-dogs/training/dogs')
   os.mkdir('/tmp/cats-v-dogs/testing/cats')
   os.mkdir('/tmp/cats-v-dogs/testing/dogs')
    
except OSError:
    pass

3. 라이브러리를 임포트한 이유 (대충이런이유)

random.sample('경로', 1 ) # 경로안에 랜덤으로 한개만 가져옴
 
[out] ['5122.jpg']
 

shuffled_files = random.sample('경로', 12500# 경로안에 섞어서 전체(12500장)를 가져옴

copyfile( 원본경로, 이동할경로) 복사해라 (원본경로에서 , 이동할경로로) 
os.path.getsize( '경로' )   # 파일의 사이즈를 확인하는 함수 

4. 종합

# 경로를 변수로 생성
CAT_SOURCE_DIR = "/tmp/PetImages/Cat/"
TRAINING_CATS_DIR = "/tmp/cats-v-dogs/training/cats/"
TESTING_CATS_DIR = "/tmp/cats-v-dogs/testing/cats/"
DOG_SOURCE_DIR = "/tmp/PetImages/Dog/"
TRAINING_DOGS_DIR = "/tmp/cats-v-dogs/training/dogs/"
TESTING_DOGS_DIR = "/tmp/cats-v-dogs/testing/dogs/"

 

# 함수구현
def split_data(SOURCE, TRAINING, TESTING, SPLIT_SIZE):

  # 원본 경로의 파일명들을 리스트로 모두 가져온다.
  file_names = os.listdir( SOURCE )
  
  # 가져온 파일명을 잘 섞어준다.
  shuffled_files = random.sample( file_names, len(file_names) ) 
  
  # 학습용과 테스트용 분리를 위해 인덱스를 구한다.
  index = int(len(shuffled_files) * SPLIT_SIZE )
  
  # 섞인 파일명 리스트에서, 해당 인덱스 만큼 잘라서, 학습용과 테스트용 파일명 분리
  training_images = shuffled_files[0 : index]
  test_images = shuffled_files[index : ]

  # 학습용과 테스트용으로 각각 해당 폴더로, 파일을 카피한다.
  for file_name in training_images :
    if os.path.getsize( SOURCE + file_name ) > 0 :   # /tmp/PetImages/Cat/?????.jpg # getsize == 파일의 사이즈를 확인하는 함수 # 사이즈가 0 인것은 이상한 파일이다.
      copyfile( SOURCE + file_name, TRAINING + file_name)  # copyfile( src == 원본소스경로, dsc == 복사할경로 )

  for file_name in test_images :
    if os.path.getsize( SOURCE +  file_name ) > 0 :
      copyfile( SOURCE + file_name, TESTING + file_name )
  # for문 해석 test_images(파일의 리스트) 안에 한개의 파일명(jpg)을 가져와서 
  #   if (만약) 파일사이즈가 0 보다 크면 :
  #     복사해라 (원본경로에서 , 이동할경로로) 
# 잘되는지 테스트
split_size = .9
split_data(CAT_SOURCE_DIR, TRAINING_CATS_DIR, TESTING_CATS_DIR, split_size)
split_data(DOG_SOURCE_DIR, TRAINING_DOGS_DIR, TESTING_DOGS_DIR, split_size)
 

 

print(len(os.listdir('/tmp/cats-v-dogs/training/cats/')))
print(len(os.listdir('/tmp/cats-v-dogs/training/dogs/')))
print(len(os.listdir('/tmp/cats-v-dogs/testing/cats/')))
print(len(os.listdir('/tmp/cats-v-dogs/testing/dogs/')))


# Expected output:
# 11250
# 11250
# 1250
# 1250

잘된다.