MJPEG(Motion JPEG): 영상의 각 프레임을 JPEG 이미지로 압축해 연속 전송하는 방식.
ESP32 ──[JPEG_1]──[JPEG_2]──[JPEG_3]──...──→ 노트북
매초 약 20장
브라우저에서 http://[ESP32_IP]/stream에 접속하면 영상이 보입니다.
OpenCV에서 영상은 NumPy 배열입니다.
shape: (240, 320, 3)
높이 너비 채널(BGR)
frame[100, 200] → [B, G, R] 값frame[100, 200, 2] → R 채널만| 색공간 | 채널 | 장점 | 단점 |
|---|---|---|---|
| BGR | 파랑·초록·빨강 | 직관적 | 조명 변하면 모든 채널이 동시에 변함 |
| HSV | 색상·채도·명도 | 조명에 강함 (H가 안 변함) | 직관 약함 |
차선 인식에서는 HSV가 압도적으로 유리합니다. 흰색 차선을 "밝기 200 이상, 채도 30 이하"로 정의하면 조명이 어두워져도 잘 잡힙니다.
ESP32 영상 (BGR 320x240)
↓ cv2.flip(frame, 1) # 좌우 미러링 (카메라 설치 방향 보정)
↓ cv2.cvtColor(BGR2HSV)
↓ ROI 잘라내기 (하단 50%)
↓ HSV 마스크 적용
↓ 윤곽선 검출
→ 차선 중심점 좌표
import cv2
img = cv2.imread('test.jpg')
cv2.imshow('Window Name', img)
cv2.waitKey(0) # 키 입력 대기
cv2.destroyAllWindows()
cap = cv2.VideoCapture('http://192.168.137.74/stream')
while True:
ret, frame = cap.read()
if not ret:
break
cv2.imshow('ESP32-CAM', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
import numpy as np lower = np.array([0, 0, 200]) # 흰색 하한 (H, S, V) upper = np.array([180, 30, 255]) # 흰색 상한 mask = cv2.inRange(hsv, lower, upper) # mask는 흑백 영상: 흰색=조건 만족, 검정=불만족
result = cv2.bitwise_and(frame, frame, mask=mask) # result는 마스크 흰 부분만 원본, 나머지는 검정
학생용 프로그램 단계6_영상표시.py를 실행:
q를 눌러 종료관찰 기록: 영상의 해상도는? FPS는? (초당 몇 장?)
영상을 4분할로 표시하는 프로그램을 작성하시오.
┌──────────┬──────────┐ │ 원본(BGR)│ H 채널 │ ├──────────┼──────────┤ │ S 채널 │ V 채널 │ └──────────┴──────────┘
힌트:
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)
top = np.hstack([frame, cv2.cvtColor(h, cv2.COLOR_GRAY2BGR)])
bottom = np.hstack([cv2.cvtColor(s, cv2.COLOR_GRAY2BGR),
cv2.cvtColor(v, cv2.COLOR_GRAY2BGR)])
combined = np.vstack([top, bottom])
cv2.imshow('Channels', combined)
관찰 질문
다음 색을 추출하는 마스크를 만들고, 마스크가 잘 작동함을 확인하시오.
| 도전 | 추출 대상 |
|---|---|
| 1 | 본인 손바닥 (살색) |
| 2 | 빨간 색종이 |
| 3 | 형광 노란색 마커 |
| 색 | H 하한 | H 상한 | S 하한 | V 하한 |
|---|---|---|---|---|
| 살색 | ||||
| 빨강 | ||||
| 형광노랑 |
| 개념 | 설명 |
|---|---|
| MJPEG | 프레임을 JPEG로 압축해 연속 전송 |
| ROI | Region of Interest, 관심 영역 |
| BGR | OpenCV의 기본 색 순서 (파랑-초록-빨강) |
| HSV | 색상-채도-명도 색공간 (조명에 강함) |
| 마스크 | 조건을 만족하는 픽셀만 흰색으로 표시한 흑백 영상 |
cv2.inRange | HSV 범위로 마스크 생성 |
cv2.bitwise_and | 마스크와 원본을 결합 |
| 항목 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
| ESP32 영상을 노트북에 띄울 수 있다 | |||||
| HSV의 의미를 설명할 수 있다 | |||||
cv2.inRange로 색상 마스크를 만들 수 있다 | |||||
| 동료와 마스크 결과를 비교·논의했다 |