본문 바로가기

Computer Vision + Python/이미지 향상 & 세그멘테이션 (연구자)

Python으로 이미지에서 반사/글레어 제거(Reflection Removal) 기법

 

Python으로 이미지에서 반사/글레어 제거(Reflection Removal) 기법

 

1. 반사 제거는 ‘화질 개선’ 문제가 아니라 ‘데이터 포기 기준’의 문제다

이미지에서 반사(Reflection)나 글레어(Glare)를 제거하는 문제를 처음 접했을 때, 나는 이것을 단순한 전처리 문제로 생각했다. 밝게 튄 영역을 줄이고, 원래 배경을 복원하면 되는 작업이라고 판단했다. 그러나 실제 공정에 적용하면서 깨달은 점은, 반사 제거는 얼마나 복원할 것인가보다, 어디까지를 포기할 것인가를 결정하는 문제라는 사실이었다. 특히 유리 쇼케이스, 스마트폰 화면, 차량 전면 유리처럼 반사가 구조적으로 발생하는 환경에서는 “완전 제거”라는 목표 자체가 비현실적이었다.


2. 현장에서 가장 먼저 무너진 가정: 반사는 노이즈가 아니다

초기 구현에서는 반사를 노이즈처럼 다뤘다. 밝기 임계값을 기준으로 마스킹하고, 주변 픽셀로 보간하는 방식이었다. 하지만 이 방식은 반사가 약한 영역에서는 잘 작동하는 듯 보였으나, 실제 서비스 이미지에서는 제품 로고, 텍스트, 윤곽선까지 함께 사라지는 문제를 발생시켰다. 반사는 단순한 노이즈가 아니라, 원본 이미지 위에 중첩된 또 하나의 신호라는 점을 간과한 결과였다.


3. 반사 제거 파이프라인에서 가장 중요한 전환점

전환점은 “반사를 제거한다”는 표현을 버리고, “반사 성분을 분리한다”는 관점으로 사고를 바꾼 순간이었다. 이때부터 모든 공정은 제거가 아닌 **분해(decomposition)**를 목표로 재설계되었다. 이미지 하나에는 실제 물체 정보와 반사 정보가 동시에 존재하며, 두 정보를 완전히 분리할 수 없다는 전제를 먼저 받아들였다. 이 관점 변화는 이후 모든 파라미터 선택 기준을 바꿔 놓았다.


4. Python 기반 반사 제거 공정의 실제 구성 순서

실제 운영 환경에서 사용한 공정은 다음과 같은 흐름으로 고정되었다.
입력 이미지 안정화 → 색 공간 분리 → 고광도 영역 추적 → 구조 보존 필터링 → 부분 복원 또는 억제.
여기서 핵심은 고광도 영역을 단순히 제거하지 않고, 구조를 유지한 채 약화시키는 단계였다. 이 단계가 없으면 결과 이미지는 즉시 인위적으로 보이기 시작한다.


5. 글레어가 심한 이미지에서 가장 흔한 실패 패턴

가장 자주 발생한 실패는 “결과가 깨끗해 보이지만 쓸 수 없는 이미지”였다. 반사는 줄었지만, 제품의 질감이 사라지고, 평면적인 이미지로 변형되는 경우였다. 이는 대부분 반사 영역을 지나치게 공격적으로 억제했을 때 발생했다. 이후에는 항상 “반사가 남아 있더라도 정보는 남겨둔다”는 기준을 우선 적용했다.


6. Python으로 반사 성분 약화를 시도한 예제 코드

import cv2
import numpy as np

img = cv2.imread("input.jpg")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

v = hsv[:, :, 2]
mask = v > 220

v[mask] = v[mask] * 0.6
hsv[:, :, 2] = v

result = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)

코드 부가 설명

이 코드는 반사 영역을 완전히 제거하지 않고, 명도(Value) 성분만 부분적으로 약화시키는 방식이다. 실제 공정에서는 이 단계를 여러 번 반복하며, 약화 비율을 상황별로 조정했다. 중요한 점은 반사 영역을 0으로 만드는 것이 아니라, 주변 정보와 연결성을 유지하도록 조절하는 것이다.


7. 반사 제거에서 ‘자동화’가 실패하는 지점

반사 제거는 자동화에 매우 취약한 작업이다. 같은 알고리즘이라도 촬영 각도, 조명 위치, 표면 재질에 따라 결과가 극단적으로 달라진다. 이 때문에 최종 공정에서는 항상 반사 강도 등급을 먼저 분류한 후, 그에 맞는 처리 경로를 선택하도록 설계했다. 하나의 모델이나 하나의 규칙으로 모든 이미지를 처리하려는 시도는 반복적으로 실패했다.


8. 데스크톱과 모바일 환경에서의 시각적 착시 문제

흥미로운 문제는 디바이스에 따라 반사 제거 결과의 인상이 달라진다는 점이었다. 모바일에서는 자연스럽게 보이던 결과가, 데스크톱 대형 모니터에서는 얼룩처럼 인식되는 경우가 많았다. 이후 검수 기준은 항상 **가장 엄격한 환경(고해상도 모니터)**을 기준으로 설정했고, 모바일 최적화는 그 다음 단계로 분리했다.


9. 반사 제거에서 인간 판단이 개입해야 하는 이유

반사는 때로는 제거 대상이 아니라, 맥락 정보가 되기도 한다. 예를 들어 쇼윈도 반사는 “실내 촬영이 아님”을 알려주는 단서가 된다. 이런 경우 반사를 완전히 제거하면 이미지의 의미가 바뀐다. 그래서 최종 단계에서는 항상 “이 반사가 정보인가, 방해인가”를 사람이 판단할 수 있도록 중간 결과를 남기는 구조를 유지했다.


10. 현장에서 얻은 가장 실용적인 기준

여러 실패를 거치며 정립한 기준은 단순했다.
반사를 없애는 것이 목표가 아니라, 사용 목적에 맞는 수준으로만 제어하는 것이 목표라는 점이다. OCR, 객체 인식, 시각적 검수 등 목적이 달라지면 반사 제거의 정답도 달라진다. 이 기준을 명확히 하지 않으면 기술은 쉽게 과도해진다.


11. 결론: 반사 제거는 기술 문제가 아니라 선택의 문제다

Python으로 이미지 반사/글레어 제거를 구현하며 느낀 점은, 이 작업이 결코 “정답이 있는 문제”가 아니라는 사실이다. 어느 수준까지 개입할 것인지, 무엇을 남길 것인지를 결정하는 과정이 전체 결과를 좌우한다. 반사 제거는 알고리즘보다 판단 기준을 설계하는 능력이 더 중요하며, 그 기준은 항상 실제 사용 환경에서 검증되어야 한다.