본문으로 건너뛰기

M12.01 · OpenCV 영상·색공간·필터·특징

단위별 목표·권장 선수와 자료 준비 상태를 확인하고, 공개된 본문과 활동을 읽고 준비 상태를 확인할 수 있습니다.

전체 커리큘럼

학습 안내

본문을 읽고 장비 없는 기본 실습·세 확인 문제와 해설로 이해를 확인하세요.

예상 학습 시간: 미정. 이 페이지 방문이나 자료 열람으로 완료·숙달을 자동 부여하지 않습니다.

현재 경로·이전·다음 단위 확인 ↓

학습 목표

  • 영상의 행/열/채널·색 순서·값 범위와 dtype을 해석하여 입력 변환 오류를 진단한다.
  • 명시한 경계 규약의 평균/중앙값 필터와 차분을 계산하고 잡음 제거와 특징 손실의 차이를 설명한다.
  • 영상 특징과 실제 물체/기하 위치를 구분하고 반복 무늬·저대비·가림에서 필요한 추가 검사를 제안한다.

아래 설명·실습·문제로 각 학습 목표를 확인하세요.

권장 선수

일반 Python 코딩과 M01.02의 배열·shape·dtype 계약을 사용한다. 픽셀 축·경계·이웃 연산과 출력 의미는 본문에서 보충한다. 고전적 영상 처리 입문에 신경망 학습·평가나 3D 회전 단원 전체를 선수로 요구하지 않는다. 기본은 합성 픽셀 계산이며 선택 NumPy 코드는 개념 연산만 실행한다. OpenCV/카메라 실제 실행과 구분한다. 이미 알고 있다면 직접 열어볼 수 있습니다.

설명 필수

세 목표에 대응하는 검수된 설명·예제를 읽습니다.

영상 배열을 먼저 읽는다

컬러 영상은 흔히 높이 H/너비 W/채널 C의 배열이다. H는 행 수, W는 열 수이며 C=3은 세 색 성분을 뜻할 수 있다. 픽셀 좌표를 가로 u/세로 v로 쓰면 배열 접근은 image[v,u] 순서다. 가로/세로와 행/열을 바꾸면 같은 shape의 정사각형 영상에서도 다른 점을 읽는다. 여러 영상의 batch나 채널 우선 배열은 별도 축 계약이므로 모양만 보고 추정하지 않는다.

영상 좌표와 배열 인덱스: 픽셀 좌표 (u, v) → 배열 image[v, u] → 색 채널 계약 → 변환 뒤 검사.그림 원본 크기로 보기

그림 M12.01-1. 각 칸은 서로 다른 역할/근거다. 나란히 비교할 항목이며 위아래가 시간 순서를 뜻하지 않는다. 직접 제작한 개념도이며 본문의 조건과 함께 읽는다.

OpenCV의 일반적인 imread 컬러 경로는 BGR 순서를 쓴다. RGB를 기대하는 모델/표시기로 옮길 때 cvtColor의 변환 코드를 명시한다. 공식 색변환 문서의 COLOR_BGR2RGB와 COLOR_BGR2GRAY 등은 이 입력 의미의 일부다. ‘모든 영상은 BGR’이라는 뜻은 아니며 ROS Image.encoding이나 외부 라이브러리 출력 계약도 따로 확인한다. 파일 읽기가 실패하면 빈 값을 다음 연산에 넘기기 전에 경로/형식과 읽기 결과를 검사한다.

색 순서 오류는 단순한 모양 오류처럼 즉시 예외가 나지 않을 수 있다. 회색 변환의 가중 합을 G=0.299R+0.587G_c+0.114B라고 하자. 여기서 G는 회색 출력, G_c는 입력 초록 성분으로 구분한다. RGB[255,0,0]을 올바르게 읽은 부동소수 합은 76.245다. 같은 배열을 BGR로 오해하면 파란색이라 29.07이 된다. 두 값은 정수 반올림 전 계산이며 실제 OpenCV의 정수 구현을 실행해 얻은 결과라고 쓰지 않는다. 이 회색 가중합을 곧바로 물리 조도나 선형 광량 측정값으로 해석하지도 않는다.

HSV는 hue/채도/명도 성분으로 색을 표현하는 방식이다. 일반 uint8 COLOR_BGR2HSV 경로의 H는 0~179, S/V는 0~255 범위다. 다른 dtype/변환 코드·소프트웨어는 범위가 다를 수 있다. H의 양 끝은 색상환에서 이어지므로 빨강처럼 경계를 가로지르는 색은 한 연속 범위만으로 잡기 어려울 수 있다. 저채도에서 hue만으로 안정된 색을 판단하거나 조명/노출이 달라도 같은 threshold가 통한다고 가정하지 않는다.

정수 산술과 수치 범위는 다르다

