이미지 증식 테스트
사용할 라이브러리
''' 이미지 증식에 사용되는 라이브러리 '''
from keras.preprocessing.image import ImageDataGenerator
''' numpy 배열을 이미지로 변환하는 라이브러리 '''
from keras.preprocessing.image import array_to_img
''' 이미지를 numpy 배열로 변환하는 라이브러리 '''
from keras.preprocessing.image import img_to_array
''' 이미지를 읽어들이는 라이브러리 '''
from keras.preprocessing.image import load_img
''' 시각화 '''
import matplotlib.pyplot as plt
이미지 증식 객체 생성하기
📍 이미지 증식을 하는 이유?
- 이미지를 이용하여 모델 훈련 시 데이터 확보가 어려운 경우 수행
- 기존 이미지 훈련모델의 성능이 낮은 경우에 데이터를 증가 시키고자 할 때 사용
- 이미지 증식은 하나의 원본 이미지 형태를 랜덤하게 변형시켜서 많은 양의 이미지를 생성 가능
- 이미지 증식개체 생성하기
imgGen = ImageDataGenerator( ### 이미지 데이터를 0과 1사이의 값으로 정규화하기 rescale=1./255, ### 이미지 회전시키기, 0 ~ 90 사이의 랜덤하게 회전 rotation_range=15, ### 수평이동 시키기, 0 ~ 1 사이의 비율에 따라 랜덤하게 이동 # - 0.1=10%, 10%의 비율로 좌/우 랜덤하게 이동 width_shift_range=0.1, ### 수직이동 시키기 height_shift_range=0.1, ### 이미지 형태 변형(반시계방향) shear_range=0.5, ### 이미지 확대/축소(0.8 ~ 2.0 사이의 범위 값으로 랜덤하게 확대/축소) zoom_range=[0.8, 2.0], ### 수평방향으로 뒤집기 여부 horizontal_flip=True, ### 수직방향으로 뒤집기 여부 vertical_flip=True, ### 이미지 변형 시 발생하는 빈 공간의 픽셀값 처리 방법 지정 # - nearset : 가까운 곳의 픽셀값으로 채우기(기본값, default, 생략가능, 주로 사용 됨) # - reflect : 빈공간 만큼의 영역을 근처 공간의 반전된 픽셀값으로 채우기 # - warp : 빈공간을 이동하면서 잘려나간 이미지로 채우기 # - constant : 빈공간을 검정 또는 흰색으로 채우기 fill_mode="nearest" )
- 원본 이미지 불러오기
사용 이미지 ↓ (출처 : 말티즈 장군이)img = load_img("./new_img/img_sample.jpg") img
- 이미지를 데이터화 시키기
- 이미지를 array 배열 데이터로 변환하기
- 3차원 데이터로 반환됨
- (높이, 너비, 채널)
img_array = img_to_array(img) print(img_array.shape) img_array
- 이미지 증식을 위한 데이터는 4차원 데이터이므로 4차원으로 변환하기
img_array = img_array.reshape((1,) + img_array.shape) print(img_array.shape)
이미지 증식하기
### 반복을 종료하기 위한 coount값으로 사용
i = 0
### 생성할 이미지 갯수
cnt = 100
### 이미지를 반복해서 생성
# - flow() : imgGen객체를 이용해서 랜덤하게 만들어진 이미지를 저장시키는 함수
# - save_to_dir : 저장할 폴더 위치
# - save_prefix : 저장할 파일명에 사용할 이니셜, 이니셜 뒤에 자동으로 이름이 부여됨
# - save_format : 저장할 파일의 포멧, 파일명 뒤에 확장자 정의
for new_img in imgGen.flow(img_array,
save_to_dir="./new_img/new",
save_prefix="train",
save_format="png") :
''' 생성할 이미지 갯수까지만 반복 시키고 반복을 종료시키기 '''
if i > cnt :
break
''' 생성된 이미지 출력하기 '''
plt.imshow(new_img[0])
''' x, y축 그래프 숨기기 '''
plt.axis('off')
'''
반복하면서 이미지를 보여주는 경우에는 show()를 사용해야 한다.
- 그렇지 않으면 1개의 이미지만 보이게 된다.
- show() 이미지를 보여주고, 자원을 반환하는 역할도 같이 수행된다.
- 자원이 반환되야 다음 이미지를 plt를 통해서 사용가능하다.
'''
plt.show()
''' 반복을 위한 count값 증가 '''
i += 1
print(">>>>>>>>>> 이미지 증식 종료 <<<<<<<<<<<<")

사람이미지 증식 및 4차원 독립변수와 종속변수(라벨링) 생성하기
사용할 라이브러리
import os
import numpy as np
import pandas as pd
''' OpenCV 라이브러리 '''
import cv2
''' 이미지 증식 라이브러리 '''
from tensorflow.keras.preprocessing.image import ImageDataGenerator
''' 이미지를 numpy array(배열)로 변환하는 라이브러리 '''
from keras.preprocessing.image import img_to_array
특정 폴더 내에 모든 원본 이미지를 읽어들이는 함수 정의
특정 원본 이미지 폴더 내에 모든 이미지 파일을 읽어들여서, 이미지 픽셀 데이터로 변환해서 리턴하는 함수 정의
def load_images(directory) :
''' 긱 이미지별 변환 데이터를 저장할 리스트 변수 '''
images = []
''' 특정 디렉토리의 모든 파일 읽어들이기 '''
for filename in os.listdir(directory) :
''' 특정 확장자를 가지는 파일만 읽어들이기 '''
if filename.endswith((".jpg", ".jpeg", ".png")) :
''' 파일명 추출 '''
img_path = os.path.join(directory, filename)
''' 이미지를 3차원 데이터로 변환하기 '''
img = cv2.imread(img_path)
''' 이미지 데이터의 픽셀 크기를 너비 170, 높이 175로 통일시키기(정규화) '''
img = cv2.resize(img, (170, 175))
''' 변환된 이미지 데이터를 리스트 변수에 담기 '''
images.append(img)
''' numpy 배열로 변환하여 리턴 '''
return np.array(images)
읽어들인 모든 원본 이미지 각각에 대해서 이미지 증식 및 종속변수(라벨) 정의 함수
'''
- images : 원본 전체에 대한 각 이미지 데이터
- output_directory : 증식한 이미지를 저장할 폴더 위치
- target_filename : 종속변수 데이터를 저장할 (폴더+파일명)
'''
def create_images(images, output_directory, target_filename) :
### 종속 변수 데이터를 담을 리스트 변수
target = []
### 이미지 10개(원본 이미지 10개에 대)에 대한 라벨링 기준
# - 1은 위험인자, 0은 비위험인자
target_list = [1, 0, 1, 0, 1, 1, 0, 1, 1, 0]
############### 이미지 증식 객체 생성하기 ###############
datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=15,
width_shift_range=0.1,
height_shift_range=0.1,
shear_range=0.5,
zoom_range=[0.8, 2.0],
horizontal_flip=True,
vertical_flip=True,
fill_mode="nearest"
)
############### 이미지 증식 시키기 ###############
# - i : images의 인덱스 번소
# - img : 각 인덱스별 이미지 데이터
for i, img in enumerate(images) :
print(f"------------------ [{i + 1} /{len(images)}] 번째 증식 중 ------------------")
### 3차원 이미지 데이터를 4차원으로 변환하기
img = img.reshape((1,) + img.shape)
### 증식된 이미지를 저장할 파일명 정의
save_prefix = "train_img_" + str(i)
### 각 이미지 별로 생성(증식)할 이미지의 갯수 정의
create_img_cnt = 20
############### 이미지 증식 및 파일 저장 시키기 ###############
for batsh in datagen.flow(img,
save_to_dir=output_directory,
save_prefix=save_prefix,
save_format="png") :
### 증식된 이미지 별로 [종속변수]로 사용할 값을 리스트에 담기
target.append(target_list[i])
create_img_cnt -= 1
### 생성할 이미지 갯수만큼 만들어지면 종료시키기
if create_img_cnt == 0 :
break
### 종속변수 리스트를 numpy 배열 타입으로 변환하기
target = np.array(target)
### 종속변수 리스트를 numpy 파일로 저장시키기
# - target_filename : 저장할 폴더 + 파일명
# - target : 종속변수 리스트
np.save(target_filename, target)
'''
너무 많은 증식을 할 경우, 원하는 갯수만큼 증식이 안되는 경우가 있다.
- 증식을 만드는 시간과 시스템 폴더에 저장되는 시간차로 발생
- 많은 양을 만들경우 조금씩 여러번에 걸쳐서 증식
'''
증식한 이미지 폴던 내에 모든 이미지 파일을 차원 [4차원 데이터]로 변환 및 저장하는 함수
증식된 파일이 저장된 폴더 내 모든 파일에 대해서 4차원 데이터로 변환하여 numpy 배열 형태로 저장시키기
'''
- output_directory : 증식된 파일이 위치한 폴더
- save_4d_filename : 저장할 파일명
'''
def save_4d_data(output_directory, save_4d_filename) :
### 4차원 데이터를 담을 리스트 변수
data = []
### 증식된 모든 파일 읽어들이기
for filename in os.listdir(output_directory) :
if filename.endswith((".jpg", ".jpeg", ".png")) :
img_path = os.path.join(output_directory, filename)
### 3차원 데이터로 읽어들이기
img = cv2.imread(img_path)
### 픽셀 정규화
img = cv2.resize(img, (170, 175))
### 리스트에 담기
data.append(img)
data = np.array(data)
print(data.shape)
np.save(save_4d_filename, data)
함수 호출
- 특정 폴더 내에 모든 이미지파일 로드하여, 이미지 데이터로 변환하는 함수 호출
### 폴더 위치 지정 input_directory = "./data/01_org_img/" ### 함수 호출하기 images = load_images(input_directory) images.shape
- 이미지 증식 및 파일저장, 종속변수 생성 및 파일 저장 함수 호출
### 증식된 이미지 파일 저장 폴더 output_directory = "./data/02_train_img/" ### 종속변수 데이터 파일명 # - numpy 파일의 확장자는 보통 .npy를 사용한다. target_filename = "./data/03_train_4d_data/target_data.npy" ### 함수 호출하기 create_images(images, output_directory, target_filename)
- 증식된 이미지 각각에 대한 이미지 데이터로 변환하여 numpy 배열 파일로 저장하기
save_4d_filename = "./data/03_train_4d_data/train_4d_data.npy" save_4d_data(output_directory, save_4d_filename)
- numpy로 저장된 독립변수와 종속변수 데이터 확인하기
train = np.load(save_4d_filename) target = np.load(target_filename) train.shape, target.shape
4차원 이미지 데이터와 종속변수 데이터를 읽어들여서 CNN 훈련시키기
- 데이터 불러오기 / 정규화 / 분리
''' 사용할 라이브러리 다시 정의 ''' import numpy as np import tensorflow as tf from tensorflow import keras from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler ''' 독립변수 : image_data / 종속변수 : label_data ''' image_data = np.load("./data/03_train_4d_data/train_4d_data.npy") label_data = np.load("./data/03_train_4d_data/target_data.npy") image_data.shape, label_data.shape ''' 픽셀 데이터 정규화 (0 ~ 1 범위) ''' image_data = image_data / 255.0 image_data.shape ''' 훈련 및 테스트 = 8 : 2 로 분리 ''' x_train, x_test, y_train, y_test = train_test_split(image_data, label_data, test_size=0.2, random_state=42) print(x_train.shape, y_train.shape) print(x_test.shape, y_test.shape)
- CNN 모델 생성하기
''' <CNN 모델 생성하기> - 입력계층 : CNN 모델 사용 출력크기 32, 커널사이즈 3, 활성화 함수 ReLU - 은닉계층 : MaxPooling, 전처리 1차원 계층 생성 - 출력계층 ''' model = keras.Sequential() model.add(keras.layers.Conv2D(32, kernel_size=3, activation="relu", padding="same", strides=1, input_shape=(175, 170, 3))) model.add(keras.layers.MaxPool2D(pool_size=2, strides=2)) model.add(keras.layers.Conv2D(64, kernel_size=3, activation="relu", padding="same", strides=1)) model.add(keras.layers.MaxPool2D(pool_size=2, strides=2)) model.add(keras.layers.Flatten()) model.add(keras.layers.Dense(64, activation="relu")) model.add(keras.layers.Dense(1, activation="sigmoid"))
- 모델 설정
''' <모델 설정> - 옵티마이저 : adam - 손실함수 - 출력 값 ''' model.compile(optimizer="adam", loss = "binary_crossentropy", metrics="accuracy")
- 훈련
''' <훈련> - 반복횟수 15번 - 배치사이즈 32개 - validation_split=0.2 : 훈련 데이터에서 20%를 검증 데이터로 사용하라는 의미 - fit() 함수 실행 시 내부적으로 다시 분류하여 사용함 ''' model.fit(x_train, y_train, batch_size=32,epochs=15, validation_split=0.2)
- 테스트 데이터로 검증
''' <테스트 데이터로 검증> ''' model.evaluate(x_test, y_test)
(응용)CNN 모델을 이용해서 위험한 사람 확인 및 비프음 발생시키기
- 사용 라이브러리
import os import platform ### 윈도우 OS인 경우에만 사용(mac은 제외) import winsound import time
- 예측하기
''' 예측할 이미지 불러오기 ''' # target_list = [1, 0, 1, 0, 1, 1, 0, 1, 1, 0] pred_img = cv2.imread("./data/04_detection_img/0_1.png") # pred_img = cv2.imread("./data/04_detection_img/1_0.png") ''' predict() ''' pred_img = cv2.resize(pred_img, (170, 175)) pred_img = pred_img.reshape((1,) + pred_img.shape) pred_data = pred_img / 255.0 pred_data.shape y_pred = model.predict(pred_data) y_pred ''' 확률이 50%인 경우 위험인자로 인식해서 비프음 발생하기 ''' if y_pred[0] > 0.5 : print(f"인식율[{y_pred[0]}] : 위험") ''' 비프음 발생시키기 ''' ### 윈도우 OS인 경우 if platform.system() == "Windows" : ### 1000 : 소리 주파수(소리 높낮이 조정값) # - 보통 사람의 청각 범위 : 20Hz ~ 20,000Hz ### 500 : 지속시간(1000dms 1초, 500은 0.5초) for i in range(5) : winsound.Beep(1000, 500) time.sleep(0.5) ### MAC인 경우 elif platform.system() == "Darwin" : os.system("osascript -e 'breep'") else : print(f"인식율[{y_pred[0]}] : 안전")
'Digital Boot > 인공지능' 카테고리의 다른 글
[인공지능][DL] Deep Learning - YOLO / Camera 객체탐지 (1) | 2024.01.11 |
---|---|
[인공지능][DL] Deep Learning - YOLO / 객체탐지 (0) | 2024.01.10 |
[인공지능][DL] Deep Learning - 합성곱신경망(CNN) (1) | 2024.01.08 |
[인공지능][DL] Deep Learning - RNN 응용 / 규칙기반 챗봇 (2) | 2024.01.08 |
[인공지능][DL] Deep Learning - 순환신경망(RNN), 장기기억 순환신경망(LSTM), 게이트웨이 반복 순환신경망(GRU) (1) | 2024.01.08 |