方法 |
优点 |
适用场景 |
缺点 |
光流法 |
实时性强、支持稠密方向分析 |
视频流中物体整体运动 |
对背景复杂场景鲁棒性差 |
特征点跟踪 |
精确捕捉局部运动 |
特征点明显的物体 |
特征点丢失影响结果 |
帧间差分 |
简单快速,适合实时检测 |
背景稳定、低复杂度场景 |
对噪声和阴影敏感 |
深度摄像头 |
三维方向检测,抗背景干扰能力强 |
需要深度信息的场景 |
需要特殊硬件,成本较高 |
惯性传感器 |
不依赖视觉,适用环境广泛 |
设备本体的运动分析 |
精度受传感器噪声影响 |
机器学习 |
能适应复杂非线性场景 |
复杂场景,非规则运动 |
数据需求高,训练成本高 |
背景建模 |
对静态背景场景鲁棒性好 |
固定背景的视频监控 |
背景变化会降低精度 |
import cv2
import numpy as np
# Parameters for Lucas-Kanade optical flow
lk_params = dict(winSize=(15, 15), maxLevel=2,
criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
# Initialize video capture
cap = cv2.VideoCapture("input_video.mp4")
# Capture the first frame and detect Shi-Tomasi corners
ret, old_frame = cap.read()
if not ret:
print("Failed to read video.")
cap.release()
exit()
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)
p0 = cv2.goodFeaturesToTrack(old_gray, mask=None, maxCorners=100, qualityLevel=0.3, minDistance=7, blockSize=7)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Calculate optical flow
p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)
# Select good points
good_new = p1[st == 1]
good_old = p0[st == 1]
# Draw tracks
for (new, old) in zip(good_new, good_old):
a, b = new.ravel()
c, d = old.ravel()
cv2.arrowedLine(frame, (c, d), (a, b), (0, 255, 0), 2)
# Display the result
cv2.imshow("Feature Point Tracking", frame)
# Update the previous frame and points
old_gray = frame_gray.copy()
p0 = good_new.reshape(-1, 1, 2)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
import cv2
cap = cv2.VideoCapture("input_video.mp4")
ret, prev_frame = cap.read()
if not ret:
print("Failed to read video.")
cap.release()
exit()
prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Frame difference
diff = cv2.absdiff(prev_gray, gray)
# Threshold and find contours
_, thresh = cv2.threshold(diff, 25, 255, cv2.THRESH_BINARY)
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
if cv2.contourArea(contour) > 500:
x, y, w, h = cv2.boundingRect(contour)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# Display the result
cv2.imshow("Frame Difference", frame)
prev_gray = gray.copy()
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
import cv2
import pyrealsense2 as rs # Requires Intel RealSense SDK
# Initialize RealSense pipeline
pipeline = rs.pipeline()
config = rs.config()
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
pipeline.start(config)
try:
while True:
# Get frames
frames = pipeline.wait_for_frames()
depth_frame = frames.get_depth_frame()
color_frame = frames.get_color_frame()
if not depth_frame or not color_frame:
continue
depth_image = np.asanyarray(depth_frame.get_data())
color_image = np.asanyarray(color_frame.get_data())
# Visualize depth and motion direction (simple demo)
cv2.imshow("Color Image", color_image)
cv2.imshow("Depth Image", depth_image)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
finally:
pipeline.stop()
cv2.destroyAllWindows()
from sense_hat import SenseHat # For Raspberry Pi with Sense HAT
sense = SenseHat()
while True:
accel = sense.get_accelerometer_raw()
x = accel['x']
y = accel['y']
z = accel['z']
print(f"Acceleration -> X: {x:.2f}, Y: {y:.2f}, Z: {z:.2f}")
if abs(x) > 0.5:
print("Device moving in X direction")
if abs(y) > 0.5:
print("Device moving in Y direction")
# Add a short delay
time.sleep(0.1)
import cv2
cap = cv2.VideoCapture("input_video.mp4")
# Initialize background subtractor
fgbg = cv2.createBackgroundSubtractorMOG2()
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
fgmask = fgbg.apply(frame)
# Find contours
contours, _ = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
if cv2.contourArea(contour) > 500:
x, y, w, h = cv2.boundingRect(contour)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# Display the result
cv2.imshow("Background Subtraction", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
利用深度学习框架(如PyTorch或TensorFlow)训练模型判断运动方向。这部分需要采集数据集并进行模型训练,属于更复杂的场景。
需要更多帮助,可针对具体方法详细展开!
python
复制代码
import cv2import numpy as np
# Parameters for optical flow
lk_params = dict(winSize=(15, 15), maxLevel=2,
criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
# Colors for drawing
color = (0, 255, 0) # Green for arrows
# Capture video
cap = cv2.VideoCapture("input_video.mp4") # Replace with 0 for webcam
# Read the first frame
ret, old_frame = cap.read()if not ret:
print("Failed to read video.")
cap.release()
exit()
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)
# Detect initial feature points
p0 = cv2.goodFeaturesToTrack(old_gray, mask=None, maxCorners=100, qualityLevel=0.3, minDistance=7, blockSize=7)
# Create a mask image for drawing purposes
mask = np.zeros_like(old_frame)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Calculate optical flow
p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)
# Select good points
if p1 is not None:
good_new = p1[st == 1]
good_old = p0[st == 1]
# Draw the tracks with arrows
for (new, old) in zip(good_new, good_old):
a, b = new.ravel()
c, d = old.ravel()
# Draw arrow
cv2.arrowedLine(mask, (int(c), int(d)), (int(a), int(b)), color, 2, tipLength=0.3)
# Overlay the mask on the frame
output = cv2.add(frame, mask)
# Display the result
cv2.imshow("Optical Flow with Arrows", output)
# Update the previous frame and points
old_gray = frame_gray.copy()
p0 = good_new.reshape(-1, 1, 2)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
光流计算:
方向显示:
绘制掩膜:
按键退出:
你可以调整以下参数以适应不同场景: