opencv3/Python 稠密光流calcOpticalFlowFarneback详解

yizhihongxing

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如何实现华氏温度和摄氏温度转换

    让我来为您详细讲解如何使用 Python 实现华氏温度和摄氏温度转换。 摄氏度和华氏度的换算公式 我们先来简单讲解下摄氏度和华氏度的换算公式。 摄氏度和华氏度的换算公式为:C = (F – 32) * 5/9,其中 C 为摄氏度,F 为华氏度。 若要计算华氏温度,可以使用该公式的变形:F = C * 9/5 + 32 Python实现摄氏度转华氏度的代码 接…

    python 2023年5月14日
    00
  • 对numpy数据写入文件的方法讲解

    对NumPy数据写入文件的方法讲解 NumPy是Python中用于科学计算的一个重要的库,它提供了高效的多维数组array和各种量函数。本文将详细讲解NumPy中对数据写入文件的方法,包括savetxt()和save()函数。 savetxt()函数 savetxt()函数是NumPy中用于将数组写入文本文件的函数。下面是一个示例: import numpy…

    python 2023年5月14日
    00
  • python numpy矩阵信息说明,shape,size,dtype

    以下是关于“Python NumPy矩阵信息说明的完整攻略”。 shape 在NumPy中,shape是一个元组,它表示数组的维度。例如,一个二维数组的shape为(m,n),其中m表示行数,n表示列数。下面是一个示例: import numpy as np # 创建一个二维数组 a = np.array([[1, 2,3], [4, 5, 6]]) # 输…

    python 2023年5月14日
    00
  • pyMySQL SQL语句传参问题,单个参数或多个参数说明

    pyMySQL SQL语句传参问题 在使用Python操作MySQL数据库时,我们通常使用pyMySQL库来连接和操作数据库。在执行SQL语句时,我们需要传递参数,以便在SQL语句中使用。本攻略将详细讲解pyMySQL SQL语句传参问题,包括单个参数和多个参数的情况。 单个参数 在SQL语句中,我们可以使用占位符(?)来表示参数。在pyMySQL中,我们可…

    python 2023年5月14日
    00
  • Python中11种NumPy高级操作总结

    Python中11种NumPy高级操作总结 NumPy是Python中一个非常流行的科学计算库,它提供了许多常用的数学函数和工具。本攻略中,我们将介绍11NumPy高级操作,包括的切片、数组的拼接、数组的重塑、数组的排序、的去重、数组的比较、数组的统计、数组的线性代数、数组的傅里叶变换、数组的随机数生成和数组的文件读写。 数组的切片 我们可以使用切片操作来获…

    python 2023年5月13日
    00
  • python安装gdal的两种方法

    GDAL是一个开源的地理信息系统库,提供了对各种栅格和矢量地理数据格式的读写和转换功能。在Python中使用GDAL需要安装GDAL的Python绑定库。以下是Python安装GDAL的两种方法的完整攻略,包括方法的介绍和示例说明: 使用pip安装GDAL 可以使用pip命令安装GDAL的Python绑定库。但是,在安装之前需要先安装GDAL的C++库和头文…

    python 2023年5月14日
    00
  • 最简单的matplotlib安装教程(小白)

    Matplotlib是一个用于绘制2D图形的Python库。以下是一个最简单的Matplotlib安装教程,适用于小白用户。本攻略包含两个示例说明。 安装Matplotlib 在Python中,可以使用pip安装Matplotlib。以下是一个安装Matplotlib的示例: pip install matplotlib 在这个示例中,我们使用pip ins…

    python 2023年5月14日
    00
  • Python ndarray 数组的变形详情

    以下是Python ndarray数组的变形详情的攻略: Python ndarray 数组的变形详情 在NumPy中,可以使用reshape()函数来改变ndarray数组的形状。以下是一些实现方法: 将一维数组变形为二维数组 可以使用reshape()函数将一维数组变形为二维数组。以下是一个示例: import numpy as np a = np.ar…

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