基于Python及OpenCV的光流实现

基于Python及OpenCV的光流实现

本文内容摘自 << Programming Computer Vision with Python >> 一书

1. 光流

光流是目标、场景或摄像机在连续两帧图像间运动时造成的目标的运动。它是图像在平移过程中的二维矢量场。

光流法主要依赖于三个假设:

  • 亮度很定。 图像中目标的像素强度在连续帧之间不会发生变化。
  • 时间规律。 相邻帧之间的时间足够短,以至于在考虑运行变化时可以忽略他们之间的差异。
  • 空间一致性。相邻像素具有相似的运动。

2. 基于Python及OpenCV的实现

import cv2
from numpy import *
from pylab import *


def draw_flow(im, flow, step=16):
    """在间隔分开的像素采样点处绘制光流"""
    h, w = im.shape[:2]
    y, x = mgrid[step / 2:h:step, step / 2:w:step].reshape(2, -1).astype(int)
    fx, fy = flow[y, x].T

    # 创建线的终点
    lines = vstack([x, y, x + fx, y + fy]).T.reshape(-1, 2, 2)
    lines = int32(lines)

    # 创建图像并绘制
    vis = cv2.cvtColor(im, cv2.COLOR_GRAY2BGR)
    for (x1, y1), (x2, y2) in lines:
        cv2.line(vis, (x1, y1), (x2, y2), (0, 255, 0), 1)
        cv2.circle(vis, (x1, y1), 1, (0, 255, 0), -1)

    return vis


if __name__ == '__main__':
    # 设置视频捕获
    # cap = cv2.VideoCapture(r"E:\data\vidoe.avi")    # 使用本地视频
    cap = cv2.VideoCapture(0)                         # 使用摄像头

    ret, im = cap.read()
    prev_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)  # 获取灰度图像

    while True:
        ret, im = cap.read()
        gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)

        # 计算流
        flow = cv2.calcOpticalFlowFarneback(prev_gray, gray, None, 0.5, 3, 15, 3, 5, 1.2, 0)
        prev_gray = gray

        # 画出流矢量
        cv2.imshow('Optical flow', draw_flow(gray, flow))

        if cv2.waitKey(10) == 27:
            break

运行效果
光流

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是基于PythonOpenCV实现法的代码示例: ```python import cv2 # 读取视频 cap = cv2.VideoCapture('video.mp4') # 创建 ShiTomasi 角点检测器参数 feature_params = dict(maxCorners=100, qualityLevel=0.3, minDistance=7, blockSize=7) # 创建 Lucas-Kanade 法参数 lk_params = dict(winSize=(15, 15), maxLevel=2, criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03)) # 随机颜色 color = (0, 255, 0) # 读取第一帧 ret, old_frame = cap.read() # 转换为灰度图像 old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY) # 获取角点 p0 = cv2.goodFeaturesToTrack(old_gray, mask=None, **feature_params) # 创建掩膜 mask = np.zeros_like(old_frame) while True: # 读取当前帧 ret, frame = cap.read() # 转换为灰度图像 frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 计算 p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params) # 选择好的点 good_new = p1[st == 1] good_old = p0[st == 1] # 绘制轨迹 for i, (new, old) in enumerate(zip(good_new, good_old)): a, b = new.ravel() c, d = old.ravel() mask = cv2.line(mask, (a, b), (c, d), color, 2) frame = cv2.circle(frame, (a, b), 5, color, -1) img = cv2.add(frame, mask) # 显示图像 cv2.imshow('frame', img) # 更新上一帧的图像和点 old_gray = frame_gray.copy() p0 = good_new.reshape(-1, 1, 2) # 按下 ESC 键退出 k = cv2.waitKey(30) & 0xff if k == 27: break # 释放资源 cap.release() cv2.destroyAllWindows() ``` 这段代码实现了对视频的法处理,可以通过读取视频文件,检测角点并计算,最后绘制轨迹并显示处理后的图像。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值