uint8은 0~255를 저장한다. dtype을 float로 바꾸는 것과 값을 255로 나누어 0~1로 정규화하는 것은 다른 연산이다. NumPy uint8 배열끼리 250+10을 계산하면 랩어라운드로 4가 될 수 있지만, OpenCV의 uint8 add는 포화시켜 255로 만든다. 넓은 정수형으로 바꿔 더하면 260을 보존한다. 공식 산술 비교처럼 같은 덧셈 기호라도 소비자/자료형 규칙을 확인한다.

차분에 음수가 필요할 때도 uint8 결과만 보면 부호를 잃을 수 있다. 먼저 적절한 signed/float 형식으로 변환하고 계산한 다음 표시용 범위 변환을 별도로 한다. 색/범위 오류는 필터나 모델을 더 크게 만들어 해결할 문제가 아니다. 원본 encoding과 dtype/범위, 변환 순서, 모델이 기대하는 채널/정규화를 기록한다.

필터는 어떤 정보를 희생하는가

필터는 이웃 픽셀을 결합해 새 값을 만든다. 평균은 작은 변동을 줄일 수 있지만 경계도 퍼뜨린다. 중앙값 median은 창 안 값을 정렬한 가운데 값을 쓰므로 고립된 극단값에 덜 끌릴 수 있다. 어느 쪽이 좋은지는 잡음과 과제에 달려 있다. 공식 필터 자료의 함수에는 kernel/출력 dtype/경계 처리 규약이 있으므로 결과를 비교할 때 함께 맞춘다.

종이 예제는 1차원 float 신호 x=[0,0,90,0,0], 창 크기 3, stride=1의 valid 모드를 쓴다. valid는 창이 완전히 들어가는 위치만 계산하여 경계 바깥 값을 보충하지 않는 규약이다. OpenCV의 기본 경계 처리와 동일하다고 주장하지 않는다. 창[0,0,90]/[0,90,0]/[90,0,0]의 평균은 모두 30, 중앙값은 모두 0이다. 90이 잡음이면 중앙값이 유용할 수 있지만 작은 밝은 표식이었다면 없애 버린 실패다.

변형 신호[0,0,90,90,90]은 경계가 있는 계단이다. 평균은[30,60,90]으로 경계를 퍼뜨리고 중앙값은[0,90,90]이다. 필터 크기를 키워 매끈해졌다는 이유만으로 물체 위치 정확도가 좋아졌다고 보지 않는다. 얇은 차선/작은 표식 보존과 잡음 제거를 함께 평가한다.

원래 신호의 인접 차분 d_i=x_(i+1)−x_i는[0,90,−90,0]이다. i는 왼쪽부터 0으로 세는 인덱스이며 d_i는 픽셀i와i+1 사이의 밝기 변화다. |d_i|≥50이면 두 위치가 후보가 되지만 이것이 물체 두 개라는 뜻은 아니다. 한 밝은 점의 양쪽 경계일 수 있다. 실제 2차원 Sobel/Canny와 같은 전체 알고리즘을 이 한 식으로 재현한 것도 아니다.

특징은 대응을 위한 단서다

edge는 한 방향의 밝기 변화, corner는 여러 방향으로 옮겼을 때 주변 밝기 패턴이 달라지는 지점으로 이해할 수 있다. 평평한 단색 영역은 위치를 조금 옮겨도 비슷하고 긴 직선 경계는 선 방향의 이동을 구분하기 어려울 수 있다. 공식 Harris 자료는 주변 변화로 corner/edge/평탄 영역을 구분하는 이유를 설명한다. 특징의 점수는 이 정의의 반응이지 물체 종류나 3차원 깊이의 측정값이 아니다.

descriptor는 특징점 주변의 모양/밝기 패턴을 비교 가능한 수치 벡터나 이진 부호 등으로 요약한 표현이다. descriptor 거리는 정한 비교 규칙의 비유사도이며, 작다고 같은 물리점이 확정되는 것은 아니다. 특징점/descriptor를 이용해 다른 영상과 대응할 수 있지만 반복 무늬에서는 서로 다른 점이 비슷할 수 있다. 조명 변화·흐림·가림·크기 변화로 특징이 사라지거나 잘못 짝지어질 수도 있다. 대응의 기하 일관성/시간 연속성·외부 보정이나 추가 센서로 확인해야 한다. corner가 많다는 사실만으로 추적 성공을 선언하지 않는다. 프레임 번호/시각·좌표/색 변환·필터와 특징 설정·거부된 대응도 기록한다. 기존 4.1 영상 좌표와 연결해 픽셀의 단서와 공간 기하를 나누어 본다.

선택 CPU 개념 확인

