빙응의 공부 블로그

[6주차]이미지 처리와 OpenCV 인식 본문

goorm

[6주차]이미지 처리와 OpenCV 인식

빙응이 2024. 10. 2. 16:13

📝이미지 파일 업로드 구현

이미지 파일 업로드를 위한 기능을 만들어보자!

 

📌미디어 파일 업로드 설정 값 

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
  • MEDIA_URL
    • 웹에서 접근할 미디어 파일의 URL 경로를 정의한다.
  • MEDIA_ROOT 
    • 업로드된 파일들이 실제로 서버의 파일 시스템에서 저장될 경로이다. 
    • MEDIA_ROOT = os.path.join(BASE_DIR, 'media')로 설정하면 프로젝트의 루트 디렉토리에 media/ 폴더가 생성된다.

 

📌이미지 업로드 처리

from django.shortcuts import render, redirect
from .forms import SimpleUploadForm
from django.core.files.storage import FileSystemStorage

def simple_upload(request):
    if request.method == 'POST':
        form = SimpleUploadForm(request.POST, request.FILES)
        if form.is_valid():
            myfile = request.FILES['image']
            fs = FileSystemStorage()
            filename = fs.save(myfile.name, myfile)
            uploaded_file_url = fs.url(filename)
            return render(request, 'opencv_webapp/simple_upload.html', {
                'form': form,
                'uploaded_file_url': uploaded_file_url
            })
    else:
        form = SimpleUploadForm()
    return render(request, 'opencv_webapp/simple_upload.html', {'form': form})

해당 함수는 뷰 함수로 요청이 들어오면 POT 방식으로 업로드된 파일을 처리하고, GET 방식으로 들어오면 업로드 폼을 보여준다. 

 

fs = FileSystemStorage()
filename = fs.save(myfile.name, myfile)

해당 코드는 파일 저장 로직으로 FileSystemStorage 객체는 Django의 기본 파일 저장 시스템으로, 업로드된 파일을 저장하고 url을 생성한다. 

  • fs.save()는 파일을 서버의 지정된 경로 (MEDIA_ROOT)에 저장한다. 
uploaded_file_url = fs.url(filename)

해당 코드는 파일을 저장한 후 웹에서 접근할 수 있는 URL을 생성한다. 

 

✔ 장고의 이미지 저장

Django는 자체적으로 파일 시스템을 제공한다.이미지는 주로 서버의 파일 시스템에 저장하며 settings.py 파일에서 설정한 MEDIA_ROOT와 MEDIA_URL을 기반으로 한다. 

 

📝 OpenCV로 Face Detection 구현하기

해당 장은 OpenCV를 활용한 업로드된 이미지 파일에서 얼굴 인식을 
구현하는 것이다.

 

이미지 업로드를 위한 모델 선언
  • 얼굴 인식을 위한 이미지를 데이터베이스에 저장하기 위해 모델을 정의한다.
from django.db import models

class ImageUploadModel(models.Model):
    description = models.CharField(max_length=255, blank=True)
    document = models.ImageField(upload_to='images/%Y/%m/%d')
    uploaded_at = models.DateTimeField(auto_now_add=True)

 

이미지 업로드 폼 생성
  • 해당 폼은 사용자로부터 이미지 파일을 업로드 받아 데이터베이스에 저장한 후 저장한 이미지를 대상으로 얼굴 인식까지 적용한다.
from django import forms
from .models import ImageUploadModel

class ImageUploadForm(forms.ModelForm):
    class Meta:
        model = ImageUploadModel
        fields = ('description', 'document')

 

얼굴 인식 함수 구현
  • OpenCV를 사용하여 업로드된 이미지에서 얼굴을 감지하는 함수를 구현
  • 이 함수는 이미지 파일의 경로를 받아 얼굴을 인식하고 그 결과를 저장된 이미지에 그린다.
import cv2
import numpy as np

def cv_detect_face(path):
    img = cv2.imread(path, 1)  # 이미지를 읽어옴
    if img is not None:
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
        faces = face_cascade.detectMultiScale(gray, 1.3, 5)
        for (x, y, w, h) in faces:
            cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
        cv2.imwrite(path, img)  # 처리된 이미지 저장
    else:
        print('Image not found')

 

  • cv2.CascadeClassifier: Haar Cascade 알고리즘을 사용하여 얼굴을 감지
  • detectMultiScale: 얼굴을 찾고, 얼굴 위치와 크기를 반환
  • cv2.rectangle: 감지된 얼굴에 사각형을 그림
