아 배포 힘들다
- 배포 기능으로 만들어진 서버의 얼굴인식 부분인 openCV에서 카메라 인식이 되지 않는 문제점이 발생하여 해결
→ 해결했지만, 얼굴인식페이지 아래에 카메라가 뜸 (수정 할 사항)
→Docker 링크로 들어가면 얼굴인식 오류 (카메라가 아예 작동하지 않음)
- 배포 ( 진행중 ) : docker를 이용한 django, redis, postgreSQL, celery를 생성 가능 확인, aws ec2를 이용한 배포 (인스턴스 생성), 기능이 완료 되는 데로 배포 단계 시작 예정
- 인증 : 도메인 구매, aws 에서 https SSL인증 받기
도메인 주소 :
www.silverlinings.site
- 배포 기능으로 만들어진 서버의 얼굴인식 부분인 openCV에서 카메라 인식이 되지 않는 문제점이 발생하여 해결
→ 해결했지만, 얼굴인식페이지 아래에 카메라가 뜸 (수정 할 사항)
→Docker 링크로 들어가면 얼굴인식 오류 (카메라가 아예 작동하지 않음)
- 배포 ( 진행중 ) : docker를 이용한 django, redis, postgreSQL, celery를 생성 가능 확인, aws ec2를 이용한 배포 (인스턴스 생성), 기능이 완료 되는 데로 배포 단계 시작 예정
- 인증 : 도메인 구매, aws 에서 https SSL인증 받기
도메인 주소 :
www.silverlinings.site
- 배포 기능으로 만들어진 서버의 얼굴인식 부분인 openCV에서 카메라 인식이 되지 않는 문제점이 발생하여 해결
→ 해결했지만, 얼굴인식페이지 아래에 카메라가 뜸 (수정 할 사항)
→Docker 링크로 들어가면 얼굴인식 오류 (카메라가 아예 작동하지 않음)
- 배포 ( 진행중 ) : docker를 이용한 django, redis, postgreSQL, celery를 생성 가능 확인, aws ec2를 이용한 배포 (인스턴스 생성), 기능이 완료 되는 데로 배포 단계 시작 예정
- 인증 : 도메인 구매, aws 에서 https SSL인증 받기
도메인 주소 :
www.silverlinings.site
- 배포 기능으로 만들어진 서버의 얼굴인식 부분인 openCV에서 카메라 인식이 되지 않는 문제점이 발생
→ 밑에 카메라는 뜨지만 얼굴 인식함 (아직 수정 진행중)
- 기존 얼굴인식 코드를 수정한 코드
- html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" sizes="96x96" href="/static/img/개.png">
<title>Silver Lining</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
background-color: #f8f9fa;
}
h1 {
color: #ef4040;
margin-top: 70px;
font-size: 70px;
}
p {
font-size: 45px;
margin: 20px;
}
.button-container {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 70px;
}
button {
width: 800px;
height: 900px;
font-size: 120px;
font-weight: bold;
padding: 40px 80px;
color: white;
background-color: #ef4040;
border: none;
border-radius: 20px;
cursor: pointer;
}
button:hover {
background-color: #d93636;
}
.spinner-container {
display: none;
}
.status {
font-size: 50px;
margin-top: 100px;
display: none;
}
.en-text {
font-size: 0.5em; /* "Place an order" 텍스트 크기 줄이기 */
}
#video {
display: none; /* 웹캠 비디오 요소 숨기기 */
}
</style>
</head>
<body>
<h1>여기에서 주문하세요!</h1>
<p>화면을 터치해 주세요</p>
<p>Please touch the screen</p>
<div class="button-container">
<form id="order-form" method="post" action="{% url 'orders:face_recognition' %}">
{% csrf_token %}
<button type="submit" id="order-button">
<span class="kr-text">주문하기</span>
<span class="en-text">Place an order</span>
</button>
<div class="spinner-container" id="spinner">
<div class="spinner-border" style="width: 15rem; height: 15rem;" role="status">
<span class="visually-hidden"></span>
</div>
</div>
<div class="status" id="status">
<span class="kr-text">얼굴 인식을 진행하고 있습니다</span>
<br>
<span class="kr-text">Facial recognition is being performed</span>
</div>
</form>
</div>
<!-- 얼굴을 인식할 비디오 요소 -->
<video id="video" width="320" height="240" autoplay></video>
<!-- 비디오 스트림을 캡처하여 얼굴 이미지를 표시할 캔버스 요소 -->
<canvas id="canvas" width="320" height="240"></canvas>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/face-landmarks-detection"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-core"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-converter"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-webgl"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-cpu"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/blazeface"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
window.addEventListener('load', function () {
fetch(`/orders/switch-language/?lang="ko-KR"`)
});
// 웹캠에서 비디오를 가져오고 얼굴을 감지하는 함수
async function detectFaceAndSubmit() {
const video = document.getElementById('video');
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// 먼저 웹캠 액세스 권한을 확인합니다.
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
console.error('getUserMedia is not supported');
return;
}
try {
const stream = await navigator.mediaDevices.getUserMedia({video: {}});
video.srcObject = stream;
const faceModel = await blazeface.load();
const intervalId = setInterval(async () => {
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
const predictions = await faceModel.estimateFaces(video);
if (predictions.length > 0) {
const faceImageData = canvas.toDataURL('image/jpeg');
submitForm(faceImageData);
clearInterval(intervalId);
}
}, 100);
} catch (error) {
console.error('Error accessing webcam:', error);
}
}
// AJAX를 사용하여 폼 제출하는 함수
function submitForm(imageData) {
// FormData 객체 생성
var formData = new FormData();
// 이미지 데이터를 FormData 객체에 추가
var blob = dataURItoBlob(imageData);
formData.append('faceImageData', blob, 'face_image.jpeg');
// CSRF 토큰 가져오기
const csrftoken = getCookie('csrftoken');
// 이미지 데이터가 있는 경우 AJAX 요청 보냄
$.ajax({
url: '/orders/face_recognition/',
method: 'POST',
headers: {'X-CSRFToken': csrftoken},
data: formData,
processData: false, // jQuery가 데이터를 쿼리 문자열로 변환하는 것을 방지
contentType: false, // jQuery가 contentType을 설정하는 것을 방지
success: function (response) {
// 서버 응답을 성공적으로 받은 후에 수행할 작업
console.log('Success:', response);
// 얼굴 나이 확인
var ageNumber = response.age_number;
// 나이에 따라 페이지 리디렉션
if (ageNumber >= 60) {
window.location.href = "{% url 'orders:elder_start' %}";
} else {
window.location.href = "{% url 'orders:menu' %}";
}
},
error: function (xhr, status, error) {
console.error('Error:', error);
// 오류 처리
}
});
}
// base64 데이터를 Blob 객체로 변환
function dataURItoBlob(dataURI) {
// base64를 raw 이진 데이터로 변환
var byteString = atob(dataURI.split(',')[1]);
// mime 컴포넌트 분리
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// 이진 데이터의 바이트를 ArrayBuffer에 작성
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
// ArrayBuffer에서 Blob 객체 생성
return new Blob([ab], {type: mimeString});
}
// CSRF 토큰 가져오는 함수
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
document.getElementById("order-button").addEventListener("click", function (event) {
document.getElementById("spinner").style.display = "block";
document.getElementById("status").style.display = "block";
document.getElementById("order-button").style.display = "none";
event.preventDefault(); // 기본 폼 제출 동작 방지
detectFaceAndSubmit(); // 얼굴 감지 및 제출 함수 호출
});
</script>
</body>
</html>
@csrf_exempt
def face_recognition(request):
if request.method == 'POST' and 'faceImageData' in request.FILES:
# Get uploaded image
uploaded_image = request.FILES['faceImageData']
# Read the image using OpenCV
image_data = uploaded_image.read()
nparr = np.frombuffer(image_data, np.uint8)
frame = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
# 얼굴 인식을 위한 분류기를 로드합니다.
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
# 흑백 이미지로 변환합니다.
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 얼굴을 감지합니다.
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
if len(faces) > 0:
# 이미지를 저장하고 base64로 변환합니다.
image_path = "face.jpg"
cv2.imwrite(image_path, frame)
with open(image_path, "rb") as image_file:
encoded_image = base64.b64encode(image_file.read()).decode('utf-8')
base64_image = f"data:image/jpeg;base64,{encoded_image}"
# OpenAI API에 요청합니다.
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {OPEN_API_KEY}"
}
instruction = """
Although age can be difficult to predict, please provide an approximate number for how old the person in the photo appears to be.
Please consider that Asians tend to look younger than you might think.
And Please provide an approximate age in 10-year intervals such as teens, 20s, 30s, 40s, 50s, 60s, 70s, or 80s.
When you return the value, remove the 's' in the end of the age interval.
For example, when you find the person to be in their 20s, just return the value as 20.
Please return the inferred age in the format 'Estimated Age: [inferred age]'.
"""
payload = {
"model": "gpt-4o",
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": instruction,
},
{
"type": "image_url",
"image_url": {
"url": base64_image
}
}
]
}
],
"max_tokens": 300
}
# OpenAI API로 요청을 보냅니다.
response = requests.post("<https://api.openai.com/v1/chat/completions>", headers=headers, json=payload)
try:
os.remove(image_path)
print(f"{image_path} 이미지가 삭제되었습니다.")
except FileNotFoundError:
print(f"{image_path} 이미지를 찾을 수 없습니다.")
# OpenAI API에서 반환된 응답을 파싱합니다.
ai_answer = response.json()
print("ai_answer", ai_answer)
# 추정된 나이를 가져옵니다.
age_message = ai_answer["choices"][0]['message']['content']
age = age_message.split("Estimated Age: ")[1].strip()
age_number = int(age)
print("당신의 얼굴나이 : ", age_number)
return JsonResponse({'age_number': age_number})
return HttpResponse("Please upload an image.")
이것 때문에 오늘 5시간이 삭제 되었다...
'코딩 교육 TIL' 카테고리의 다른 글
2024-06-10 AI 코딩 TIL (0) | 2024.06.10 |
---|---|
2024-06-07 AI 코딩 TI (1) | 2024.06.07 |
2024-06-04 AI 코딩 TIL (0) | 2024.06.04 |
2024-06-03 AI 코딩 TIL (1) | 2024.06.03 |
2024-05-31 AI 코딩 TIL (1) | 2024.05.31 |