谷歌网站推广优化,如何制作企业网页,个人博客网站开发毕业设计,网站开发 定制 合同一、介绍 计算光流可以使用OpenCV的calcOpticalFlowPyrLK方法#xff0c;cv2.calcOpticalFlowPyrLK是OpenCV库中的一个函数#xff0c;用于计算稀疏光流。它实现的是Lucas-Kanade方法#xff0c;这是一种常用的光流计算方法。 光流是图像中物体运动的近似表示#… 一、介绍 计算光流可以使用OpenCV的calcOpticalFlowPyrLK方法cv2.calcOpticalFlowPyrLK是OpenCV库中的一个函数用于计算稀疏光流。它实现的是Lucas-Kanade方法这是一种常用的光流计算方法。 光流是图像中物体运动的近似表示它描述了图像中每个像素点在连续两帧之间的移动。Lucas-Kanade方法假设图像中的一个小邻域内的所有像素在运动上是一致的即具有相同的光流。
二、原理 以下是cv2.calcOpticalFlowPyrLK的基本工作原理 1. 选择特征点在第一帧图像中选择一些特征点。这些特征点通常是角点因为角点具有在所有方向上的变化更容易被跟踪。 2. 窗口对于每一个特征点定义一个周围的窗口。 3. 光流对于每一个窗口假设所有像素具有相同的光流然后通过最小化该窗口内像素在第一帧和第二帧之间的亮度差异来求解光流。 4. 金字塔实际上由于运动可能在不同的尺度上发生所以cv2.calcOpticalFlowPyrLK实际上在图像的多个尺度金字塔的每一层上重复以上步骤。这就是所谓的金字塔Lucas-Kanade方法。 需要注意的是由于Lucas-Kanade方法假设一个窗口内的所有像素具有相同的光流所以它只能处理小的和平滑的运动。对于大的或复杂的运动需要使用更复杂的方法如Horn-Schunck方法
三、代码实现 下面这段代码实现了识别特征点并跟踪这些特征点画出每个点的移动轨迹
import numpy as np
import cv2src_path rinput.mp4
target_path routput.mp4fps 25
cap cv2.VideoCapture(src_path)# ShiTomasi corner detection的参数
feature_params dict(maxCorners300,qualityLevel0.3,minDistance7,blockSize7)
# 光流法参数
# maxLevel 未使用的图像金字塔层数
lk_params dict(winSize(10, 10),maxLevel2,criteria(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))ret, old_frame cap.read() # 取出视频的第一帧
old_gray cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY) # 灰度化
p0 cv2.goodFeaturesToTrack(old_gray, maskNone, **feature_params)
mask np.zeros_like(old_frame) # 为绘制创建掩码图片
h, w, _ old_frame.shape
target_video cv2.VideoWriter(target_path,cv2.VideoWriter_fourcc(*H264), fps, (w, h))
while True:res, frame cap.read()if not res:breakframe_gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 计算光流以获取点的新位置p1, st, err cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)# 选择good pointsgood_new p1[st 1]good_old p0[st 1]good_new1 good_new.copy()for i, (new, old) in enumerate(zip(good_new, good_old)):a, b new.ravel()c, d old.ravel()mask cv2.line(mask, (int(a), int(b)), (int(c), int(d)), (0,255,0), 3)frame cv2.circle(frame, (int(a), int(b)), 5, (0,255,0), -1)img cv2.add(frame, mask)target_video.write(img)old_gray frame_gray.copy()p0 good_new1.reshape(-1, 1, 2)target_video.release()
cv2.destroyAllWindows()
cap.release()
四、参数解释
1.calcOpticalFlowPyrLK输入参数解释
1. prevImg上一帧输入图像。2. nextImg本轮输入图像。3. prevPts从上一帧图像中提取的特征点2D点向量。4. nextPts从本轮图像中提取的点2D点向量包含计算得到的新位置。5. winSize每一级金字塔的搜索窗口大小。默认值是Size(21,21)。 图像金字塔是通过对原始图像进行连续的下采样操作得到的一系列图像每一层的图像都比上一层的图像小。这就像一个金字塔底部是原始的大图像顶部是最小的图像。图像金字塔被用于处理不同尺度的运动。这是因为在实际的图像中物体的运动可能在不同的尺度上发生。例如远离摄像头的物体在图像中的运动可能比较小而靠近摄像头的物体在图像中的运动可能比较大。通过在图像金字塔的每一层上计算光流可以处理这种不同尺度的运动。6. maxLevel基于0的最大金字塔等级数如果设置为0则不使用金字塔单级如果设置为1则使用两级等。默认值是3。 在构建图像金字塔时从原始图像开始每一层图像的尺寸都是上一层图像尺寸的一半maxLevel就是这个金字塔的最大层数。maxLevel0表示只使用原始图像maxLevel1表示原始图像和它的一半尺寸的图像maxLevel2表示原始图像、一半尺寸的图像和四分之一尺寸的图像以此类推。7. criteriacriteria是一个重要的参数需要详细说一下该参数是一个指定迭代搜索算法的终止准则的元组。它包含三个元素 1 cv2.TERM_CRITERIA_EPS 或 cv2.TERM_CRITERIA_COUNT 或两者的组合。这些是终止准则的类型 - cv2.TERM_CRITERIA_EPS达到指定的精度epsilon时迭代就会停止。 - cv2.TERM_CRITERIA_COUNT达到指定的最大迭代次数时迭代就会停止。 - cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT当任一上述条件满足时迭代就会停止。 2 最大迭代次数。在这个例子中最大迭代次数是10。 3epsilon即所需的精度。在这个例子中epsilon是0.03。 例如criteria(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03)意味着迭代将在达到10次迭代或误差精度达到0.03时停止以先到达的条件为准 8. flags操作标志。可以设置为 10没有特殊行为。 2cv2.OPTFLOW_USE_INITIAL_FLOW如果设置了这个标志那么函数会使用nextPts参数中的点作为初始近似值然后进行优化。否则它会直接使用prevPts参数中的点作为初始值。 3cv2.OPTFLOW_LK_GET_MIN_EIGENVALS如果设置了这个标志那么函数会计算每个点的最小特征值并将它们存储在err参数中。 0cv2.OPTFLOW_USE_INITIAL_FLOW或cv2.OPTFLOW_LK_GET_MIN_EIGENVALS。 例如如果你想使用nextPts中的点作为初始近似值你可以这样调用函数
p1, st, err cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, flagscv2.OPTFLOW_USE_INITIAL_FLOW, **lk_params)
9. minEigThreshold最小特征值的阈值。默认值是1e-4。 这个函数的主要目的是使用Lucas-Kanade方法在两个图像之间跟踪一些特征点prevPts。这些特征点的新位置被存储在nextPts中。如果一个点不能被跟踪例如因为它走出了图像那么status向量的相应元素就会被设置为0
2.calcOpticalFlowPyrLK输出参数解释
1. nextPts这是一个数组包含了在下一帧图像中找到的输入特征点的新位置。2. status这是一个数组和输入的特征点数组大小相同。如果status[i]为1表示找到了第i个特征点的新位置如果为0表示没有找到。3. err这是一个数组和输入的特征点数组大小相同。err[i]表示第i个特征点的新位置和原位置之间的误差这个误差是基于窗口大小的。 这三个输出参数可以用于理解和评估光流的计算结果。例如你可以检查status数组来看哪些特征点在下一帧图像中被成功找到或者查看err数组来评估光流的计算精度 calcOpticalFlowPyrLK的用法就简单介绍到这关注不迷路(#^.^#)