Pixel Processing: 화소 접근 및 밝기/명암비 조절

minho-log·2026년 3월 31일

OpenCV

목록 보기
3/3

<공부 주제>

영상 내 개별 화소(Pixel) 데이터 접근법 및 산술 연산을 통한 밝기 제어

<공부한 내용 정리>

OpenCV 영상은 결국 uint8 형식을 갖는 행렬이다. 이 행렬의 각 원소(화소) 값을 수정하면 영상의 밝기를 밝게 하거나 어둡게 만들 수 있다.
1. 화소 접근 (Pixel Access)
배열 인덱싱: img[y, x] 형태로 특정 위치의 픽셀 값에 접근한다.
BGR 구조: 컬러 영상의 경우 img[y, x]는 [B, G, R] 세 개의 값을 가진 리스트 형태다.
2. 밝기 조절 (Brightness)
영상의 모든 화소에 일정 값을 더하면 밝아지고, 빼면 어두워진다.
Overflow 주의: uint8 자료형은 00 ~ 255255 사이만 표현한다. 250+10250 + 10260260이 아닌 44(나머지값)가 되지 않도록 포화 연산(Saturation) 처리가 필수다.
3. 명암비(Contrast) 조절
영상의 밝은 부분과 어두운 부분의 차이를 크게 만드는 것이다.
보통 픽셀 값에 특정 상수를 곱하여 조절한다.

<예제 / 실습 코드>

영상의 밝기를 전체적으로 높이고, 포화 연산을 적용하는 실습.
1. 밝기 조절 및 산술 연산 (brightness_test.py)
Python

import cv2
import numpy as np

# 영상 불러오기 (Grayscale로 테스트)
src = cv2.imread('lenna.jpg', cv2.IMREAD_GRAYSCALE)

if src is None:
    print("이미지를 찾을 수 없습니다.")
    exit()

# 1. 단순 더하기 (Numpy 연산 - Overflow 위험 있음)
# 255를 넘어가면 다시 0부터 시작해서 이상한 무늬가 생김
dst_bad = src + 100

# 2. OpenCV 포화 연산 함수 사용 (권장)
# 255를 넘으면 255로 고정해줌
dst_good = cv2.add(src, 100)

# 3. 명암비 조절 (픽셀 값에 2.0 곱하기)
dst_contrast = cv2.multiply(src, 2.0)

cv2.imshow('Original', src)
cv2.imshow('Bad Brightness (Numpy)', dst_bad)
cv2.imshow('Good Brightness (OpenCV)', dst_good)
cv2.imshow('Contrast High', dst_contrast)

cv2.waitKey(0)
cv2.destroyAllWindows()

<헷갈렸던 점>

Numpy 연산 vs OpenCV 함수: src + 100처럼 넘파이 배열 연산을 직접 쓰면 255255를 초과할 때 값이 튀어버리는(Modulo 연산) 현상이 발생한다. 영상 처리를 할 때는 반드시 cv2.add()나 np.clip()을 사용해 값을 가둬줘야 한다는 점을 배웠다.
데이터 타입: 연산 과정에서 일시적으로 255255를 넘거나 음수가 될 수 있으므로, 복잡한 연산 시에는 float32로 변환했다가 다시 uint8로 바꾸는 과정이 필요할 수 있음을 알게 되었다.

<오늘의 정리>

영상의 밝기는 화소 값의 덧셈/뺄셈, 명암비는 곱셈으로 조절한다.
값의 범위가 00 ~ 255255를 벗어나지 않도록 포화 연산(Saturation)을 적용해야 한다.
OpenCV의 cv2.add(), cv2.subtract() 함수는 내부적으로 포화 연산을 처리해준다.

profile
개발 공부를 하며 직접 부딪히고 공부한 것을 기록합니다.

0개의 댓글