
1. 스마트폰의 인기 기능, 인물 모드를 내 코드로 구현하기
최근 스마트폰 카메라 기능 중 사용자들이 가장 선호하는 기능을 꼽으라면 단연 '인물 모드(Portrait Mode)'일 것입니다. 피사체는 선명하게 살리고 배경은 부드럽게 흐리는 이 기술은 고가의 DSLR 카메라에서나 볼 수 있었던 '아웃포커싱(Out-focusing)' 효과를 소프트웨어적으로 재현한 것입니다.
필자는 과거 화상 회의 솔루션을 개발하는 프로젝트에 참여하며, 사용자의 사생활 보호를 위해 실시간으로 배경을 흐리게 만드는 기능을 구현해야 했습니다. 단순히 배경을 지우는 것을 넘어, 얼마나 자연스럽게 경계선을 처리하느냐가 서비스의 퀄리티를 결정짓는 핵심이었습니다. 이번 포스팅에서는 파이썬과 강력한 라이브러리들을 활용해, 전문가 수준의 인물 강조 효과를 만드는 과정과 그 안에 숨겨진 기술적 노하우를 공유해 보겠습니다.
2. 배경 분리의 핵심: 시멘틱 세그멘테이션(Semantic Segmentation)
인물 모드를 구현하기 위한 첫 번째 단계는 영상 속에서 '인물'과 '배경'을 정확히 구분해내는 것입니다. 이를 컴퓨터 비전에서는 시멘틱 세그멘테이션이라고 부릅니다. 과거에는 단순히 색상 차이나 움직임을 이용했지만, 이는 배경과 인물의 색상이 비슷할 경우 심각한 오류를 범하곤 했습니다.
최근에는 딥러닝 모델의 발전으로 픽셀 단위의 정교한 분리가 가능해졌습니다. 특히 구글의 Mediapipe나 Facebook의 Segment Anything Model(SAM) 같은 도구들은 복잡한 수식 없이도 우리에게 완벽한 '인물 마스크(Person Mask)'를 제공합니다. 이 마스크는 인물 영역은 흰색(1), 배경 영역은 검은색(0)으로 표시된 이진 데이터를 말하는데, 이 지도가 얼마나 정교하느냐에 따라 인물 모드의 자연스러움이 결정됩니다.
3. 자연스러운 흐림 효과를 위한 가우시안 블러의 마법
배경을 흐리게 만드는 가장 대표적인 방법은 가우시안 블러(Gaussian Blur)입니다. 이는 특정 픽셀 주변의 값들을 가중 평균하여 이미지를 뭉개뜨리는 원리입니다. 하지만 실무에서 단순히 배경에 블러를 적용하면 인물의 테두리 부분이 뿌옇게 번지는 '헤일로(Halo) 현상'이 발생합니다.
필자가 이 문제를 해결하기 위해 도입한 방법은 마스크 자체에도 가우시안 블러를 적용하여 '소프트 마스크'를 만드는 것이었습니다. 경계선을 0과 1로 딱딱하게 나누는 것이 아니라, 0.1, 0.2 처럼 점진적으로 변화하게 만들어 인물과 배경이 만나는 지점을 부드럽게 합성(Alpha Blending)하는 전략입니다. 이러한 디테일한 수치 조절이 '가짜 같은 느낌'을 지우는 결정적인 차이를 만듭니다.
4. 실시간성 확보를 위한 연산 최적화 전략
고화질 영상에서 매 프레임마다 딥러닝 추론과 블러 연산을 수행하는 것은 하드웨어에 상당한 무리를 줍니다. 특히 모바일이나 저사양 PC 환경에서는 프레임 드랍이 발생하기 쉽습니다. 필자는 이를 극복하기 위해 두 가지 최적화 기법을 주로 사용합니다.
첫째는 '입력 해상도의 조절'입니다. 세그멘테이션 모델은 의외로 낮은 해상도에서도 인물의 형태를 잘 잡아냅니다. 따라서 원본 영상을 작은 크기로 줄여 마스크를 딴 뒤, 다시 원본 크기로 키우는 방식을 사용하면 연산 속도를 3배 이상 끌어올릴 수 있습니다. 둘째는 'GPU 가속'입니다. OpenCV의 가우시안 블러 연산을 CPU가 아닌 GPU 전용 명령어로 처리하도록 설정하면, 고해상도에서도 끊김 없는 인물 모드를 유지할 수 있습니다.
5. 파이썬 기반 인물 모드 구현 핵심 코드
이제 Mediapipe와 OpenCV를 결합하여 실시간으로 배경 흐림 효과를 적용하는 핵심 코드를 살펴보겠습니다. (이 코드를 복사하여 티스토리 코드블럭에 넣으세요.)
import cv2 import mediapipe as mp import numpy as np
1. Mediapipe 인물 분리 모델 초기화
mp_selfie_segmentation = mp.solutions.selfie_segmentation segment = mp_selfie_segmentation.SelfieSegmentation(model_selection=1)
def apply_portrait_mode(frame, blur_intensity=25): # 2. RGB 변환 및 인물 마스크 추출 img_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) results = segment.process(img_rgb) mask = results.segmentation_mask
# 3. 마스크 이진화 및 경계선 부드럽게 처리 (Soft Mask)
# 0.1 이상의 신뢰도를 가진 영역을 인물로 판단
condition = np.stack((mask,) * 3, axis=-1) > 0.1
mask_blurred = cv2.GaussianBlur(mask, (15, 15), 0)
alpha = np.stack((mask_blurred,) * 3, axis=-1)
# 4. 배경 블러 처리
background_blurred = cv2.GaussianBlur(frame, (blur_intensity, blur_intensity), 0)
# 5. 인물과 배경 합성 (Alpha Blending)
# 공식: (인물 * 알파) + (배경 * (1 - 알파))
output = (frame * alpha + background_blurred * (1 - alpha)).astype(np.uint8)
return output
[코드에 대한 부가 설명] 위 코드는 실무에서 가장 안정적인 성능을 보이는 Mediapipe의 SelfieSegmentation을 활용한 예시입니다. 여기서 주목할 부분은 단계 5의 알파 블렌딩(Alpha Blending) 공식입니다. 단순히 마스크를 씌워 자르는 것이 아니라, 마스크의 가우시안 블러값(alpha)을 활용해 인물과 흐려진 배경을 수학적으로 혼합합니다. blur_intensity 값을 조절하면 배경이 흐려지는 정도를 실시간으로 제어할 수 있어, 사용자 인터페이스(UI)에서 슬라이더를 통해 심도를 조절하는 기능을 쉽게 구현할 수 있습니다.
6. 실무적 통찰: 복잡한 배경에서의 오작동 대응
현장에서는 항상 완벽한 조명과 단순한 배경만 주어지지 않습니다. 뒤에 사람이 지나가거나, 인물이 들고 있는 물체가 배경으로 오인되어 흐려지는 경우가 빈번합니다. 필자는 이러한 문제를 방지하기 위해 '시간적 평활화(Temporal Smoothing)' 기법을 권장합니다.
이전 프레임의 마스크 데이터와 현재 프레임의 데이터를 일정 비율로 섞어 마스크가 갑자기 튀거나 떨리는 현상을 방지하는 것입니다. 이 간단한 알고리즘 추가만으로도 영상의 안정성이 비약적으로 향상됩니다. 또한, 머리카락처럼 미세한 부분의 분리 성능을 높이려면 단순한 마스크 추출을 넘어 '그랩컷(GrabCut)' 알고리즘을 후처리에 결합하는 것도 좋은 방법입니다.
7. 인물 모드의 진화: 가상 배경과 디지털 트윈
배경 흐림 기술은 단순히 배경을 뭉개는 것에 그치지 않고 가상 배경(Virtual Background) 기술로 진화하고 있습니다. 이제는 흐린 배경 대신 다른 공간의 영상을 합성하여 사용자가 마치 다른 장소에 있는 듯한 경험을 제공합니다. 이는 특히 재택근무가 일상화된 현대 사회에서 필수적인 기술이 되었습니다.
더 나아가, 이 기술은 디지털 트윈 분야에서 실물 객체만을 추출하여 가상 세계로 전송하는 '홀로포테이션(Holoportation)'의 기초가 되기도 합니다. 우리가 작성한 이 짧은 코드가 미래의 메타버스 환경에서 실물 경제와 가상 세계를 잇는 핵심 전처리 도구가 되는 셈입니다.
8. 마치며: 기술의 조합으로 새로운 가치를 만드세요
오늘은 파이썬을 이용해 인물 모드를 구현하고, 그 과정에서 필요한 세그멘테이션과 합성 기술에 대해 심도 있게 다루어 보았습니다. 영상 처리 기술은 단독으로 쓰일 때보다 다른 분야와 결합할 때 더 큰 힘을 발휘합니다. 오늘 배운 배경 분리 기술을 앞서 포스팅한 '깊이 추정(Depth Estimation)' 기술과 결합한다면, 거리에 따라 배경이 다르게 흐려지는 진정한 의미의 '광학적 아웃포커싱'을 구현할 수도 있을 것입니다.
프로그래밍은 단순히 문법을 익히는 것이 아니라, 이러한 논리적인 도구들을 조합해 현실의 문제를 해결해 나가는 과정입니다. 여러분도 오늘 공유해 드린 코드를 기초 삼아 자신만의 창의적인 영상 처리 필터를 만들어 보시길 바랍니다. 구현 중 발생하는 에러나 성능 개선에 대한 고민이 있다면 언제든 댓글로 남겨주세요. 여러분의 성장을 돕는 좋은 동료가 되겠습니다. 감사합니다.
'Computer Vision + Python > 영상 처리 & 비디오 분석 (엔지니어)' 카테고리의 다른 글
| Python으로 영상에서 그림자 제거(Shadow Removal) 및 품질 향상 실무 가이드 (0) | 2025.12.17 |
|---|---|
| Python으로 영상 분할(Segmentation) 후 객체별 색상 랜더링(Object Coloring) (0) | 2025.12.16 |
| Python으로 구현하는 단안 깊이 추정(Depth Estimation)과 AR/VR 실무 응용 전략 (0) | 2025.12.14 |
| Python으로 영상에서 저조도 영상(Low-Light Video) 보정 및 향상하기 (0) | 2025.12.13 |
| Python으로 영상에서 객체 탈락(Object Occlusion) 대응 알고리즘 구현 (0) | 2025.12.12 |