网站建设资料准备标准,拉销智能模板建站系统,百度贴吧首页,兰州网站建设王道下拉強光流简介 光流#xff08;optical flow#xff09;是运动物体在观察成像平面上的像素运动的瞬时速度。光流法是利用图像序列中像素在时间域上的变化以及相邻帧之间的相关性来找到上一帧跟当前帧之间存在的对应关系#xff0c;从而计算出相邻帧之间物体的运动信息的一种方法。…光流简介 光流optical flow是运动物体在观察成像平面上的像素运动的瞬时速度。光流法是利用图像序列中像素在时间域上的变化以及相邻帧之间的相关性来找到上一帧跟当前帧之间存在的对应关系从而计算出相邻帧之间物体的运动信息的一种方法。通常将二维图像平面特定坐标点上的灰度瞬时变化率定义为光流矢量。光流是由物体或相机的运动引起的图像物体在连续两帧之间的明显运动的模式。它是 2D 矢量场其中每个矢量是一个位移矢量显示点从第一帧到第二帧的移动。 以下图片显示了计算出的光流示意图颜色表示光流方向颜色饱和度表示大小 参考博文
计算机视觉大型攻略 —— 光流1基本原理和经典算法_光流算法_linusyue的博客-CSDN博客
光流法(optical flow)简介_Fm镄的博客-CSDN博客 opencv光流实现 光流追踪的前提是
1. 对象的像素强度在连续帧之间不会改变
2. 相邻像素具有相似的运动。 OpenCV提供了两种算法计算光流
cv::calcOpticalFlowPyrLK()---稀疏光流 通过 Lucas-Kanade 方法计算稀疏特征集的光流使用 Shi-Tomasi 算法检测到的角点
cv::calcOpticalFlowFarneback--密集光流 通过 Gunner Farneback 来寻找密集光流。它计算帧中所有点的光流。
p1, st, err cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, winSize(15, 15), maxLevel2, criteria(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
- old_gray: 上一帧单通道灰度图 - frame_gray: 下一帧单通道灰度图 - prePtsp0上一帧坐标pts - nextPts: None - winSize: 每个金字塔级别上搜索窗口的大小 - maxLevel: 最大金字塔层数 - criteria指定迭代搜索算法的终止条件在指定的最大迭代次数 10 之后或搜索窗口移动小于 0.03
flow cv2.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0)
- prvs: 上一帧单通道灰度图 - next: 下一帧单通道灰度图 - flow: 流 None - pyr_scale: 0.5经典金字塔构建金字塔缩放scale - level3 初始图像的金字塔层数 - winsize3 平均窗口大小数值越大算法对图像的鲁棒性越强 - iterations15 迭代次数 - poly_n5 像素邻域的参数多边形大小用于在每个像素中找到多项式展开式较大的值意味着图像将使用更平滑的曲面进行近似从而产生更高的分辨率、鲁棒算法和更模糊的运动场通常多边形n5或7。 - poly_sigma1.2 高斯标准差用于平滑导数 - flags: 可以是以下操作标志的组合OPTFLOW_USE_INITIAL_FLOW使用输入流作为初始流近似值。OPTFLOW_FARNEBACK_GAUSSIAN: 使用GAUSSIAN过滤器而不是相同尺寸的盒过滤器
源码实例
稀疏光流追踪
# 光流追踪
# 光流追踪的前提是1. 对象的像素强度在连续帧之间不会改变2. 相邻像素具有相似的运动。
# - cv2.goodFeaturesToTrack() 确定要追踪的特征点
# - cv2.calcOpticalFlowPyrLK() 追踪视频中的特征点# 取第一帧检测其中的一些 Shi-Tomasi 角点使用 Lucas-Kanade 光流迭代跟踪这些点。
# 对于函数 cv2.calcOpticalFlowPyrLK() 传递前一帧、前一个点和下一帧。它返回下一个点以及一些状态编号如果找到下一个点则值为 1否则为零。
# 然后在下一步中迭代地将这些下一个点作为前一个点传递。# USAGE
# python video_optical_flow.pyimport imutils
import numpy as np
import cv2cap cv2.VideoCapture(images/slow_traffic_small.mp4)# ShiTomasi角点检测的参数
feature_params dict(maxCorners100,qualityLevel0.3,minDistance7,blockSize7)# Lucas Kanada光流检测的参数
lk_params dict(winSize(15, 15),maxLevel2,criteria(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))# 构建随机颜色
color np.random.randint(0, 255, (100, 3))# 获取第一帧并发现角点
ret, old_frame cap.read()
old_gray cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)
p0 cv2.goodFeaturesToTrack(old_gray, maskNone, **feature_params)# 为绘制光流追踪图构建一个Mask
mask np.zeros_like(old_frame)num 0
while (1):ret, frame cap.read()if not ret:breakframe_gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 使用迭代Lucas Kanade方法计算稀疏特征集的光流# - old_gray: 上一帧单通道灰度图# - frame_gray: 下一帧单通道灰度图# - prePtsp0上一帧坐标pts# - nextPts: None# - winSize: 每个金字塔级别上搜索窗口的大小# - maxLevel: 最大金字塔层数# - criteria指定迭代搜索算法的终止条件在指定的最大迭代次数criteria.maxCount之后或搜索窗口移动小于criteria.epsilonp1, 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[i].tolist(), 2)frame cv2.circle(frame, (a, b), 5, color[i].tolist(), -1)img cv2.add(frame, mask)cv2.imshow(frame, img)cv2.imwrite(videoof-imgs/ str(num) .jpg, imutils.resize(img, 500))print(str(num))num num 1k cv2.waitKey(30) 0xffif k 27:break# 更新之前的帧和点old_gray frame_gray.copy()p0 good_new.reshape(-1, 1, 2)cv2.destroyAllWindows()
cap.release() 改进版稀疏光流追踪
# 优化后的光流追踪—Lucas-Kanade tracker
# 当不见检查下一个关键点的正确程度时即使图像中的任何特征点消失光流也有可能找到下一个看起来可能靠近它的点。实际上对于稳健的跟踪角点应该在特定的时间间隔内检测点。
# 找到特征点后每 30 帧对光流点的向后检查只选择好的。
# Lucas Kanade稀疏光流演示。使用GoodFeatures跟踪用于跟踪初始化和匹配验证的回溯帧之间。
# Lucas-Kanade sparse optical flow demo. Uses goodFeaturesToTrack for track initialization and back-tracking for match verification between frames.# Usage
# pyhton lk_track.py images/slow_traffic_small.mp4
# 按 ESC键退出from __future__ import print_functionimport imutils
import numpy as np
import cv2def draw_str(dst, target, s):x, y targetcv2.putText(dst, s, (x 1, y 1), cv2.FONT_HERSHEY_PLAIN, 1.0, (0, 0, 0), thickness2, lineTypecv2.LINE_AA)cv2.putText(dst, s, (x, y), cv2.FONT_HERSHEY_PLAIN, 1.0, (255, 255, 255), lineTypecv2.LINE_AA)lk_params dict(winSize(15, 15),maxLevel2,criteria(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))feature_params dict(maxCorners500,qualityLevel0.3,minDistance7,blockSize7)class App:def __init__(self, video_src):self.track_len 10self.detect_interval 30self.tracks []self.cam cv2.VideoCapture(video_src)self.frame_idx 0def run(self):while True:_ret, frame self.cam.read()if not _ret:breakframe_gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)vis frame.copy()if len(self.tracks) 0:img0, img1 self.prev_gray, frame_grayp0 np.float32([tr[-1] for tr in self.tracks]).reshape(-1, 1, 2)p1, _st, _err cv2.calcOpticalFlowPyrLK(img0, img1, p0, None, **lk_params)p0r, _st, _err cv2.calcOpticalFlowPyrLK(img1, img0, p1, None, **lk_params)d abs(p0 - p0r).reshape(-1, 2).max(-1)good d 1new_tracks []for tr, (x, y), good_flag in zip(self.tracks, p1.reshape(-1, 2), good):if not good_flag:continuetr.append((x, y))if len(tr) self.track_len:del tr[0]new_tracks.append(tr)cv2.circle(vis, (x, y), 2, (0, 255, 0), -1)self.tracks new_trackscv2.polylines(vis, [np.int32(tr) for tr in self.tracks], False, (0, 255, 0))draw_str(vis, (20, 20), track count: %d % len(self.tracks))if self.frame_idx % self.detect_interval 0:mask np.zeros_like(frame_gray)mask[:] 255for x, y in [np.int32(tr[-1]) for tr in self.tracks]:cv2.circle(mask, (x, y), 5, 0, -1)p cv2.goodFeaturesToTrack(frame_gray, maskmask, **feature_params)if p is not None:for x, y in np.float32(p).reshape(-1, 2):self.tracks.append([(x, y)])self.prev_gray frame_graycv2.imshow(lk_track, vis)print(self.frame_idx)cv2.imwrite(videoOof-imgs/ str(self.frame_idx) .jpg, imutils.resize(vis, 500))self.frame_idx 1ch cv2.waitKey(1)if ch 27:breakdef main():import systry:video_src sys.argv[1]except:video_src 0App(video_src).run()print(Done)if __name__ __main__:print(__doc__)main()cv2.destroyAllWindows() 密集光流追踪
# OpenCV中的密集光流
# Lucas-Kanade 方法计算稀疏特征集的光流使用 Shi-Tomasi 算法检测到的角点。
# OpenCV 提供了另一种算法: Gunner Farneback 来寻找密集光流。它计算帧中所有点的光流。
# 通过cv2.calcOpticalFlowFarneback() 将得到一个带有光流向量 (u,v) 的 2 通道阵列。可以找到它们的大小和方向然后对结果进行颜色编码以实现更好的可视化。
# 在HSV图像中方向对应于图像的色调幅度对应于价值平面。import cv2
import imutils
import numpy as npcap cv2.VideoCapture(images/slow_traffic_small.mp4)ret, frame1 cap.read()
prvs cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
hsv np.zeros_like(frame1)
hsv[..., 1] 255num 0
while (1):ret, frame2 cap.read()if not ret:breaknext cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)# 使用迭代Gunner Farneback 方法计算密集特征的光流# - prvs: 上一帧单通道灰度图# - next: 下一帧单通道灰度图# - flow: 流 None# - pyr_scale: 0.5经典金字塔构建金字塔缩放scale# - level3 初始图像的金字塔层数# - winsize3 平均窗口大小数值越大算法对图像的鲁棒性越强# - iterations15 迭代次数# - poly_n5 像素邻域的参数多边形大小用于在每个像素中找到多项式展开式较大的值意味着图像将使用更平滑的曲面进行近似从而产生更高的分辨率、鲁棒算法和更模糊的运动场通常多边形n5或7。# - poly_sigma1.2 高斯标准差用于平滑导数# - flags: 可以是以下操作标志的组合OPTFLOW_USE_INITIAL_FLOW使用输入流作为初始流近似值。OPTFLOW_FARNEBACK_GAUSSIAN: 使用GAUSSIAN过滤器而不是相同尺寸的盒过滤器flow cv2.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0)mag, ang cv2.cartToPolar(flow[..., 0], flow[..., 1])hsv[..., 0] ang * 180 / np.pi / 2hsv[..., 2] cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX)rgb cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)cv2.imshow(Origin VS frame2, np.hstack([frame2, rgb]))cv2.imwrite(dof-imgs/ str(num) .jpg, imutils.resize(np.hstack([frame2, rgb]), 600))k cv2.waitKey(30) 0xffnum num 1if k 27:breakelif k ord(s):cv2.imwrite(dof-imgs/origin VS dense optical flow HSVres str(num) .jpg,imutils.resize(np.hstack([frame2, rgb]), width800))prvs nextcap.release()
cv2.destroyAllWindows()