Python/Vision Code

[OpenCV + Numpy] Film Grain 효과 추가 예제 코드

jimmy_AI 2025. 9. 27. 01:34
반응형

안녕하세요.

이번 글에서는 이미지에 필름 그레인 효과를 OpenCV와 Numpy를 활용하여

추가해보는 간단한 예제 코드를 다루어보도록 하겠습니다.

 

코드 스니펫 예시는 다음과 같습니다.

import cv2
import numpy as np
import argparse

def add_film_grain(
    img_bgr: np.ndarray,
    amount: float = 0.06,      # 전체 그레인 강도 (0.0~0.3 권장)
    size: float = 1.2,         # 입자(노이즈) 스케일; 클수록 거칠고 큼
    monochrome: bool = True,   # True면 흑백 그레인(영화 느낌), False면 컬러 그레인
    shadow_boost: float = 0.6, # 그림자 영역 가중치(0~1+, 높을수록 그림자에 그레인 증가)
    highlight_protect: float = 0.35 # 하이라이트 억제(0~1, 높을수록 밝은 영역에 덜 적용)
) -> np.ndarray:
    """
    input / output 이미지는 모두 BGR 및 0~255 스케일 가정
    """

    img = img_bgr.astype(np.float32) / 255.0
    h, w, c = img.shape

    # sRGB luma (밝기) 계산: 그레인을 톤에 따라 가중
    luma = 0.2126 * img[:, :, 2] + 0.7152 * img[:, :, 1] + 0.0722 * img[:, :, 0]

    # 톤 가중치: 하이라이트 보호 + 그림자 부스트
    w_hi = 1.0 - (luma ** (1.0 + 2.0 * np.clip(highlight_protect, 0, 1)))
    w_sh = 0.6 + shadow_boost * (1.0 - luma)
    tone_weight = np.clip(w_hi * w_sh, 0.0, 1.5).astype(np.float32)

    # 노이즈 생성 (흑백/컬러)
    if monochrome:
        noise = np.random.normal(0.0, 1.0, (h, w, 1)).astype(np.float32)
        noise = np.repeat(noise, 3, axis=2)
    else:
        noise = np.random.normal(0.0, 1.0, (h, w, 3)).astype(np.float32)

    # 그레인 입자 크기 조절: 가우시안 블러로 거칠게
    if size > 0:
        noise = cv2.GaussianBlur(noise, (0, 0), sigmaX=size, sigmaY=size)

    # 톤 가중치 적용
    noise *= (amount * tone_weight[..., None])

    # 원본 이미지에 합성
    out = np.clip(img + noise, 0.0, 1.0)

    return (out * 255.0 + 0.5).astype(np.uint8)

 

예시로 다음과 같은 풍경 이미지에 film grain을 직접 추가해보도록 하겠습니다.

(이미지 출처: pixabay)

 

이미지에 위에서 구현한 film grain 함수를 적용하는 예시 코드는 다음과 같습니다.

img = cv2.imread("image.jpg", cv2.IMREAD_COLOR)

output_bgr = add_film_grain(img, amount=0.05, size=0.3)

output_rgb = cv2.cvtColor(output_bgr, cv2.COLOR_BGR2RGB) # 이 부분이 결과 이미지

 

amount 값을 0.05에서 0.1로 올리면 아래와 같은 효과로 바뀌게 됩니다.

 

다양한 파라미터 값을 시도해 보시면서 원하시는 이미지에 적합한 효과를 찾아보세요.

이 글의 내용이 film grain 효과 적용 과정에 도움이 되셨기를 기원합니다.

감사합니다.