15장. 비디오 처리와 실시간 영상처리
프레임마다 처리하기
공장의 포장 줄에서는 상자가 하나 올 때마다 같은 일을 합니다. 상자를 받고, 테이프를 붙이고, 송장을 붙이고, 다음 줄로 넘깁니다. 상자가 더 오지 않으면 줄을 멈춥니다. 동영상 처리의 반복도 이렇게 생겼습니다.
그림의 둘째 단계 "끝인가"에서 ok 가 False 면 반복을 빠져나와 닫기로 가고, True 면 처리와 쓰기를 한 뒤 다시 읽기로 돌아갑니다. 여기서 상자가 프레임이고, 테이프와 송장 붙이기가 흑백 바꾸기·블러·Canny 같은 처리이고, 다음 줄로 넘기는 일이 녹화기에 쓰거나 결과를 리스트에 모으는 일입니다.
그림은 30번 프레임 한 장에 3장의 흑백 바꾸기, 6장의 Gaussian 블러, 11장의 Canny 를 차례로 건 결과입니다. 동영상 처리는 이 한 장의 처리를 80장 모두에 되풀이하는 것뿐입니다.
앞 장의 처리를 프레임에 걸기
| 처리 | 코드 | 배운 곳 |
|---|---|---|
| 흑백 바꾸기 | cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) | 3장 |
| 흐리게 하기 | cv2.GaussianBlur(gray, (5, 5), 0) | 6장 |
| 이진화 | cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) | 8장 |
| 모폴로지 | cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel) | 9장 |
| 경계 찾기 | cv2.Canny(blur, 50, 150) | 11장 |
import cv2
cap = cv2.VideoCapture("ch15_conveyor.mp4")
means = []
while True:
ok, frame = cap.read()
if not ok: # 다 읽었으면 반복을 끝낸다
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
means.append(float(gray.mean())) # 장마다 평균 밝기를 모은다
cap.release()
print("처리한 프레임:", len(means)) # 결과: 80
print("첫 장과 끝 장의 평균 밝기:", round(means[0], 1), round(means[-1], 1))주의할 점
- 반복 안에서 무거운 일을 하면 장 수만큼 곱절로 느려집니다. 커널이나 구조 요소처럼 장마다 똑같은 것은 반복 밖에서 한 번만 만들어 둡니다.
- 처리한 결과를 모두 리스트에 담지 말고 필요한 숫자(평균 밝기, 비율)만 모으면 메모리를 아낍니다.