이미지 리사이징 기능 추가
  • 업로드된 이미지가 너무 큰 경우 자동으로 크기를 조절하는 기능을 구현하여 서버 성능 최적화를 해보자
from django.conf import settings
import numpy as np
import cv2

def cv_detect_face(path):
    img = cv2.imread(path, 1)

    if (type(img) is np.ndarray):
        print(img.shape)

        resize_needed = False
        if img.shape[1] > 640:
            resize_needed = True
            new_w = img.shape[1] * (640.0 / img.shape[1])
            new_h = img.shape[0] * (640.0 / img.shape[1])
        elif img.shape[0] > 480:
            resize_needed = True
            new_w = img.shape[1] * (480.0 / img.shape[0])
            new_h = img.shape[0] * (480.0 / img.shape[0])

        if resize_needed:
            img = cv2.resize(img, (int(new_w), int(new_h)))

        baseUrl = settings.MEDIA_ROOT_URL + settings.MEDIA_URL
        face_cascade = cv2.CascadeClassifier(baseUrl + 'haarcascade_frontalface_default.xml')
        eye_cascade = cv2.CascadeClassifier(baseUrl + 'haarcascade_eye.xml')

        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray, 1.3, 5)
        for (x, y, w, h) in faces:
            cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
            roi_gray = gray[y:y + h, x:x + w]
            roi_color = img[y:y + h, x:x + w]
            eyes = eye_cascade.detectMultiScale(roi_gray)
            for (ex, ey, ew, eh) in eyes:
                cv2.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 2)
        cv2.imwrite(path, img)

    else:
        print('Error occurred within cv_detect_face!')
        print(path)

 

 

  • cv2.imread(path, flags)
    • 설명: 지정된 경로에서 이미지를 읽어온다.
    • 파라미터:
      • path: 이미지 파일 경로
      • flags: 읽기 모드 (1: 컬러, 0: 그레이스케일)
  • cv2.resize(src, dsize)
    • 설명: 이미지를 지정한 크기로 리사이즈한다.
    • 파라미터:
      • src: 입력 이미지
      • dsize: 출력 이미지 크기 (너비, 높이 튜플)
  • cv2.CascadeClassifier(filename)
    • 설명: 사전 훈련된 Haar Cascade 분류기를 로드한다.
    • 파라미터:
      • filename: XML 형식의 분류기 파일 경로
  • detectMultiScale(image, scaleFactor, minNeighbors)
    • 설명: 이미지를 분석하여 물체(얼굴 등)를 탐지한다.
    • 파라미터:
      • image: 분석할 이미지 (그레이스케일)
      • scaleFactor: 이미지 크기를 줄이는 비율
      • minNeighbors: 최소 이웃 수 (물체의 유효성 판단 기준)
  • cv2.rectangle(img, pt1, pt2, color, thickness)
    • 설명: 이미지에 사각형을 그린다.
    • 파라미터:
      • img: 사각형을 그릴 이미지
      • pt1: 시작 좌표 (좌상단)
      • pt2: 끝 좌표 (우하단)
      • color: 사각형 색상 (BGR)
      • thickness: 선의 두께
  • cv2.cvtColor(src, code)
    • 설명: 이미지의 색상 공간을 변환한다.
    • 파라미터:
      • src: 변환할 이미지
      • code: 변환할 색상 공간 (예: cv2.COLOR_BGR2GRAY)
  • cv2.imwrite(filename, img)
    • 설명: 이미지를 파일로 저장한다.
    • 파라미터:
      • filename: 저장할 파일 경로
      • img: 저장할 이미지

 

 

'goorm' 카테고리의 다른 글

[8주차]  (1) 2024.10.16
[7주차]  (2) 2024.10.08
[4,5주차]  (1) 2024.09.25
[3주차]Django  (1) 2024.09.09
[2주차]Django 본격적인 시작  (0) 2024.09.02