1.cv2.goodFeaturesToTrack(old_gray, mask=None, **feature_params)  用于获得光流估计所需要的角点
参数说明:old_gray表示输入图片,mask表示掩模,feature_params:maxCorners=100角点的最大个数,qualityLevel=0.3角点品质,minDistance=7即在这个范围内只存在一个品质最好的角点
2. pl, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)  用于获得光流检测后的角点位置

参数说明:pl表示光流检测后的角点位置,st表示是否是运动的角点,err表示是否出错,old_gray表示输入前一帧图片,frame_gray表示后一帧图片,p0表示需要检测的角点,lk_params:winSize表示选择多少个点进行u和v的求解,maxLevel表示空间金字塔的层数

3. cv2.add(frame, mask) # 将两个图像的像素进行加和操作

参数说明:frame表示输入图片,mask表示掩模

光流估计:通过当前时刻与前一时刻的亮度不变的特性I(x, y, t) = I(x+∆x, y+∆y, t+∆t) 使用lucas-kanade算法进行求解问题, 我们需要求得的是x,y方向的速度

下面是lucas-kanade的推导公式, 即位置发生变动时,其像素点的大小没有发生变化,

I(x, y, t) = I(x+dx, y+dy, t+dt)

= I(x, y, t) + Ixdx + Iydy + Itdt 使用泰勒基数进行展开
       对上式进行化解即:

Ixdx + Iydy + Itdt = 0  Ix表示x轴的梯度方向,Iy表示y轴的梯度方向,It表示单位时间上的像素点的变化
                               如果我们使用前后两帧的变化, 那么dx和dy也就是表示x轴和y轴的速度,返回的结果是dx和dy,即在x轴和y轴方向上移动的步数,我们就可以知道目标的位置了

下面是实际求解u和v的过程,根据上述的空间一致性,我们选择出关键点周围的25个点进行求解,即(5, 5)的方框, 构造Au = b 进行求解,我们可以看出(A^T*A)^-1

但是当前像素点不一定可逆,如果保证可逆呢,即A^T*A的特征值λ1和λ2接近相等且较大,符合条件的就是角点, 因此使用角点去求解u和v

代码:

第一步:使用cv2.capture读入视频

第二步:构造角点检测所需参数, 构造lucas kanade参数

第三步:拿到第一帧图像,并做灰度化, 作为光流检测的前一帧图像

第四步:使用cv2.goodFeaturesToTrack获得光流检测所需要的角点

第五步:构造一个mask用于画直线

第六步:读取一张图片,进行灰度化,作为光流检测的后一帧图像

第七步:使用cv2.caclOpticalFlowPyrLK进行光流检测

第八步:使用st==1获得运动后的角点,原始的角点位置

第九步:循环获得角点的位置,在mask图上画line,在后一帧图像上画角点

第十步:使用cv2.add()将mask和frame的像素点相加并进行展示

第十一步:使用后一帧的图像更新前一帧的图像,同时使用运动的后一帧的角点位置来代替光流检测需要的角点

import numpy as np
import cv2 # 第一步:视频的读入
cap = cv2.VideoCapture('test.avi') # 第二步:构建角点检测所需参数
feature_params = dict(maxCorners=100,
qualityLevel=0.3,
minDistance=7) # lucas kanade参数
lk_params = dict(winSize=(15, 15),
maxLevel=2) # 随机颜色条
color = np.random.randint(0, 255, (100, 3)) # 第三步:拿到第一帧图像并灰度化作为前一帧图片
ret, old_frame = cap.read()
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)
# 第四步:返回所有检测特征点,需要输入图片,角点的最大数量,品质因子,minDistance=7如果这个角点里有比这个强的就不要这个弱的
p0 = cv2.goodFeaturesToTrack(old_gray, mask=None, **feature_params) # 第五步:创建一个mask, 用于进行横线的绘制
mask = np.zeros_like(old_frame) while(True):
# 第六步:读取图片灰度化作为后一张图片的输入
ret, frame = cap.read()
frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 第七步:进行光流检测需要输入前一帧和当前图像及前一帧检测到的角点
pl, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params) # 第八步:读取运动了的角点st == 1表示检测到的运动物体,即v和u表示为0
good_new = pl[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)
k = cv2.waitKey(150) & 0xff
if k == 27:
break # 第十一步:更新前一帧图片和角点的位置
old_gray = frame_gray.copy()
p0 = good_new.reshape(-1, 1, 2)
# p0 = cv2.goodFeaturesToTrack(old_gray, mask=None, **feature_params) cv2.destroyAllWindows()
cap.release()

