OpenCV 光流Optical Flow示例

yizhihongxing

下面是对于“OpenCV 光流Optical Flow示例”的完整攻略以及两个示例说明。

简介

Optical Flow是指在视频中的相邻两帧之间,在像素级别上计算出像素点在两帧之间的位移的技术。OpenCV是一个广泛使用的计算机视觉库,也支持光流技术。本攻略将介绍如何使用OpenCV进行光流分析。

步骤

  1. 安装OpenCV。

如果你还没有安装OpenCV,请先前往官方网站下载安装。

  1. 加载视频。

将视频加载到OpenCV中。

import cv2

cap = cv2.VideoCapture('path/to/video')
  1. 设置参数。

设置角点检测器的最大角点数,角点检测器的质量水平等等。

feature_params = dict(maxCorners=100, qualityLevel=0.3, minDistance=7, blockSize=7)
lk_params = dict(winSize=(15, 15), maxLevel=2, criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
color = (0, 255, 0)
  1. 计算光流。

计算相邻两帧之间的光流,并将其绘制到新图像中。

# 读取一帧
ret, old_frame = cap.read()
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)

# 寻找角点
p0 = cv2.goodFeaturesToTrack(old_gray, mask=None, **feature_params)

# 创建一个mask用来绘制轨迹
mask = np.zeros_like(old_frame)

# 循环读取视频并计算光流
while True:
    ret, frame = cap.read()
    if not ret:
        break
    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)

    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break

cv2.destroyAllWindows()
cap.release()

示例1

在这个示例中,我们模拟一个二维的均匀平移,它会随着时间的推移而减小。

import cv2
import numpy as np

# 创建画布
canvas = np.zeros((400, 400), dtype="uint8")

# 初始化变量
shift = 0
delta = 4

# 绘制旋转方格
for x in range(10, 390, 25):
    shift += delta
    pts = np.array([[10 + shift, x], [390, x], [390 - shift, x + 25], [10, x + 25]], dtype=np.int32)
    cv2.fillConvexPoly(canvas, pts, (255))

# 循环将画布变换
for i in range(120):
    M = np.float32([[1, 0, i * 3], [0, 1, 0]])
    rotated = cv2.warpAffine(canvas, M, (400, 400))

    # 计算光流
    flow = cv2.calcOpticalFlowFarneback(canvas, rotated, None, 0.5, 3, 25, 3, 5, 1.2, 0)
    magnitude, angle = cv2.cartToPolar(flow[..., 0], flow[..., 1])

    # 构造HSV图像
    hsv = np.zeros((400, 400, 3), dtype="uint8")
    hsv[..., 0] = angle * (180 / np.pi / 2)
    hsv[..., 1] = 255
    hsv[..., 2] = cv2.normalize(magnitude, None, 0, 255, cv2.NORM_MINMAX)

    # 转换为BGR图像并输出
    bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
    cv2.imshow("Optical Flow", bgr)
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

cv2.destroyAllWindows()

该示例演示了如何在画布上进行均匀平移,然后使用OpenCV的calcOpticalFlowFarneback函数计算出运动的光流。最终使用cvtColor函数将光流图像转换为BGR空间,以便将其显示出来。

示例2

在这个示例中,我们将通过直接对NGC 2237进行光流处理来演示OpenCV的光流功能。NGC 2237是Rosette星云中的一个部分,是一个美丽的星云。

import cv2
import numpy as np
from urllib import request

# 加载图像
url = "https://www.winhelponline.com/blog/wp-content/uploads/2017/12/Windows-10-default-background-3.jpg"
resp = request.urlopen(url)
image = np.asarray(bytearray(resp.read()), dtype="uint8")
image = cv2.imdecode(image, cv2.IMREAD_GRAYSCALE)

# 初始化前一帧和光流
previous_frame = None
optical_flow = None

# 不断循环,直到用户终止程序
while True:
    # 如果前一帧为空,则将当前帧设置为前一帧
    if previous_frame is None:
        previous_frame = image.copy()
    else:
        previous_frame = current_frame.copy()

    # 如果当前帧为空,则退出循环
    current_frame = image.copy()
    if current_frame is None:
        break

    # 如果光流为空,则使用Farneback计算光流
    if optical_flow is None:
        optical_flow = cv2.calcOpticalFlowFarneback(previous_frame, current_frame, None, 0.5, 3, 15, 3, 5, 1.2, 0)

    # 在当前帧上绘制运动向量
    for y in range(0, current_frame.shape[0], 5):
        for x in range(0, current_frame.shape[1], 5):
            dx, dy = optical_flow[y, x].astype(np.int0)
            cv2.arrowedLine(current_frame, (x, y), (x + dx, y + dy), (255, 255, 255))

    # 显示帧
    cv2.imshow("Rosette Nebula (NGC 2237)", current_frame)

    # 侦听键盘事件,确定是否退出
    key = cv2.waitKey(1) & 0xFF
    if key == ord("q"):
        break

