로보플로우는 오픈이라서 내 사진을 학습시키기가 애매할때가 있다.
내 얼굴 사진 2500 장을 학습시켜 나를 알아보는지? 모델링을 해보자
일단 웹캠으로 내 얼굴을 2500장 찍는 코드는 다음과 같다
###############################################################
## 해당 파일은 로컬 cam을 이용하여 본인의 이미지를 촬영하고 저장합니다.
###############################################################
import os
import cv2
## 이미지를 저장할 폴더 경로
folder_path = './my_face_temp'
## 이미지 저장 폴더가 없다면 폴더 생성
if not os.path.exists(folder_path) :
os.makedirs(folder_path)
print('my_face 폴더를 생성합니다.')
## 웹캠으로 얼굴 사진을 찍어 저장하는 함수
def capture_owner_images(num_images=2500) : ## num_images에 숫자를 입력한만큼 이미지 저장
## 0은 기본 웹캠
cap = cv2.VideoCapture(0)
## haarcascade 알고리즘으로 얼굴 탐지
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
## 위에서 지정한 수만큼 촬영 및 저장하는 반복문
count = 0
while count < num_images :
_, frame = cap.read()
frame = cv2.flip(frame, 1)
## haarcascade 알고리즘은 흑백 이미지의 명암 차이로 탐지를 하는 것이기에 흑백으로 변환
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
## 변환된 프레임에서 얼굴 탐지 시도
faces = face_cascade.detectMultiScale(gray, 1.1, 4)
## 탐지된 얼굴에서 좌표를 가져오는 반복문
for (x, y, w, h) in faces :
## 프레임에서 얼굴 영역만 가져온다
face = frame[y:y+h, x:x+w]
## 탐지한 얼굴 영역 사이즈 변환 : 괄호를 채우면 됩니다.
resized_face = cv2.resize(face, (512 , 512) )
## 파일 이름 설정 및 저장
face_file = f"./my_face_temp/temp_{count}.jpg"
cv2.imwrite(face_file, resized_face)
count += 1
## 변환된 얼굴 이미지 출력하여 확인
cv2.imshow('Captured Face', resized_face)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
capture_owner_images()
print('저장 완료')
(혹시나 해서.. 윈도우 기준이다)
이코드를 돌리면 자동으로 사진이 찍히고 내가 설정한 경로에 저장된다.
2500장을 학습시킬때 로컬에서 돌리면 곤란하니깐 코랩에서 돌릴거다
구글 드라이브에 파일을 만들고 (내 코드에선 파일명: project) 내 사진과 다른사람들 사진 들을 zip파일로 올린다
코랩에서 실행시킬거기땨문에 꼭 zip으로 올리는게 좋다 아니면 내 컴퓨터에서 처리량이 많이지기 때문!!
추가로 다른사람들 사진은 2500장보다 많게 올렸다
#구글드라이브 연결
from google.colab import drive
drive.mount('/content/drive')
path = '/content/drive/MyDrive/project'
#라이브러리 로딩및 설치 (YOLO - cls 이용할거다)
!pip install ultralytics
기본준비를 마치고,
내가 project 폴더에 넣어두었던 이미지 데이터셋을 불러온다
import os
import zipfile
data_myFace = os.path.join(path, 'my_face_temp.zip')
data_myFace
## Colab에서 생성할 본인 얼굴 이미지 데이터 폴더의 경로
extract_folder = '/content/my_face'
## 위의 경로에 폴더가 없을 때 폴더 생성
if not os.path.exists(extract_folder) :
os.mkdir(extract_folder)
## 위의 경로에 압축 해제
## data_myFace 압축 파일을 읽기 모드로 사용할 건데, 그 이름은 zip_ref
with zipfile.ZipFile(data_myFace, 'r') as zip_ref :
## zip_ref에 있는 모든 파일을 리스트화
file_list = zip_ref.namelist()
# print(file_list)
## 모든 파일 리스트 반복문
for f in file_list :
## 만약 파일명이 /로 끝나지 않으면서, .jpg로 끝난다면
if not f.endswith('/') and f.lower().endswith('.jpg') :
## file_name이란 변수로 사용하겠다.
file_name = os.path.basename(f)
# print(file_name)
## 만약 파일명이 ._로 시작하지 않는다면 (Mac OS에서의 숨김 파일 방지용)
if not file_name.startswith('._') :
## d_path 변수에 폴더명과 file_name을 합친 문자열을 사용하겠다.
d_path = os.path.join(extract_folder, file_name)
# print(d_path)
## 불러와서 쓰는 과정 : 이 과정에서 위의 폴더에 파일들이 생성됨.
with zip_ref.open(f) as source, open(d_path, 'wb') as target :
target.write( source.read() )
## 생성된 본인 얼굴 이미지 데이터 폴더 안의 이미지 수
len(os.listdir(extract_folder) )
내 얼굴말고 다른얼굴 이미지도 불러온다
data_other = os.path.join(path, 'lfw-deepfunneled.zip')
data_other
## Colab에 생성할 다른 얼굴 폴더 경로
extract_folder = '/content/other_face'
## 위의 경로에 폴더가 없을 때 생성
if not os.path.exists(extract_folder) :
os.makedirs(extract_folder)
## 위의 경로에 압축을 해제
with zipfile.ZipFile(data_other, 'r') as zip_ref :
file_list = zip_ref.namelist()
for f in file_list :
if not f.endswith('/') and f.lower().endswith('.jpg') :
file_name = os.path.basename(f)
if not file_name.startswith('._') :
d_path = os.path.join(extract_folder, file_name)
with zip_ref.open(f) as source, open(d_path, 'wb') as target :
target.write(source.read())
## 생성된 다른 사람 얼굴 이미지 데이터 폴더 안의 이미지 수
len(os.listdir(extract_folder) )
데이터 전처리
-
- YOLO-cls 모델이 요구하는 폴더 구조를 만듭니다.
- Datasets라는 폴더를 생성합니다.
- Training set, Validation set이 들어갈 폴더를 생성합니다.
- 각 데이터셋 폴더에 분류할 클래스의 이름을 가진 폴더를 생성합니다.
- 폴더 구조에 맞게 데이터를 분배합니다.
- YOLO-cls 모델이 요구하는 폴더 구조를 만듭니다.
이 과정을 수행할거다
import os
import glob
import random
import shutil
import numpy as np
## 각 데이터셋 길이 비교
len(os.listdir('/content/my_face')) , len(os.listdir('/content/other_face'))
## 폴더 생성
datasets_path = '/content/Datasets'
## 원본 폴더 경로들
source_folders = {
'my_face': '/content/my_face',
'other_face': '/content/other_face'
}
## 타겟 폴더 경로들
target_folders = {
'train': {'my_face': '/content/Datasets/train/my_face',
'other_face': '/content/Datasets/train/other_face',
},
'val': {'my_face': '/content/Datasets/val/my_face',
'other_face': '/content/Datasets/val/other_face',
},
}
## 폴더 생성
if not os.path.exists(datasets_path) :
os.mkdir(datasets_path)
## 하위 폴더 생성
for folder in target_folders :
temp1 = os.path.join(datasets_path , folder)
if not os.path.exists( temp1 ) :
os.mkdir( temp1 )
for folder2 in source_folders.keys() :
temp2 = os.path.join(temp1, folder2)
if not os.path.exists( temp2 ) :
os.mkdir( temp2 )
참고로 이번에 yaml 파일은 필요없다
각 폴더에 이미지 데이터 옮기기
# 스플릿 비율
split_size = 0.8
## 각 카테고리(my_face, other_face)에 대해 처리
for category, source_folder in source_folders.items():
## 원본 폴더에서 모든 파일 리스트 가져오기
img_list = sorted(glob.glob(os.path.join(source_folder, '*')))
## 총 파일 개수 계산
total_imgs = len(img_list)
tr_val_split = int(total_imgs * split_size)
## train, validation로 나누기
tr_img = img_list[ : tr_val_split]
val_img = img_list[tr_val_split : ]
## 각각의 이미지들을 타겟 폴더로 이동
for img_path in tr_img :
dst_path = os.path.join(target_folders['train'][category], os.path.basename(img_path))
shutil.move(img_path , dst_path)
for img_path in val_img :
dst_path = os.path.join(target_folders['val'][category], os.path.basename(img_path))
shutil.move(img_path , dst_path)
print(f'{category} images moved to train, validation sets')
사전 학습된 UltraLytics YOLO-cls 모델에 Transfer Learning하기
import os
os.environ['WANDB_MODE'] = 'disabled'
from ultralytics import YOLO, settings
#세부 모델로 n, s, m, l, x가 있습니다. n가 가장 빠르고, x가 가장 연산량이 많습니다.
settings['datasets_dir'] = '/content/'
settings
model = YOLO('yolo11n-cls.pt')
#학습
results_tr = model.train(model='/content/yolo11n-cls.pt',
data='/content/Datasets',
epochs=10,
patience=4,
)
#추론
results = model.predict()
#모델저장
model_check = YOLO()
model_check
,pt 형태로 모델이 코랩에 저장이 되면, 로컬에 다운받아 사용하면 된다!!