机器学习进阶-光流估计 1.cv2.goodFeaturesToTrack(找出光流估计所需要的角点) 2.cv2.calcOpticalFlowPyrLK(获得光流检测后的角点位置) 3.cv2.add(进行像素点的加和)的更多相关文章

  1. 机器学习进阶-项目实战-信用卡数字识别 1.cv2.findContour(找出轮廓) 2.cv2.boudingRect(轮廓外接矩阵位置) 3.cv2.threshold(图片二值化操作) 4.cv2.MORPH_TOPHAT(礼帽运算突出线条) 5.cv2.MORPH_CLOSE(闭运算图片内部膨胀) 6. cv2.resize(改变图像大小) 7.cv2.putText(在图片上放上文本)

    7. cv2.putText(img, text, loc, text_font, font_scale, color, linestick) # 参数说明:img表示输入图片,text表示需要填写的 ...

  2. 机器学习进阶-图像金字塔与轮廓检测-轮廓检测 1.cv2.cvtColor(图像颜色转换) 2.cv2.findContours(找出图像的轮廓) 3.cv2.drawContours(画出图像轮廓) 4.cv2.contourArea(轮廓面积) 5.cv2.arcLength(轮廓周长) 6.cv2.aprroxPloyDP(获得轮廓近似) 7.cv2.boudingrect(外接圆)..

    1. cv2.cvtcolor(img, cv2.COLOR_BGR2GRAY) # 将彩色图转换为灰度图 参数说明: img表示输入的图片, cv2.COLOR_BGR2GRAY表示颜色的变换形式 ...

  3. 机器学习进阶-图像金字塔与轮廓检测-模板匹配(单目标匹配和多目标匹配)1.cv2.matchTemplate(进行模板匹配) 2.cv2.minMaxLoc(找出矩阵最大值和最小值的位置(x,y)) 3.cv2.rectangle(在图像上画矩形)

    1. cv2.matchTemplate(src, template, method)  # 用于进行模板匹配 参数说明: src目标图像, template模板,method使用什么指标做模板的匹配 ...

  4. 机器学习进阶-背景建模-(帧差法与混合高斯模型) 1.cv2.VideoCapture(进行视频读取) 2.cv2.getStructureElement(构造形态学的卷积) 3.cv2.createBackgroundSubtractorMOG2(构造高斯混合模型) 4.cv2.morpholyEx(对图像进行形态学的变化)

    1. cv2.VideoCapture('test.avi') 进行视频读取 参数说明:‘test.avi’ 输入视频的地址2. cv2.getStructureElement(cv2.MORPH_E ...

  5. 机器学习进阶-案例实战-答题卡识别判 1.cv2.getPerspectiveTransform(获得投射变化后的H矩阵) 2.cv2.warpPerspective(H获得变化后的图像) 3.cv2.approxPolyDP(近似轮廓) 4.cv2.threshold(二值变化) 7.cv2.countNonezeros(非零像素点个数)6.cv2.bitwise_and(与判断)

    1.H = cv2.getPerspectiveTransform(rect, transform_axes) 获得投射变化后的H矩阵 参数说明:rect表示原始的位置左上,右上,右下,左下, tra ...

  6. 机器学习进阶-案例实战-图像全景拼接-图像全景拼接(RANSCA) 1.sift.detectAndComputer(获得sift图像关键点) 2.cv2.findHomography(计算单应性矩阵H) 3.cv2.warpPerspective(获得单应性变化后的图像) 4.cv2.line(对关键点位置进行连线画图)

    1. sift.detectAndComputer(gray, None)  # 计算出图像的关键点和sift特征向量 参数说明:gray表示输入的图片 2.cv2.findHomography(kp ...

  7. 从一亿个ip找出出现次数最多的IP(分治法)

    /* 1,hash散列 2,找到每个块出现次数最多的(默认出现均匀)—–>可以用字典树 3,在每个块出现最多的数据中挑选出最大的为结果 */ 问题一: 怎么在海量数据中找出重复次数最多的一个 算 ...

  8. 机器学习进阶-图像特征sift-SIFT特征点 1.cv2.xfeatures2d.SIFT_create(实例化sift) 2. sift.detect(找出关键点) 3.cv2.drawKeypoints(画出关键点) 4.sift.compute(根据关键点计算sift向量)

    1. sift = cv2.xfeatures2d.SIFT_create() 实例化 参数说明:sift为实例化的sift函数 2. kp = sift.detect(gray, None)  找出 ...

  9. 机器学习进阶-目标追踪-SSD多进程执行 1.cv2.dnn.readnetFromCaffe(用于读取已经训练好的caffe模型) 2.delib.correlation_tracker(生成追踪器) 5.cv2.writer(将图片写入视频中) 6.cv2.dnn.blobFromImage(图片归一化) 10.multiprocessing.process(生成进程)

    1. cv2.dnn.readNetFromCaffe(prototxt, model)  用于进行SSD网络的caffe框架的加载 参数说明:prototxt表示caffe网络的结构文本,model ...

随机推荐

  1. csv文件操作

    1.python2中: import csv infos = [ ['peter','male'], ['marry','female'], ['johon','male'], ['rose','fe ...

  2. Foxmail Gmail Outlook

    三个邮件客户端都比较好,但是作为用户精力是非常有限地,必须优中选优. 我选outlook,非常值得拥有. 理由如下: (1)和office完美契合 (2)和生产环境完美契合 (3)免费 (4)良好地任 ...

  3. java1.8新特性(四 创建 stream对象)

    java1.8 提供了 stream对象 可以用作 对 集合 数组的 一系列操作,都是基于lambda 表达式 ,所以得先熟悉lambda 表达式 集合创建stream对象 // 1.集合创建stre ...

  4. 信息安全-加密:AES 加密

    ylbtech-信息安全-加密:AES 加密 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一 ...

  5. java中,什么是方法的重载?需要满足什么条件?两同三不同指的什么?

    方法重载需要满足以下几个条件: 在同一个类中 方法的名称相同 参数列表不同 方法重载有以下特点: 与访问修饰符和返回值类型无关 与异常无关 方法重载的作用: 传递不同的参数实现相同的效果 所谓两同,就 ...

  6. [UE4]多线程开关,开启的解决方案

    像这样直接获取值就会被警告. 解决方法:定义一个变量speed,然后在“Blueprint Update Animation”事件中赋值给这个变量. 这样就不会被警告了. 另外一种解决方法:就是关掉多 ...

  7. Linux打开TCP BBR拥塞控制算法

    要求内核为4.9以上,如果不是,请升级内核. modprobe tcp_bbr echo "tcp_bbr" >> /etc/modules-load.d/module ...

  8. PHP:导出数据到word(包含图片)

    1.方法 public function word() { $xlsModel = M('api_aliucheng'); $Data = $xlsModel->Field('id,u_name ...

  9. openstack-- neutron 二/三层网络实现探究

    引出 Neutron 是openstack 中提供网络虚拟化的组件,根据二层网络的实现方式不同(即agent的不同),可以分为Linux bridge的方式,Openvswitch的方式.而且,lay ...

  10. Android 显示Dialog的同时自动弹出软键盘;

    需求大致就是这样的:用户点击按钮弹出Dialog,Dialog中有输入框,然后Dialog弹出后要自动弹出软键盘:(如果让用户自己手动点击输入框再弹出软键盘的话,用户体验太差了): 好的,需求大致就是 ...