cv2.destroyAllWindows()

该示例加载一个图像,然后使用calcOpticalFlowFarneback函数计算出前一帧和当前帧之间的运动光流。最终,使用光流图像在当前帧上绘制运动向量,并显示结果。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:OpenCV 光流Optical Flow示例 - Python技术站

(0)
上一篇 2023年5月25日
下一篇 2023年5月25日

相关文章

  • Android使用OKHttp库实现视频文件的上传到服务器功能

    下面我会详细讲解使用OKHttp库实现视频文件上传到服务器的步骤。 1. 引入OKHttp库 首先,在项目中引入OKHttp库,可以通过在build.gradle文件中添加以下代码: dependencies { implementation ‘com.squareup.okhttp3:okhttp:4.9.1’ } 2. 创建请求体 上传视频文件需要将视频…

    人工智能概论 2023年5月25日
    00
  • Django跨域请求无法传递Cookie的解决

    当在Django应用中进行跨域请求时,由于浏览器的同源策略限制,无法直接在跨域请求中传递Cookie信息。但是,我们可以通过一些方式解决这个问题,本文将详细介绍Django中跨域请求无法传递Cookie的解决方案及其步骤: 1. 使用CORS CORS(Cross Origin Resource Sharing)是跨源资源共享的缩写。它允许浏览器向跨源服务器…

    人工智能概论 2023年5月25日
    00
  • 使用python编写简单计算器

    使用Python编写简单计算器的完整攻略可以分为以下几个步骤: 1. 确定需求 在编写计算器之前,需要先明确计算器的需求和功能,包括支持的运算符号、输入格式、错误处理等。根据需求,我们可以创建一个”README”文件来记录计算器的功能说明和使用方法,以便其他人使用。 2. 创建代码文件 在Python中,可以使用文本编辑器或集成开发环境(IDE)创建代码文件…

    人工智能概论 2023年5月24日
    00
  • win10下vs2015配置Opencv3.1.0详细过程

    以下是win10下vs2015配置Opencv3.1.0详细过程: 第一步:下载安装Opencv3.1.0 1.打开Opencv官网,下载Opencv3.1.0压缩包2.解压后将文件夹重命名为“opencv-3.1.0”并放在“C:\”盘根目录下3.添加系统环境变量: 右键“计算机” >> “属性” >> “高级系统设置” >&…

    人工智能概论 2023年5月24日
    00
  • Django 序列化的具体使用

    Django 是一个流行的 Python Web 框架,具有高度可扩展性和易于维护性。在 Django 中,序列化是指将 Django 模型(Model)转换为 Python 数据类型,并将其转换为一种格式,以便可以将其存储在文件中、通过 HTTP 传输或用于其他目的。Django 内置了序列化与反序列化功能,可以方便地实现数据的导入和导出。 下面详细讲解 …

    人工智能概论 2023年5月25日
    00
  • Nginx 499错误问题及解决办法

    下面是详细讲解“Nginx 499错误问题及解决办法”的完整攻略。 什么是Nginx 499错误 Nginx 499错误是Nginx服务器中的一个常见错误,通常意味着客户端在请求响应期间关闭了连接,而这种关闭连接的方式不被Nginx服务器所接受。 产生Nginx 499错误的原因 Nginx 499错误通常发生在以下情况下: 客户端在请求期间关闭了与服务器的…

    人工智能概览 2023年5月25日
    00
  • Win10下android studio开发环境配置图文教程

    Win10下安装配置Android Studio 1. 下载安装JDK 首先我们需要下载并安装Java Development Kit (JDK),在Oracle官网下载与你的系统对应版本的JDK。安装完成后,需要将JDK的bin目录添加到系统的PATH环境变量中。 2. 下载和安装Android Studio 在官方网站下载Android Studio安装…

    人工智能概览 2023年5月25日
    00
  • perl Socket编程实例代码

    下面是“perl Socket编程实例代码”的完整攻略: 实例说明 本文将介绍如何在perl中使用Socket编程,创建一个简单的服务器和客户端。其中,服务器将会监听一个指定端口,接受客户端的连接请求,并向客户端发送一条欢迎信息;客户端将连接到服务器,接收并显示来自服务器的欢迎信息。同时,我们还将展示如何使用perl的IO::Select模块,使服务器可以同…

    人工智能概论 2023年5月25日
    00
合作推广
合作推广
分享本页
返回顶部