코딩라이브러리/파이썬

AWS Rekognition 부적절한 이미지를 판별하는 파이썬 코드 알아보기

유니네 라이브러리 2025. 4. 11. 13:37

이전 포스트에서 AWS Rekognition 사용하기 위한 로컬 환경설정을 알아봤다.

이번 글에서는 업로드된 이미지를 바탕으로 Amazon Rekognition API를 호출하여 해당 이미지가 부적절한 콘텐츠를 포함하고 있는지 확인하는 파이썬 백엔드 코드를 함께 살펴보자.

 

✅ 개발 환경

이 예제는 다음과 같은 로컬 환경에서 테스트되었다.

  • 운영체제: macOS (맥북)
  • 프런트엔드: Vue 3
  • 백엔드: Python 3(Django Framework)
  • 사용 서비스: AWS Rekognition(Moderation Labels)

🧑‍💻 AWS Rekognition 연동을 위한 백엔드 코드

 

1. URL 설정 (urls.py)

먼저 Rekognition API 호출을 위한 엔드포인트를 등록해 준다.

# smith/urls.py
from django.urls import path, include

urlpatterns = [
    path('api/smith/', include('smithapp.urls')),  # Rekognition API 연결
]

 

2. 이미지 판별 처리 함수 (views.py)

Rekognition의 detect_moderation_labels() 메서드를 사용하여 이미지를 분석한다.

 

🔍 주요 흐름 요약

  1. 클라이언트에서 이미지 경로(myImg)를 GET 방식으로 전달받음
  2. 해당 경로의 이미지 파일을 바이트 형태로 읽어옴
  3. boto3을 통해 AWS Rekognition API를 호출
  4. 부적절한 콘텐츠가 감지되면 해당 라벨 정보 반환
  5. 아무 문제없으면 빈 리스트([]) 반환

📄 코드 설명

from rest_framework.response import Response
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
from rest_framework import status
from django_ratelimit.decorators import ratelimit
from django.core.files.storage import default_storage

import boto3, os
from urllib.parse import unquote
  • rest_framework 관련 모듈: API 응답을 위해 사용된다.
  • ratelimit: 특정 IP에서 너무 많은 요청이 들어오는 걸 막기 위한 속도 제한 장치이다.
  • boto3: AWS Rekognition을 호출하기 위한 Python SDK이다.
  • default_storage: Django가 관리하는 이미지 저장 경로를 불러오기 위해 사용한다.

✅ 핵심 뷰 함수 코드

@ratelimit(key='ip', rate='10/m', method='GET', block=True)
@api_view(['GET'])
@permission_classes([AllowAny])
def img_rekognition(request):
    print("▶️ Rekognition 분석 시작")

    # GET 파라미터에서 이미지 경로 추출
    image_path = request.GET.get('myImg')
    if not image_path:
        return Response({'error': '이미지 경로가 누락되었습니다.'}, status=status.HTTP_400_BAD_REQUEST)
  • 클라이언트에서 보낸 myImg 파라미터를 추출한다.
  • 값이 없을 경우 에러 응답을 보낸다.

🔒 요청 제한(Rate Limit)

@ratelimit(key='ip', rate='10/m', method='GET', block=True)
  • 같은 IP에서 1분에 10번 이상 요청하면 자동으로 차단된다.
  • 과도한 봇 요청을 방지할 수 있어 보안과 안정성을 높이는 데 도움이 된다.

✅ boto3 세션 설정

    session = boto3.Session()
    client = session.client('rekognition')
  • boto3.Session()을 통해 AWS Rekognition 클라이언트를 생성한다.
  • .aws/credentials 파일에 설정된 자격증명을 자동으로 불러온다.
  • 이 경우 실제로는 다음과 같은 설정을 사용한다:
    • ~/.aws/credentials 파일에 [default]로 저장된 액세스 키
    • ~/.aws/config 파일에 [default]로 설정된 리전(region)

🔄 만약 다른 프로파일을 사용하고 싶다면?

예를 들어 yuneenelife 라는 이름의 프로파일을 사용하고 싶다면 profile_name을 명시화 한다.

session = boto3.Session(profile_name='yuneenelife')
client = session.client('rekognition')

 

✅ 이미지 경로

    current_path = os.getcwd()
    full_path = unquote(current_path + default_storage.url(image_path))
    print("📷 분석 이미지 경로:", full_path)
  • 현재 서버의 작업 디렉터리를 기준으로 저장된 이미지의 전체 경로를 구성한다.
  • unquote()는 URL 인코딩 된 문자열을 원래대로 복원해 준다.

