详解OpenCV中的Lucas Kanade稀疏光流单应追踪器

  • 1. 效果图
  • 2. 源码
  • 参考

这篇博客将详细介绍OpenCV中的Lucas Kanade稀疏光流单应追踪器。

  • 光流是由物体或相机的运动引起的图像物体在连续两帧之间的明显运动的模式。
  • Lucas Kanade是一个算法,用于稀疏光流的追踪;

1. 效果图

单应追踪器效果图如下:

选中随机特征点为红色,判断帧之间是否存在关联关系,存在则绘制轨迹线。每帧均可选择新的随机点作为特征点;

2. 源码

# Lucas Kanade稀疏光流单应追踪器demo
# 使用GoodFeatures用于跟踪初始化特征点和回溯帧之间的匹配验证。
# 查找引用视图和当前视图之间的单应性。
# Lucas-Kanade sparse optical flow demo. Uses goodFeaturesToTrack
# for track initialization and back-tracking for match verification
# between frames. Finds homography between reference and current views.
#
# Usage
# python lk_homography.py images/slow_traffic_small.mp4
# 按 ESC 退出
# 空格开始追踪
# 按 r 随机切换from __future__ import print_functionimport cv2# 在目标图像dst的target位置开始绘制文本s
import imutilsdef draw_str(dst, target, s):x, y = targetcv2.putText(dst, s, (x + 1, y + 1), cv2.FONT_HERSHEY_PLAIN, 1.0, (0, 0, 0), thickness=2, lineType=cv2.LINE_AA)cv2.putText(dst, s, (x, y), cv2.FONT_HERSHEY_PLAIN, 1.0, (255, 255, 255), lineType=cv2.LINE_AA)lk_params = dict(winSize=(19, 19),maxLevel=2,criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))feature_params = dict(maxCorners=1000,qualityLevel=0.01,minDistance=8,blockSize=19)def checkedTrace(img0, img1, p0, back_threshold=1.0):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)status = d < back_thresholdreturn p1, statusgreen = (0, 255, 0)
red = (0, 0, 255)class App:def __init__(self, video_src):self.cam = self.cam = cv2.VideoCapture(video_src)self.p0 = Noneself.use_ransac = Truedef run(self):num = 0while True:_ret, frame = self.cam.read()if not _ret:break# 转换灰度图frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 复制帧vis = frame.copy()if self.p0 is not None:p2, trace_status = checkedTrace(self.gray1, frame_gray, self.p1)self.p1 = p2[trace_status].copy()self.p0 = self.p0[trace_status].copy()self.gray1 = frame_grayif len(self.p0) < 4:self.p0 = Nonecontinue# findHomography(srcPoints, dstPoints[, method[, ransacReprojThreshold[, mask[, maxIters[, confidence]]]]]) -> retval, mask# 查找两个平面之间的透视变换# - p0: 原始平面中点的坐标,CV_32FC2或点向量# - p1: 目标平面中点的坐标,CV_32FC2或点向量# - method: 用于计算单应矩阵的方法。可以采用以下方法:# 0: 使用所有点的常规方法,即最小二乘法# RANSAC: 基于RANSAC的鲁棒方法# LMEDS: 最小中值稳健法# 基于RHO**-PROSAC的鲁棒方法# - ransAcreProjectThreshold: 将点对视为内部对象时允许的最大重投影错误H, status = cv2.findHomography(self.p0, self.p1, (0, cv2.RANSAC)[self.use_ransac], 10.0)h, w = frame.shape[:2]overlay = cv2.warpPerspective(self.frame0, H, (w, h))vis = cv2.addWeighted(vis, 0.5, overlay, 0.5, 0.0)for (x0, y0), (x1, y1), good in zip(self.p0[:, 0], self.p1[:, 0], status[:, 0]):# 如果俩帧中间可回溯,有关联,绘制光流线if good:cv2.line(vis, (x0, y0), (x1, y1), (0, 128, 0))# 可回溯,绘制绿色点,不可回溯绘制随机红色特征点cv2.circle(vis, (x1, y1), 2, (red, green)[good], -1)draw_str(vis, (20, 20), 'track count: %d' % len(self.p1))if self.use_ransac:draw_str(vis, (20, 40), 'RANSAC')else:# 初始化特征点(并绘制为绿色的点)p = cv2.goodFeaturesToTrack(frame_gray, **feature_params)if p is not None:for x, y in p[:, 0]:cv2.circle(vis, (x, y), 2, green, -1)draw_str(vis, (20, 20), 'feature count: %d' % len(p))cv2.imshow('lk_homography', vis)if (num == 0):cv2.waitKey(0)if (num % 5 == 0):cv2.imwrite('lk_himgs/' + str(num) + ".jpg", imutils.resize(vis, width=500))num = num + 1ch = cv2.waitKey(1)if ch == 27:breakif ch == ord(' '):self.frame0 = frame.copy()# 初始化特征点self.p0 = cv2.goodFeaturesToTrack(frame_gray, **feature_params)if self.p0 is not None:self.p1 = self.p0self.gray0 = frame_grayself.gray1 = frame_grayif ch == ord('r'):self.use_ransac = not self.use_ransacdef 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()

