사전 학습된 MobileNetV2 모델을 이용하여 ImageNet 데이터셋으로 학습된 모델로 이미지를 분석.
-기능:
- 모델 불러오기: Keras에서 제공하는 MobileNetV2 모델을 ImageNet 가중치와 함께 불러옵니다.
- 이미지 전처리: 사용자가 선택한 이미지를 모델 입력에 맞게 전처리합니다.
- 예측 수행: 전처리된 이미지에 대해 모델이 예측한 결과(상위 3개의 클래스)를 얻습니다.
- 결과 시각화: 이미지를 화면에 표시하고, 이미지 하단에 예측 결과를 텍스트로 출력합니다.
- 파일 탐색기 사용: tkinter 모듈을 사용하여 사용자가 직접 분석할 이미지를 선택할 수 있게 합니다.
*모듈 설치
pip install tensorflow matplotlib numpy pillow
- TensorFlow는 Keras와 함께 딥러닝 모델을 구성하고 실행하는 데 사용됩니다.
- Matplotlib는 이미지 및 결과를 시각화하는 데 필요합니다.
- NumPy는 배열 연산을 위해 사용됩니다.
- Pillow는 이미지 로드를 위한 라이브러리입니다.
- tkinter는 대부분의 Python 배포판에 기본 포함되어 있으므로 별도 설치가 필요하지 않습니다. 만약 설치되어 있지 않다면, OS에 맞게 추가 설치하세요.
0. 전체 코드
import tensorflow as tf
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.applications.mobilenet_v2 import decode_predictions, preprocess_input
from tensorflow.keras.preprocessing import image
import numpy as np
import matplotlib.pyplot as plt
# 파일 탐색기 기능을 위한 tkinter 임포트
import tkinter as tk
from tkinter import filedialog
# 1. 사전 학습된 MobileNetV2 모델 불러오기 (ImageNet 가중치 사용)
model = MobileNetV2(weights='imagenet')
print("사전 학습된 MobileNetV2 모델 불러오기 완료.")
def load_and_preprocess_image(img_path, target_size=(224, 224)):
"""
이미지를 로드하여 MobileNetV2 전처리 함수에 맞게 처리하는 함수
- img_path: 이미지 파일 경로
- target_size: 모델 입력 크기 (224x224)
"""
img = image.load_img(img_path, target_size=target_size)
img_array = image.img_to_array(img)
img_array = np.expand_dims(img_array, axis=0) # 배치 차원 추가
img_array = preprocess_input(img_array)
return img_array
# 2. 파일 탐색기를 열어 이미지 파일 선택하기
root = tk.Tk() # tkinter 루트 윈도우 생성
root.withdraw() # 루트 윈도우 숨기기 (파일 탐색기만 표시)
img_path = filedialog.askopenfilename(
title="분석할 이미지 파일 선택",
filetypes=[("Image files", "*.jpg;*.jpeg;*.png"), ("All files", "*.*")]
)
if not img_path:
print("이미지 파일이 선택되지 않았습니다.")
exit()
print("선택된 이미지 파일:", img_path)
# 3. 이미지 로드 및 전처리
img_array = load_and_preprocess_image(img_path)
# 4. 예측 수행
preds = model.predict(img_array)
# 5. 예측 결과 디코딩 (상위 3개 결과 출력)
decoded_preds = decode_predictions(preds, top=3)[0]
print("예측 결과:")
pred_text_lines = []
for pred in decoded_preds:
line = f"{pred[1]}: {pred[2]*100:.2f}%"
pred_text_lines.append(line)
print(line)
# 예측 결과 문자열 (여러 줄로 구성)
prediction_str = "\n".join(pred_text_lines)
# 6. 이미지 시각화 및 예측 결과 표시
img = image.load_img(img_path, target_size=(224, 224))
plt.figure(figsize=(6, 6))
plt.imshow(img)
plt.title("Input Image")
plt.axis('off')
# 이미지 아래쪽에 예측 결과 텍스트를 중앙에 표시
plt.figtext(0.5, 0.01, prediction_str, wrap=True, horizontalalignment='center', fontsize=12)
plt.show()
1. 필요한 라이브러리 임포트
import tensorflow as tf
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.applications.mobilenet_v2 import decode_predictions, preprocess_input
from tensorflow.keras.preprocessing import image
import numpy as np
import matplotlib.pyplot as plt
# 파일 탐색기 기능을 위한 tkinter 임포트
import tkinter as tk
from tkinter import filedialog
- TensorFlow와 Keras:
tensorflow와 Keras 모듈을 불러와 딥러닝 모델과 이미지 전처리 기능을 사용 - MobileNetV2 관련 함수:
MobileNetV2 모델과 ImageNet 가중치 관련 전처리 함수(preprocess_input) 및 예측 결과를 사람이 읽을 수 있는 형식으로 변환하는 함수(decode_predictions)를 임포트 - 이미지 처리 및 수치 계산:
image 모듈과 numpy를 사용하여 이미지를 불러오고 배열 형태로 변환 - Matplotlib:
matplotlib.pyplot을 이용하여 이미지를 시각화 - tkinter:
tkinter와 filedialog를 사용하여 파일 탐색기를 통해 이미지 파일을 선택
2. 사전 학습된 MobileNetV2 모델 불러오기
# 1. 사전 학습된 MobileNetV2 모델 불러오기 (ImageNet 가중치 사용)
model = MobileNetV2(weights='imagenet')
print("사전 학습된 MobileNetV2 모델 불러오기 완료.")
- 모델 불러오기:
MobileNetV2(weights='imagenet') 코드는 ImageNet 데이터셋으로 미리 학습된 MobileNetV2 모델을 불러옴.
이때 가중치 파일은 로컬에 없으면 자동으로 다운로드되며, 이후에는 캐시된 파일을 사용 - 출력 메시지:
모델이 정상적으로 불러와지면 콘솔에 확인 메시지가 출력
3. 이미지 전처리 함수 정의
def load_and_preprocess_image(img_path, target_size=(224, 224)):
"""
이미지를 로드하여 MobileNetV2 전처리 함수에 맞게 처리하는 함수
- img_path: 이미지 파일 경로
- target_size: 모델 입력 크기 (224x224)
"""
img = image.load_img(img_path, target_size=target_size)
img_array = image.img_to_array(img)
img_array = np.expand_dims(img_array, axis=0) # 배치 차원 추가
img_array = preprocess_input(img_array)
return img_array
- 함수 목적:
이 함수는 지정한 경로의 이미지를 모델이 요구하는 입력 크기(224×224)로 리사이즈한 후, 배열로 변환하고 전처리합니다. - 세부 동작:
- image.load_img: 지정된 경로에서 이미지를 불러오고, target_size에 맞게 리사이즈합니다.
- image.img_to_array: 이미지를 numpy 배열로 변환합니다.
- np.expand_dims: 모델은 배치 단위 입력을 받기 때문에, 배열의 차원을 하나 늘려 (1, 224, 224, 3) 형태로 만듭니다.
- preprocess_input: MobileNetV2 전용 전처리를 수행하여 이미지 데이터를 정규화합니다.
4. 파일 탐색기를 통한 이미지 선택
# 2. 파일 탐색기를 열어 이미지 파일 선택하기
root = tk.Tk() # tkinter 루트 윈도우 생성
root.withdraw() # 루트 윈도우 숨기기 (파일 탐색기만 표시)
img_path = filedialog.askopenfilename(
title="분석할 이미지 파일 선택",
filetypes=[("Image files", "*.jpg;*.jpeg;*.png"), ("All files", "*.*")]
)
if not img_path:
print("이미지 파일이 선택되지 않았습니다.")
exit()
print("선택된 이미지 파일:", img_path)
- tkinter 윈도우 생성:
tk.Tk()로 tkinter의 루트 윈도우를 생성한 후 withdraw()를 호출하여 윈도우를 숨깁니다.
이렇게 하면 파일 탐색기만 띄워지게 됩니다. - 파일 선택:
filedialog.askopenfilename 함수를 사용해 사용자가 파일 탐색기에서 이미지 파일을 선택할 수 있도록 합니다.
선택 가능한 파일 형식은 JPEG, PNG 등입니다. - 선택 여부 확인:
사용자가 파일을 선택하지 않으면 프로그램을 종료합니다.
선택된 파일 경로는 img_path 변수에 저장되고, 이를 콘솔에 출력합니다.
5. 이미지 로드 및 전처리
# 3. 이미지 로드 및 전처리
img_array = load_and_preprocess_image(img_path)
- 전처리 함수 호출:
앞서 정의한 load_and_preprocess_image 함수를 사용하여 선택한 이미지를 불러오고 전처리합니다.
이 결과는 모델 입력에 적합한 형태의 numpy 배열로 저장됩니다.
6. 예측 수행
# 4. 예측 수행
preds = model.predict(img_array)
- 예측:
전처리된 이미지를 MobileNetV2 모델에 넣어 예측을 수행합니다.
결과는 각 클래스에 대한 확률 값이 담긴 배열로 반환됩니다.
7. 예측 결과 디코딩 및 출력
# 5. 예측 결과 디코딩 (상위 3개 결과 출력)
decoded_preds = decode_predictions(preds, top=3)[0]
print("예측 결과:")
pred_text_lines = []
for pred in decoded_preds:
line = f"{pred[1]}: {pred[2]*100:.2f}%"
pred_text_lines.append(line)
print(line)
# 예측 결과 문자열 (여러 줄로 구성)
prediction_str = "\n".join(pred_text_lines)
- 디코딩:
decode_predictions 함수를 사용하여 모델의 예측 결과를 사람이 읽을 수 있는 형식(클래스 이름과 확률)으로 변환합니다.
여기서는 상위 3개의 예측 결과를 가져옵니다. - 텍스트 구성:
각 예측 결과를 문자열 형식(예: dog: 85.23%)으로 만들어 리스트에 저장하고, 이를 한 줄씩 출력합니다.
마지막에 \n으로 연결하여 여러 줄의 문자열(prediction_str)을 생성합니다.
8. 이미지 시각화 및 예측 결과 표시
# 6. 이미지 시각화 및 예측 결과 표시
img = image.load_img(img_path, target_size=(224, 224))
plt.figure(figsize=(6, 6))
plt.imshow(img)
plt.title("Input Image")
plt.axis('off')
# 이미지 아래쪽에 예측 결과 텍스트를 중앙에 표시
plt.figtext(0.5, 0.01, prediction_str, wrap=True, horizontalalignment='center', fontsize=12)
plt.show()
- 이미지 출력:
선택한 이미지를 다시 불러와(리사이즈된 상태) Matplotlib를 사용해 표시합니다.
plt.imshow로 이미지를 출력하고, plt.title로 제목을 붙입니다.
plt.axis('off')를 통해 축과 눈금을 숨깁니다. - 예측 결과 텍스트 출력:
plt.figtext 함수를 이용하여 그림 전체의 하단 중앙에 예측 결과 텍스트(prediction_str)를 표시합니다.
wrap=True 옵션으로 텍스트가 자동 줄바꿈되어 보기 좋게 출력됩니다. - plt.show():
최종적으로 이미지를 창에 표시하여 시각적으로 확인할 수 있도록 합니다.
결론
이 코드는
- 사전 학습된 MobileNetV2 모델을 불러오고,
- tkinter를 통해 사용자가 원하는 이미지 파일을 선택한 후,
- 선택한 이미지를 모델 입력에 맞게 전처리하여 예측을 수행하고,
- 예측 결과를 디코딩하여 콘솔에 출력하며,
- Matplotlib를 사용해 이미지와 함께 예측 결과를 시각적으로 표시합니다.
이 과정을 통해 별도의 학습 데이터 없이도 ImageNet으로 사전 학습된 모델을 활용하여 이미지가 어떤 사물인지 분석하고 결과를 확인할 수 있습니다.
*단, 단일 이미지만 정상분석 가능. 모델을 학습시킬 때 단일 이미지를 이용했기 때문이라는 것 같음.