✅ 이미지 파일을 바이트로 변환

    try:
        with open(full_path, 'rb') as image_file:
            image_bytes = image_file.read()
    except FileNotFoundError:
        return Response({'error': '이미지를 찾을 수 없습니다.'}, status=status.HTTP_404_NOT_FOUND)
  • 이미지 파일을 열어 바이트 단위로 읽어온다. 바이트 단위로 전달해야 하기 때문이다.
  • 파일이 없을 경우 404 에러 응답을 반환한다.

✅ detect_moderation_labels() 호출

    response = client.detect_moderation_labels(
        Image={'Bytes': image_bytes},
        MinConfidence=60  # 신뢰도 60% 이상인 항목만 반환
    )
  • Rekognition의 핵심 기능인 detect_moderation_labels()를 호출한다.
  • MinConfidence는 신뢰도 임계값으로, 60% 이상만 결과에 포함되도록 설정했다.

✅ 응답 코드

    labels = response.get('ModerationLabels', [])
    
    if not labels:
        print("✅ 안전한 콘텐츠입니다.")
    else:
        print("⚠️ 부적절한 콘텐츠 감지:")
        for label in labels:
            print(f" - {label['Name']} ({label['Confidence']:.2f}%)")
  • 응답값에서 ModerationLabels 항목을 추출한다.
  • 부적절한 내용이 없으면 빈 리스트, 있으면 라벨 정보가 포함된다.
  • 각 라벨에는 이름(Name), 신뢰도(Confidence), 상위 카테고리(ParentName)가 포함되어 있다.

✅ 응답 값 리턴

    return Response(labels)
  • 분석 결과를 프런트엔드 (Vue3 등)에 JSON 형식으로 그대로 전달한다.
  • 예: [] 또는 [{ "Name": "Explicit Nudity", "Confidence": 88.5, "ParentName": "Nudity" }, ...]

📌 풀 코드

# smithapp/views.py
from rest_framework.response import Response
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
from rest_framework import status
from django_ratelimit.decorators import ratelimit
from django.core.files.storage import default_storage

import boto3, os
from urllib.parse import unquote

# Rekognition API를 호출하는 뷰
@ratelimit(key='ip', rate='10/m', method='GET', block=True)
@api_view(['GET'])
@permission_classes([AllowAny])
def img_rekognition(request):
    print("▶️ Rekognition 분석 시작")

    image_path = request.GET.get('myImg')
    if not image_path:
        return Response({'error': '이미지 경로가 누락되었습니다.'}, status=status.HTTP_400_BAD_REQUEST)

    # boto3 클라이언트 생성
    session = boto3.Session()
    client = session.client('rekognition')

    # 이미지 바이트 추출
    current_path = os.getcwd()
    full_path = unquote(current_path + default_storage.url(image_path))
    print("📷 분석 이미지 경로:", full_path)

    try:
        with open(full_path, 'rb') as image_file:
            image_bytes = image_file.read()
    except FileNotFoundError:
        return Response({'error': '이미지를 찾을 수 없습니다.'}, status=status.HTTP_404_NOT_FOUND)

    # Rekognition 호출
    response = client.detect_moderation_labels(
        Image={'Bytes': image_bytes},
        MinConfidence=60  # 신뢰도 기준 (60% 이상만 반환)
    )

    labels = response.get('ModerationLabels', [])
    
    if not labels:
        print("✅ 안전한 콘텐츠입니다.")
    else:
        print("⚠️ 부적절한 콘텐츠 감지:")
        for label in labels:
            print(f" - {label['Name']} ({label['Confidence']:.2f}%)")

    return Response(labels)

 

📝 출력 예시

 

1) 부적절한 이미지가 없을 경우

[]

 

2) 부적절한 이미지가 있는 경우

[
  {
    "Confidence": 91.32,
    "Name": "Explicit Nudity",
    "ParentName": "Nudity"
  },
  {
    "Confidence": 65.88,
    "Name": "Suggestive",
    "ParentName": "Nudity"
  }
]

 

📘 관련 aws 개발자 가이드는 아래를 참고했다.

Moderating Images with Amazon Rekognition

 

부적절한 이미지 감지 - Amazon Rekognition

이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

docs.aws.amazon.com

 

✍️ 마무리

이렇게 해서 로컬 Django 백엔드에서 Amazon Rekognition을 호출해 이미지가 부적절한 콘텐츠를 포함하는지 판별해 보았다.

이 API는 성인용, 노출, 폭력 등 다양한 카테고리를 평가하여 필터링 기준을 제시해 주기 때문에 이미지 검수 작업이 필요한 서비스에 유용하게 활용할 수 있다.