작성 시 cv2는 로컬에 없으므로 실제 OpenCV 함수를 실행하지 않았다. 아래 완전 코드는 Darwin/NumPy 2.4.4 CPU에서 실행한 개념 대체 경로다. valid 평균/중앙값/차분과 정수 범위만 확인하며 OpenCV의 경계/정수 반올림을 검증하지 않는다.

import numpy as np

x = np.array([0, 0, 90, 0, 0], dtype=np.float64)
print("mean", np.convolve(x, np.ones(3) / 3, mode="valid").tolist())
print("median", [float(np.median(x[i:i+3])) for i in range(3)])
print("diff", np.diff(x).tolist())
a = np.array([250], dtype=np.uint8)
b = np.array([10], dtype=np.uint8)
print("uint8", (a + b).tolist())
print("wide", (a.astype(np.int16) + b.astype(np.int16)).tolist())
mean [30.0, 30.0, 30.0]
median [0.0, 0.0, 0.0]
diff [0.0, 90.0, -90.0, 0.0]
uint8 [4]
wide [260]

학습 범위와 한계

기본 설명·예제가 준비되었습니다. 기존 보충 자료의 범위와 구별하세요.

실습 필수

장비 없는 실습을 수행하고 관찰·계산 근거를 해설과 비교합니다.

입력은 RGB[255,0,0], HWC 영상과 픽셀(u=2,v=1), 위 두 신호와 valid 필터, 반복 체크무늬의 특징 대응이라는 가상 상황이다.

  1. 배열 접근/색 순서·회색 합과 uint8 산술 차이를 계산한다. HSV 범위가 어떤 계약인지 설명한다.
  2. 두 신호의 평균/중앙값과 원래 신호의 차분 후보를 계산한다. 90을 잡음/표식으로 본 판정 차이를 적는다.
  3. 반복 무늬에서 높은 corner 점수만으로 대응/물체 위치를 승인할 수 있는지 설명하고 추가 확인/실패 기록을 제안한다.

관찰은 영상 계약·필터 계산·특징 판단으로 나눈다. 막히면 색 성분 이름을 붙인 뒤 계산하고, valid 창을 세 개 직접 그린다. 카메라나 OpenCV 설치는 필요하지 않다.

0 / 8,000자 · 확인하면 이 브라우저에 저장

답안을 작성하고 확인하기를 한 번 선택하면 해설·판정 기준을 열어볼 수 있습니다.

학습 범위와 한계

기본 실습은 장비 없이 수행합니다. 실제 장비·GPU 실증을 완료했다는 뜻은 아닙니다.

평가·해설 필수

목표별 세 서술문항에 답하고 해설·판정 기준으로 자기검토합니다.

확인 문제 Q1

HWC 영상의 가로 u=3/세로 v=2는 어떤 배열 인덱스인가? RGB[255,0,0]을 BGR로 오해하면 색 의미가 어떻게 달라지는가? uint8 덧셈과 float 변환/0~1 정규화도 구분하라.

0 / 8,000자 · 확인하면 이 브라우저에 저장

답안을 작성하고 확인하기를 한 번 선택하면 해설·판정 기준을 열어볼 수 있습니다.

확인 문제 Q2

신호[0,60,0] 하나의 3칸 valid 창에서 평균/중앙값을 구하라. 60이 작은 표식인 경우 중앙값 결과를 좋은 잡음 제거라고 확정할 수 있는가?

0 / 8,000자 · 확인하면 이 브라우저에 저장

답안을 작성하고 확인하기를 한 번 선택하면 해설·판정 기준을 열어볼 수 있습니다.

확인 문제 Q3

체크무늬에서 비슷한 특징이 여러 개 검출됐고 한 쌍의 descriptor 거리가 작다. 같은 실제 점이며 깊이까지 알았다고 할 수 있는가? 추가 검증과 실패 조건을 제안하라.

0 / 8,000자 · 확인하면 이 브라우저에 저장

답안을 작성하고 확인하기를 한 번 선택하면 해설·판정 기준을 열어볼 수 있습니다.

학습 범위와 한계

서술답안과 해설이 준비되었습니다. 자기검토와 학습 완료는 숙달 인증과 별개입니다.

참고 자료

학습 확인

실습과 세 문항의 답안을 해설과 비교한 뒤, 이 단위의 학습 완료를 직접 기록할 수 있습니다. 자기검토·학습 완료는 자동 채점이나 숙달 인증과 별개입니다.

실습1개·확인 문제3개의 답안을 저장하고 각각 자기검토를 기록하세요.

학습 이동

학습 단계 순서 · 공통 과정 이후 전문화 선택

전체 목차로 돌아가기 →

신규 활동의 답안은 이 브라우저의 통합 학습 기록에 저장합니다. 기존 화면의 답안·진도는 원래 키를 유지합니다. AI 강사는 현재 단위의 준비 상태·부족한 범위와 연결된 실제 자료를 참고합니다.