Block Matching 알고리즘을 사용하여 Dense Optical Flow를 계산하면서, 가우시안 피라미드(Gaussian Pyramid)를 5 레벨로 구성하여 성능을 개선하는 방법을 구현할 수 있습니다. 가우시안 피라미드는 이미지의 여러 레벨에서의 흐름을 계산하여 보다 정확한 Optical Flow를 추정하는 데 도움이 됩니다.
아래는 Block Matching 방법을 사용하여 Dense Optical Flow를 계산하고, 가우시안 피라미드를 5 레벨로 구성하는 Python 코드입니다. OpenCV의 cv2.calcOpticalFlowBM을 사용하여 각 피라미드 레벨에서 Optical Flow를 계산한 후, 상위 레벨로의 흐름을 보간하여 최종 Optical Flow를 생성합니다.
### **Python 코드 예제**
```python
import cv2
import numpy as np
def build_gaussian_pyramid(image, levels=5):
pyramid = [image]
for i in range(1, levels):
image = cv2.pyrDown(image)
pyramid.append(image)
return pyramid
def calculate_block_matching_optical_flow(prev_pyramid, next_pyramid):
# Initialize flow with zeros
h, w = next_pyramid[0].shape
flow = [np.zeros((h, w, 2), np.float32) for _ in range(len(prev_pyramid))]
# Compute flow from the lowest resolution to the highest
for level in reversed(range(len(prev_pyramid) - 1)):
prev_img = prev_pyramid[level]
next_img = next_pyramid[level]
if level < len(prev_pyramid) - 1:
flow_up = cv2.pyrUp(flow[level + 1])
flow_up = cv2.resize(flow_up, (next_img.shape[1], next_img.shape[0]))
flow[level] = flow_up
# Calculate Optical Flow at this level
flow[level] = cv2.calcOpticalFlowBM(prev_img, next_img, blockSize=15, maxLevel=4,
criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 30, 0.01))
return flow[0]
def visualize_flow(flow):
magnitude, angle = cv2.cartToPolar(flow[..., 0], flow[..., 1])
hue = angle * 180 / np.pi / 2
saturation = np.ones_like(hue) * 255
value = cv2.normalize(magnitude, None, 0, 255, cv2.NORM_MINMAX)
hsv_img = np.zeros((flow.shape[0], flow.shape[1], 3), dtype=np.uint8)
hsv_img[..., 0] = hue
hsv_img[..., 1] = saturation
hsv_img[..., 2] = value
bgr_img = cv2.cvtColor(hsv_img, cv2.COLOR_HSV2BGR)
return bgr_img
# 비디오 또는 이미지 로드
cap = cv2.VideoCapture('video.mp4') # 비디오 파일 또는 웹캠 사용
# 첫 번째 프레임 읽기
ret, prev_frame = cap.read()
if not ret:
print("비디오를 읽는 데 실패했습니다.")
cap.release()
cv2.destroyAllWindows()
exit()
prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
# 비디오의 모든 프레임에 대해 Optical Flow 계산
while cap.isOpened():
ret, next_frame = cap.read()
if not ret:
break
next_gray = cv2.cvtColor(next_frame, cv2.COLOR_BGR2GRAY)
# Build Gaussian pyramids
prev_pyramid = build_gaussian_pyramid(prev_gray, levels=5)
next_pyramid = build_gaussian_pyramid(next_gray, levels=5)
# Optical Flow 계산
flow = calculate_block_matching_optical_flow(prev_pyramid, next_pyramid)
# Optical Flow를 시각화
flow_vis = visualize_flow(flow)
# 결과 표시
cv2.imshow('Dense Optical Flow', flow_vis)
if cv2.waitKey(30) & 0xFF == 27: # ESC 키를 누르면 종료
break
prev_gray = next_gray
cap.release()
cv2.destroyAllWindows()
```
### **코드 설명**
1. **`build_gaussian_pyramid` 함수**:
- 입력 이미지를 가우시안 피라미드를 구성합니다. 각 레벨에서 이미지의 크기를 줄여가며 피라미드를 생성합니다.
- `cv2.pyrDown`을 사용하여 이미지를 다운샘플링합니다.
2. **`calculate_block_matching_optical_flow` 함수**:
- 피라미드의 가장 낮은 레벨부터 가장 높은 레벨까지 Optical Flow를 계산합니다.
- `cv2.calcOpticalFlowBM`을 사용하여 각 피라미드 레벨에서 Optical Flow를 계산합니다.
- 상위 레벨로 이동하면서 흐름을 보간하고, 최종 Optical Flow를 추정합니다.
3. **`visualize_flow` 함수**:
- Optical Flow를 HSV 색상 공간으로 변환하여 시각화합니다.
- 흐름의 크기와 방향을 색상으로 변환하고, HSV 이미지를 BGR 이미지로 변환하여 시각화합니다.
4. **비디오 읽기 및 결과 표시**:
- 비디오 파일을 열고, 각 프레임에 대해 가우시안 피라미드를 사용하여 Block Matching Optical Flow를 계산하고 시각화하여 화면에 표시합니다.
- ESC 키를 눌러 프로그램을 종료합니다.
이 코드는 가우시안 피라미드를 사용하여 블록 매칭 기반의 Dense Optical Flow를 계산합니다. 이 방법은 다양한 스케일에서의 흐름을 고려하여 더 정확한 Optical Flow를 추정할 수 있습니다.
'개발자 > Computer Vision' 카테고리의 다른 글
Camera Geometry #0(Calibration) (0) | 2024.03.11 |
---|---|
[Tracking] 딥러닝 DNN 기반 트래킹 정리(2편 DeepSORT 알고리즘) - 작성중 (0) | 2023.11.24 |
[Tracking] 딥러닝 DNN 기반 트래킹 정리(1편 SORT 알고리즘) (3) | 2023.11.24 |
YUV Image 관련 정리 (0) | 2022.09.01 |
Object Detection -YOLO [복습] (0) | 2022.05.22 |