face
┣ mysite
┃ ┣ config
┃ ┃ ┣ __pycache__
┃ ┃ ┃ ┣ __init__.cpython-310.pyc
┃ ┃ ┃ ┣ __init__.cpython-39.pyc
┃ ┃ ┃ ┣ settings.cpython-310.pyc
┃ ┃ ┃ ┣ settings.cpython-39.pyc
┃ ┃ ┃ ┣ urls.cpython-310.pyc
┃ ┃ ┃ ┣ urls.cpython-39.pyc
┃ ┃ ┃ ┣ wsgi.cpython-310.pyc
┃ ┃ ┃ ┗ wsgi.cpython-39.pyc
┃ ┃ ┣ __init__.py
┃ ┃ ┣ asgi.py
┃ ┃ ┣ settings.py
┃ ┃ ┣ urls.py
┃ ┃ ┗ wsgi.py
┃ ┣ star
┃ ┃ ┣ __pycache__
┃ ┃ ┃ ┣ __init__.cpython-310.pyc
┃ ┃ ┃ ┣ __init__.cpython-39.pyc
┃ ┃ ┃ ┣ admin.cpython-310.pyc
┃ ┃ ┃ ┣ admin.cpython-39.pyc
┃ ┃ ┃ ┣ apps.cpython-310.pyc
┃ ┃ ┃ ┣ apps.cpython-39.pyc
┃ ┃ ┃ ┣ forms.cpython-310.pyc
┃ ┃ ┃ ┣ models.cpython-310.pyc
┃ ┃ ┃ ┣ models.cpython-39.pyc
┃ ┃ ┃ ┣ urls.cpython-310.pyc
┃ ┃ ┃ ┣ urls.cpython-39.pyc
┃ ┃ ┃ ┣ views.cpython-310.pyc
┃ ┃ ┃ ┗ views.cpython-39.pyc
┃ ┃ ┣ migrations
┃ ┃ ┃ ┣ __pycache__
┃ ┃ ┃ ┃ ┣ __init__.cpython-310.pyc
┃ ┃ ┃ ┃ ┗ __init__.cpython-39.pyc
┃ ┃ ┃ ┗ __init__.py
┃ ┃ ┣ .DS_Store
┃ ┃ ┣ __init__.py
┃ ┃ ┣ admin.py
┃ ┃ ┣ apps.py
┃ ┃ ┣ forms.py
┃ ┃ ┣ models.py
┃ ┃ ┣ team3_new.h5
┃ ┃ ┣ tests.py
┃ ┃ ┣ urls.py
┃ ┃ ┗ views.py
┃ ┣ static
┃ ┃ ┣ assets
┃ ┃ ┃ ┣ img
┃ ┃ ┃ ┃ ┣ .DS_Store
┃ ┃ ┃ ┃ ┣ bg-callout.jpg
┃ ┃ ┃ ┃ ┣ bg-masthead.jpg
┃ ┃ ┃ ┃ ┣ portfolio-1.jpg
┃ ┃ ┃ ┃ ┣ portfolio-2.jpg
┃ ┃ ┃ ┃ ┣ portfolio-3.jpg
┃ ┃ ┃ ┃ ┗ portfolio-4.jpg
┃ ┃ ┃ ┣ .DS_Store
┃ ┃ ┃ ┗ favicon.ico
┃ ┃ ┣ css
┃ ┃ ┃ ┣ style.css
┃ ┃ ┃ ┗ styles.css
┃ ┃ ┣ js
┃ ┃ ┃ ┗ scripts.js
┃ ┃ ┗ .DS_Store
┃ ┣ templates
┃ ┃ ┣ index.html
┃ ┃ ┗ result.html
┃ ┣ .DS_Store
┃ ┣ db.sqlite3
┃ ┣ manage.py
┃ ┗ requirements.txt
┗ .DS_Store
프로젝트 목표 및 진행방향
1. 이미지 분류 모델(.h5)파일 장고 구현
2. DB연결 및 EC2서버 배포
- 프로젝트 시작 전 강사님께서 각 팀당 AWS EC2 서버 주소를 공유
django-admin startproject config .
django-admin startapp star
# settings.py
ALLOWED_HOSTS = ['?.??.???.???']
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'bootstrap4',
'star',
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'team3',
'USER': '????',
'PASSWORD': '?????',
'HOST': '?.??.???.???',
'PORT': '3306'
}
}
]
STATIC_URL = 'static/'
STATICFILES_DIRS = [
BASE_DIR / 'static',
os.path.join(BASE_DIR, 'static'),
os.path.join(BASE_DIR, 'static', 'assets'),
os.path.join(BASE_DIR, 'static', 'assets', 'img'),
]
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('star.urls')),
]
import os
from PIL import Image
from .models import Post
from django.shortcuts import render
from django.http import HttpResponse
from .forms import ImageUploadForm
from .models import ImageClassifier,Post
import numpy as np
import glob
# Create your views here.
def classify_image(request):
if request.method == 'POST':
form = ImageUploadForm(request.POST, request.FILES)
if form.is_valid():
image = form.cleaned_data['image']
# 모델 경로 설정
model_path = 'star/team3_new.h5' # 실제 모델 파일의 경로로 수정
# 이미지 분류기 초기화
classifier = ImageClassifier(model_path)
# 이미지 분류
result = classifier.classify_image(image)
Post.objects.create(confidence=result['confidence'], result=result['class_label'])
return render(request, 'result.html', {'result': result})
else:
form = ImageUploadForm()
return render(request, 'index.html', {'form': form})
def rank(request):
results = Post.objects.all()
return render(request, 'ranking.html', {'results': results})
def sub_menu_1(request):
return render(request, 'sub_menu_1.html')
import tensorflow as tf
from django.db import models
from PIL import Image
import numpy as np
import os
class ImageClassifier:
def __init__(self, model_path):
self.model = tf.keras.models.load_model(model_path)
def classify_image(self, image):
class_label=['강해린',
'김채원',
'뉴진스 하니',
'안유진',
'아린',
'장원영',
'카즈하',
'차은우',
'방탄소년단 뷔',
'정준하',
'정형돈',
'서강준',
'카리나',
'마동석',
'박보검',
'손석구',
'아이브 가을',
'이광수',
'침착맨',
'르세라핌 사쿠라',]
img = Image.open(image)
img = img.resize((224, 224)) # 모델에 맞는 이미지 크기로 조정
img = np.array(img) / 255.0 # 이미지 정규화
img = np.expand_dims(img, axis=0) # 배치 차원 추가
predictions = self.model.predict(img)
pred_class = np.argmax(predictions, axis=1)
class_index = np.argmax(predictions[0]) # 가장 높은 확률을 가진 클래스 인덱스
confidence = predictions[0][class_index] # 분류 확률
result = class_label[pred_class[0]]
result = {
'class_label': result,
'confidence': confidence,
}
return result
class Post(models.Model):
confidence = models.FloatField()
result = models.CharField(max_length=100)
def __str__(self):
return self.result
from django import forms
class ImageUploadForm(forms.Form):
image = forms.ImageField()
from django.urls import path, include
from . import views
from star.views import classify_image
app_name = 'star'
urlpatterns = [
path('', classify_image, name='classify_image'),
path('sub_menu_1/', views.sub_menu_1, name='sub_menu_1'),
]
<nav id="sidebar-wrapper">
<ul class="sidebar-nav">
<style>
.sub-menu {
display: none;
}
.sidebar-nav-item:hover .sub-menu {
display: block;
}
</style>
<li class="sidebar-nav-item"><a href="{% url 'star:sub_menu_1' %}">About</a>
</li>
<li class="sidebar-nav-item"><a href="{% url 'star:classify_image' %}">닮은꼴 찾기</a></li>
</ul>
</nav>
<body>
<h5 style="text-align: center;"> ※ '.png' 파일은 안됩니다! ※</h5>
<form method="POST" enctype="multipart/form-data" style="text-align: center;">
{% csrf_token %}
{{ form }}
<div class="button-container">
<button type="submit" class="btn btn-primary btn-xl">이미지 분류하기</button>
</div>
</form>
</body>
<!-- result.html -->
{%load static%}
<!DOCTYPE html>
<html>
<header>
<meta charset="UTF-8">
<title>분류 결과</title>
<style>
body {
display: flex;
flex-direction: column;
justify-content: top center;
align-items: center;
height: 100vh;
text-align: center;
}
.return-button {
display: inline-block;
padding: 10px 20px;
background-color: #006242;
color: white;
text-decoration: none;
border-radius: 5px;
font-size: 16px;
margin-top: 20px;
}
.return-button:hover {
background-color: #4CAF50;
}
.profile-image {
width: 400px; /* 원하는 너비로 조정 */
height: auto; /* 너비에 맞춰 자동으로 높이 조정 */
}
</style>
</style>
</header>
<body>
<h1>분류 결과</h1>
<p>예측 결과: 대박 미친 {{ result.class_label }} 입니다...</p>
<img class="profile-image" src="{% static result.class_label|add:'.jpg' %}">
<p><a href="{% url 'star:classify_image' %}" class="return-button">돌아가기</a></p>
</body>
{% comment %}
<body>
<h1>분류 결과</h1>
<p>예측 결과: {{ result }}</p>
<img class="profile-image" src="{% static result.class_label|add:'.jpg' %}">
<p><a href="http://127.0.0.1:8000/star/classify/">돌아가기</a></p>
</body>
</html> {% endcomment %}
VGG16모델에서 .png파일을 인식하지 못하는 이유
- VGG16모델은 RGB이미지를 입력으로 사용하고, png파일은 RGBA형식으로 저장(=이미지에 투명도 채널을 추가하는 것)
- VGG16모델은 투명도 채널을 처리할 수 없어 .png파일을 인식하지 못함
해결방법
- .png파일을 RGBA에서 RGB형식으로 변경
- 예시코드
from PIL import Image
image = Image.open('image.png')
image = image.convert('RGB')
image.save('image.jpg', 'JPEG')
<!-- sub_menu_1.html -->
<!DOCTYPE html>
<html>
<head>
<title>아이템 선정</title>
<!-- 필요한 스타일시트 및 스크립트 태그를 추가하세요 -->
<style>
body {
background-image: url('/static/assets/img/bg-masthead.jpg');
/* background-repeat: no-repeat; */
background-size: cover;
}
.center-text {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
height: 100vh;
}
.container h1 {
font-size: 48px;
/* 화면 전체 높이에 맞게 조절 */
}
.header-container {
text-align: center;
margin-top: 50px;
}
.split-container {
display: flex;
justify-content: center;
border-top: 1px solid black;
flex-wrap: wrap;
position: relative;
}
.split-container::before {
content: "";
width: 1px;
background-color: black; /* 세로줄 색상 */
position: absolute; /* 절대적 위치 설정 */
top: 240px; /* 세로줄이 가로줄 위에 위치하도록 설정 */
bottom: -400px; /* 세로줄이 가장 아래까지 표시되도록 설정 */
left: 50%; /* 가운데로 위치하도록 설정 */
transform: translateY(-50%); /* 세로줄을 정중앙에 위치시키도록 설정 */
margin-top: 50px; /* 상단 여백 조정 */
}
.split-container .col {
flex: 1;
padding: 20px;
}
body, html {
height: 100%;
margin: 0;
display: flex;
flex-direction: column;
}
.content {
flex: 1;
}
</style>
</head>
<body>
<div class="header-container">
<h1 >프로젝트 Face</h1>
<h3 class="mb-5"><em>딥러닝을 이용하여 학습시킨 모델을 활용하여<br>닮은 유명인을 찾아주는 홈페이지 만들기</em></h3>
</div>
<div class="split-container">
<div class="col" style="background-color: white;">
<h2 style="text-align: center;">프로젝트명칭: Face</h2>
<p>개발 인원: 6명</p>
<p>개발 기간: 2023.05.12 - 2023.05.18</p>
<p>간단한 소개: 딥러닝을 이용하여 학습시킨 모델을 홈페이지에 적용하여 사용자들이 사진을 올리면 닮은 연예인을<br> 보여주도록 함</p>
<p>개발 언어: python</p>
<p>형상 관리 틀: GitHub</p>
<p>데이터베이스: SQLite</p>
</div>
<!-- 왼쪽 내용 -->
<div class="col">
<h2 style="text-align: center;">DB 설계</h2>
<img src="/static/DB.jpg" alt="DB 설계 이미지" width="700">
</div>
</div>
</body>
</html>
현재 강사님께서 주신 서버가 내려가서 이미지가 부족하네요..
향후 추가하도록 하겠습니다.