opencv3/Python 稠密光流calcOpticalFlowFarneback详解

OpenCV3/Python稠密光流calcOpticalFlowFarneback详解

稠密光流是计算机视觉中的一个重要问题,它可以用来估计图像中每个像素的运动。OpenCV供了多种稠密光流算法,其中calcOpticalFlowFarneback是一种常用的方法。本攻略将详细讲解如何使用OpenCV3和Python实现calcOpticalFlowFarneback算法,并提供两个示例。

步骤一:导入库

在使用OpenCV3和Python实现calcOpticalFlowFarneback算法之前,我们需要先导入相关的库。下面是一个简单的示例:

import cv2
import numpy as np

在上面的代码中,我们导入了OpenCV和NumPy库。

步骤二:读取视频

在使用OpenCV3和Python实现calcOpticalFlowFarneback算法之前,我们需要先读取视频。下面是一个简单的示例:

# 读取视频
cap = cv2.VideoCapture('test.mp4')

# 获取第一帧
ret, frame1 = cap.read()

# 转换为灰度图像
prvs = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)

在上面的代码中,我们使用cv2.VideoCapture方法读取视频,然后使用cap.read方法获取第一帧图像。接着,我们使用cv2.cvtColor方法将图像转换为灰度图像。

步骤三:计算稠密光流

在读取视频之后,我们可以使用OpenCV3和Python计算稠密光流。下面是一个简单的示例:

# 计算稠密光流
while(1):
    ret, frame2 = cap.read()
    if ret:
        next = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
        flow = cv2.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0)
        # 可视化稠密光流
        hsv = np.zeros_like(frame2)
        hsv[...,1] = 255
        mag, ang = cv2.cartToPolar(flow[...,0], flow[...,1])
        hsv[...,0] = ang*180/np.pi/2
        hsv[...,2] = cv2.normalize(mag,None,0,255,cv2.NORM_MINMAX)
        bgr = cv2.cvtColor(hsv,cv2.COLOR_HSV2BGR)
        cv2.imshow('frame2',bgr)
        k = cv2.waitKey(30) & 0xff
        if k == 27:
            break
        # 更新前一帧
        prvs = next
    else:
        break

在上面的代码中,我们使用cv2.calcOpticalFlowFarneback方法计算稠密光流,并使用cv2.cartToPolar将光流向量转换为极坐标形式。接着,使用cv2.normalize方法将光流强度归一化到0-255之间,并使用cv2.cvtColor方法将图像从HSV颜色空间转换为BGR颜色空间。最后,我们使用cv2.imshow方法显示可视化的稠密光流,并使用cv2.waitKey方法等待用户按下ESC键退出程序。

示例一:稠密光流跟踪运动目标

下面是一个稠密光流跟踪运动目标的示例:

# 读取视频
cap = cv2.VideoCapture('test.mp4')

# 获取第一帧
ret, frame1 = cap.read()

# 转为灰度图像
prvs = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)

# 定义ROI
r,h,c,w = 250,90,400,125
track_window = (c,r,w,h)

# 设置追踪器参数
term_crit = ( cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1 )

# 计算稠密光流
while(1):
    ret, frame2 = cap.read()
    if ret:
        next = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
        flow = cv2.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0)
        # 可视化稠密光流
        hsv = np.zeros_like(frame2)
        hsv[...,1] = 255
        mag, ang = cv2.cartToPolar(flow[...,0], flow[...,1])
        hsv[...,0] = ang*180/np.pi/2
        hsv[...,2] = cv2.normalize(mag,None,0,255,cv2.NORM_MINMAX)
        bgr = cv2.cvtColor(hsv,cv2.COLOR_HSV2BGR)
        cv2.imshow('frame2',bgr)
        # 追踪运动目标
        if c > 0 and r > 0 and w > 0 and h > 0:
            roi = bgr[r:r+h, c:c+w]
            hsv_roi =  cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
            mask = cv2.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.)))
            roi_hist = cv2.calcHist([hsv_roi],[0],mask,[180],[0,180])
            cv2.normalize(roi_hist,roi_hist,0,255,cv2.NORM_MINMAX)
            dst = cv2.calcBackProject([hsv],[0],roi_hist,[0,180],1)
            ret, track_window = cv2.meanShift(dst, track_window, term_crit)
            x,y,w,h = track_window
            img2 = cv2.rectangle(bgr, (x,y), (x+w,y+h), 255,2)
            cv2.imshow('img2',img2)
        k = cv2.waitKey(30) & 0xff
        if k == 27:
            break
        # 更新前一帧
        prvs = next
    else:
        break

在上面的代码中,我们首先定义了一个ROI,然后使用cv2.inRange方法将ROI中的像素转换为二进制掩码。接着,我们使用cv2.calcHist方法计算ROI的颜色直方图,并使用cv2.normalize方法将直方图归一化到0-255之间。然后,使用cv2.calcBackProject方法计算反向投图,并使用cv2.meanShift方法追踪运动目标。最后,我们使用cv2.rectangle方法在图像中绘制矩形框,以标记运动目标。

示例二:稠密光流估计相机运动

下面是一个使用稠密光流估计相机运动的示例:

# 读取视频
cap = cv2.VideoCapture('test.mp4')

# 获取第一帧
ret, frame1 = cap.read()

# 转换为灰度图像
prvs = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)

