이전 포스트에서 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() 메서드를 사용하여 이미지를 분석한다.
🔍 주요 흐름 요약
- 클라이언트에서 이미지 경로(myImg)를 GET 방식으로 전달받음
- 해당 경로의 이미지 파일을 바이트 형태로 읽어옴
- boto3을 통해 AWS Rekognition API를 호출
- 부적절한 콘텐츠가 감지되면 해당 라벨 정보 반환
- 아무 문제없으면 빈 리스트([]) 반환
📄 코드 설명
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는 성인용, 노출, 폭력 등 다양한 카테고리를 평가하여 필터링 기준을 제시해 주기 때문에 이미지 검수 작업이 필요한 서비스에 유용하게 활용할 수 있다.
'코딩라이브러리 > 파이썬' 카테고리의 다른 글
aws rekognition 사용하기 위한 로컬 환경설정 (0) | 2025.04.10 |
---|---|
[파이썬] json data 정렬 시 sorted의 key 값으로 설정하기 (6) | 2024.09.12 |
[파이썬] 백준 24052 알고리즘 수업 삽입 정렬 2 (0) | 2024.07.16 |
[파이썬] 백준 24051 알고리즘 수업 삽입 정렬 1 (0) | 2024.07.12 |
[파이썬] 백준 23969 알고리즘 수업 버블 정렬 2 (0) | 2024.07.03 |