参考

  • https://github.com/opencv/opencv/blob/master/samples/python/lk_homography.py
  • https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_video/py_lucas_kanade/py_lucas_kanade.html#lucas-kanade

详解OpenCV中的Lucas Kanade稀疏光流单应追踪器相关推荐

  1. python的装饰器迭代器与生成器_详解python中的生成器、迭代器、闭包、装饰器

    迭代是访问集合元素的一种方式.迭代器是一个可以记住遍历的位置的对象.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退. 1|1可迭代对象 以直接作用于 for ...

  2. python用函数绘制椭圆_详解opencv中画圆circle函数和椭圆ellipse函数

    1. void ellipse(InputOutputArray img, Point center, Size axes, double angle, double startAngle, doub ...

  3. 一文详解OpenCV中的CUDA模块

    如果您使用OpenCV已有一段时间,那么您应该已经注意到,在大多数情况下,OpenCV都使用CPU,这并不总能保证您所需的性能.为了解决这个问题,OpenCV在2010年增加了一个新模块,该模块使用C ...

  4. 详解OpenCV中的cvCreateMat()函数

    CreateImage函数 Creates an matrix header and allocates the matrix data   //创建矩阵头并分配矩阵数据. .C:CvMat* cvC ...

  5. 详解python中GPU版本的opencv常用方法介绍

    更多编程教程请到:菜鸟教程 https://www.piaodoo.com/ 友情链接:好看站 http://www.nrso.net/ 高州阳光论坛https://www.hnthzk.com/ 引 ...

  6. 三维空间刚体运动5:详解SLAM中显示机器人运动轨迹及相机位姿(原理流程)

    三维空间刚体运动5:详解SLAM中显示机器人运动轨迹及相机位姿(原理流程) 一.显示运动轨迹原理讲解 二.前期准备 三.git管理子模块及克隆源代码 1.学习使用Git Submodule 2.克隆源 ...

  7. OpenCV-Python实战(10)——详解 OpenCV 轮廓检测

    OpenCV-Python实战(10)--详解 OpenCV 轮廓检测 0. 前言 1. 轮廓介绍 2. 轮廓检测 3. 轮廓压缩 4. 图像矩 4. 1 一些基于矩的对象特征 4.2 Hu 不变矩 ...

  8. 详解OpenCV的椭圆曲线点坐标近似计算函数ellipse2Poly()

    详解OpenCV的椭圆曲线点坐标近似计算函数ellipse2Poly() 函数ellipse2Poly()可用于近似计算椭圆曲线的像素坐标. 而前面介绍过的函数ellipse()则是直接在图像中绘制椭 ...

  9. 详解 OpenCV 透视变换原理 及 实例

    OpenCV提供了两种图片变换的方式:仿射变换和透视变换,两者的区别很容易区分, 前者是将矩形的图片变成平行四边形 后者是将图片变成梯形 这两种变换虽然都有各自的应用场景,但在实际的图片变换中由于透视 ...

最新文章

  1. 计算机二级ms office excel,计算机二级Msoffice考试excel答案.docx
  2. 解决TextView排版混乱或者自动换行的问题
  3. 安卓勒索软件进一步扩散
  4. ubuntu配置文件对照表
  5. 【图数据结构的遍历】java实现广度优先和深度优先遍历
  6. matlab调用cst计算扫频,CST MWS I算法求解单站RCS是否可以进行扫频设置
  7. 裸看美剧必备英文词汇
  8. express搭建的nodejs项目使用webpack进行打包
  9. CnOpenData中国理财产品数据
  10. 2019银保监计算机类真题,2019中国银保监会招聘考试全真模拟卷(计算机类)
  11. 全年爆文率14%+,这个小红书品牌的内容营销密码是什么?
  12. 洛谷P4061 大吉大利,晚上吃鸡
  13. HFSS初探日志(六)被动毫米波成像系统馈源天线
  14. 关于数字IC设计中分频后的慢速时钟和以快时钟触发的信号的关系处理
  15. 一篇让你熟练掌握Google Guava包(全网最全)
  16. 《你充满电了吗?》读后感
  17. 设计模式:(状态模式)
  18. [原]删除dboy病毒
  19. protonmail邮箱注册
  20. 阅文集团Java研发实习生面试经验(base上海)

热门文章

  1. 多视觉任务的全能: HRNet
  2. 2021年大数据HBase(十五):HBase的Bulk Load批量加载操作
  3. Libzip 版本过低或提示reinstall解决方法
  4. hql调用mysql存储过程_hibernate调用mysql存储过程
  5. python中什么是字符举例说明_第20p,什么是字符串?Python中的str
  6. mysql sql w3cschool_SQL复习(w3school)笔记
  7. 关于char(M)和varchar(N)的区别
  8. POJ 3268 D-Silver Cow Party
  9. 为何Redis要比Memcached好用(转)
  10. python用django连接mysql_三分钟了解Django如何连接Mysql数据库