# 计算稠密光流
while(1):
    ret, frame2 = cap.read()
    if ret:
        next = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
        flow = cv2.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0)
        # 可视化稠密光流
        hsv = np.zeros_like(frame2)
        hsv[...,1] = 255
        mag, ang = cv2.cartToPolar(flow[...,0], flow[...,1])
        hsv[...,0] = ang*180/np.pi/2
        hsv[...,2] = cv2.normalize(mag,None,0,255,cv2.NORM_MINMAX)
        bgr = cv2.cvtColor(hsv,cv2.COLOR_HSV2BGR)
        cv2.imshow('frame2',bgr)
        # 估计相机运动
        M = np.zeros((2,3))
        M[0,0] = 1
        M[1,1] = 1
        M[1,2] = np.mean(flow[...,0])
        M[0,2] = np.mean(flow[...,1])
        frame2 = cv2.warpAffine(frame2,M,(frame2.shape[1],frame2.shape[0]))
        cv2.imshow('frame2',frame2)
        k = cv2.waitKey(30) & 0xff
        if k == 27:
            break
        # 更新前一帧
        prvs = next
    else:
        break

在上面的代码中,我们使用np.mean方法计算光流向量的平均值,并使用cv2.warpAffine方法估计相机运动。最后,我们使用cv2.imshow方法显示估计的相机运动。

总结

本攻略详细解了如何使用OpenCV3和Python实现calcOpticalFlowFarneback算法,并提供了两个示例。在实际编程中,我们可以根据具体的需求选择合适的稠密光流算法和参数,以提高稠密光流的准确率和鲁棒性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:opencv3/Python 稠密光流calcOpticalFlowFarneback详解 - Python技术站

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

相关文章

  • Python+NumPy绘制常见曲线的方法详解

    下面是关于“Python+NumPy绘制常见曲线的方法详解”的完整攻略,包含了两个示例。 示例一:绘制正弦曲线 下面是一个示例,演示如何使用 NumPy 和 Matplotlib 绘制正弦曲线。 import numpy as np import matplotlib.pyplot as plt # 生成 x 坐标轴数据 x = np.linspace(0,…

    python 2023年5月14日
    00
  • python安装读取grib库总结(推荐)

    读取GRIB文件是气象学和气象预报中的一个重要任务。在Python中,可以使用pygrib库来读取GRIB文件。以下是安装和使用pygrib库的攻略: 安装pygrib库 在安装pygrib库之前,需要先安装eccodes库。eccodes是一个用于解码和编码GRIB和BUFR格式的库。可以从官方网站下载并安装eccodes库。 安装完成eccodes库后,…

    python 2023年5月14日
    00
  • tf.concat中axis的含义与使用详解

    以下是关于“tf.concat中axis的含义与使用详解”的完整攻略。 背景 在TensorFlow中,tf.concat()函数用于多个张量沿着指定的维度拼接。在使用tf.concat()函数时,需要指定拼的维度,即axis参数。本攻略将详细介绍tf.concat()函数中axis的含义和使用方法,并提供两个示例来示如何使用这个函数。 tf.concat中…

    python 2023年5月14日
    00
  • Python .py生成.pyd文件并打包.exe 的注意事项说明

    Python.py生成.pyd文件并打包.exe的注意事项说明 在Python中,我们可以使用Cython将Python代码编译成C代码,并生成.pyd文件。然后,我们可以使用pyinstaller将.pyd文件和其他必要文件打包成.exe可执行文件。本攻略将介绍如何使用Python.py生成.pyd文件并打包.exe的注意事项,包括如何安装Cython、如…

    python 2023年5月14日
    00
  • TensorFlow损失函数专题详解

    TensorFlow损失函数专题详解 TensorFlow是一个流行的深度学习框架,可以用于各种任务,例如分类、回归和聚类。在进行这些任务时,损失函数是非常关键的一个部分。本文将详细讲解TensorFlow中一些常用的损失函数。 什么是损失函数? 损失函数是一个衡量模型预测结果与真实结果之间的差异的函数。在训练模型时,我们尝试最小化损失函数的值。在深度学习中…

    python 2023年5月14日
    00
  • numpy.where() 用法详解

    numpy.where()用法详解 numpy.where()是NumPy库中的一个函数,用于根据指定的条件返回输入数组中的元素。它的语法如下: numpy.where(condition[, x, y]) 其中,condition是一个布尔型数组,用于指定元素是否足条件;x和y是两个可选参数,用于指定满足条件和不满足条件的元素的替代值。只传入conditi…

    python 2023年5月13日
    00
  • Python编程给numpy矩阵添加一列方法示例

    以下是关于“Python编程给numpy矩阵添加一列方法示例”的完整攻略。 给numpy矩阵添加一列 在Python中,可以使用numpy库中的concatenate()函数和reshape()函数来给numpy矩阵添加一列。具体步骤如下: 创建一个新的一维数组,作为要添加的列; 使用concatenate()将原矩阵和新数组按列连接; 使用reshape(…

    python 2023年5月14日
    00
  • Python NumPy教程之数组的基本操作详解

    Python NumPy教程之数组的基本操作详解 NumPy是Python中用于科学计算的一个重要库,它提供了高效的多维数组对象和各种派生,以及用于数组的函数。本文将详细讲解NumPy中数组的基本操作,包括数组的创建、索引和切片、的运算、数组的拼接和重塑、数组的转置等。 数组的创建 在NumPy中,可以使用np.array()函数创建。下面是一个示例: im…

    python 2023年5月13日
    00
合作推广
合作推广
分享本页
返回顶部