目标跟踪与定位——Introduction to motion

要随着时间变化来跟踪物体并检测动作:
方法之一是提取特定的特征 观察这些特征是怎么从一帧变化到下一帧的,这里可以用到光流法(optical flow)。

光流法

光流法在诸多跟踪和动作分析应用中都有所涉及,其工作原理是通过假设图像帧的两点来实现的:一是物体像素强度在连续的图像帧里没有变化;二是相邻像素具有相同的动作。



光流法会观察兴趣点:如角点或特别明亮的像素,对这些点进行逐帧跟踪。
跟踪一个点或一组点能让我们知道点或物体移动的速度和方向,有了这些数据你就能预测物体接下来会往哪里移动。
所以你可以用光流法来做一些事情,如手势识别或跟踪特定物体 如人或车辆。

光流法原理:

我们使用一个例子来说明:
假设两个来自同一视频的图像帧,对于图像1中的对象上的一个点,想知道在图像2上的什么位置,找到后,我们可以计算动作向量:用以描述这个点从第一帧到第二帧的速度。

  1. 第一个图像中的点(x,y)将以一定的量从这个帧移动到下一帧,水平移动距离为u,垂直移动距离为v
  2. 因此在第二个图像中,该点的坐标降为(x+u,y+v)。
  3. 这个动作可以用动作向量(u,v)表示,向量有大小和方向。假设点向右移动3个像素,向上移动4个像素。则第二帧图像中将为(x+3,y+4)。动作向量为(3,4)。
亮度恒定假设

光流法假设一个图像帧中点与下一个图像帧的相同点具有一样的强度像素值,即光流法假定表面的颜色一直保持不变。在实际情况下这不是完美的假定,但是大部分情况下都很接近事实。
在第一个图像中的点(x,y)强度与图像2中的点(x+u,y+v)强度一样。



到目前为止,我们将这两个点当做(x,y)空间里的两组不同的图像,但是它们在时间上是相关联的。
可以用另一种方式看待这些图像帧:
第一个图像是在时间t发生的二维强度模式;
第一个图像是在时间t+1发生的二维强度模式。
用这种方式,我们可以将一系列图像帧I看做三维图像,具有(x,y)坐标,每个点像素值,深度为时间。



上图的方程式称为亮度恒定假设,这个函数可以进行泰勒级数展开,将这个强度函数表示为多项式的和。

在上图中,我们将各项计算为强度相对于x,y,t的导数。
可以简化这个展开公式:



结果是一个将动作向量的数值 u 和 v与图像强度在空间和时间内的变化联系起来的方程式。
光流会通过查看相同的点从一个图像帧移动到下一个图像帧的位置来跟踪对象,加载一些pacman人脸的示例帧,并使其向右和向下移动,然后观察光流如何找到描述人脸运动的运动矢量。

  1. 首先,导入资源并读入图像。
import numpy as np
import matplotlib.image as mpimg  # for reading in images
import matplotlib.pyplot as plt
import cv2  # computer vision library
%matplotlib inline

# Read in the image frames
frame_1 = cv2.imread('images/pacman_1.png')
frame_2 = cv2.imread('images/pacman_2.png')
frame_3 = cv2.imread('images/pacman_3.png')

# convert to RGB
frame_1 = cv2.cvtColor(frame_1, cv2.COLOR_BGR2RGB)
frame_2 = cv2.cvtColor(frame_2, cv2.COLOR_BGR2RGB)
frame_3 = cv2.cvtColor(frame_3, cv2.COLOR_BGR2RGB)


# Visualize the individual color channels
f, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(20,10))
ax1.set_title('frame 1')
ax1.imshow(frame_1)
ax2.set_title('frame 2')
ax2.imshow(frame_2)
ax3.set_title('frame 3')
ax3.imshow(frame_3)

  1. 寻找跟踪点

在使用光流之前,我们必须给它一组用来跟踪两个图像帧的关键点
在下面的例子中,我们要用到Shi-Tomasi角点检测器,这个检测器会使用与Harris角点检测器相同的过程来查找构成图像中“角点”的强度模式,只是它添加了一个额外的参数来帮助选择最突出的角点。你可以在 这个文档中阅读有关此检测算法的更多信息。
或者,你也可以选择使用Harris甚至ORB来查找特征点。可以参考以前写的两篇文章

# parameters for ShiTomasi corner detection
feature_params = dict( maxCorners = 10,
                       qualityLevel = 0.2,
                       minDistance = 5,
                       blockSize = 5 )


# convert all frames to grayscale
gray_1 = cv2.cvtColor(frame_1, cv2.COLOR_RGB2GRAY)
gray_2 = cv2.cvtColor(frame_2, cv2.COLOR_RGB2GRAY)
gray_3 = cv2.cvtColor(frame_3, cv2.COLOR_RGB2GRAY)


# Take first frame and find corner points in it
pts_1 = cv2.goodFeaturesToTrack(gray_1, mask = None, **feature_params)

# display the detected points
plt.imshow(frame_1)
for p in pts_1:
    # plot x and y detected points
    plt.plot(p[0][0], p[0][1], 'r.', markersize=15)

# print out the x-y locations of the detected points
print(pts_1)
  1. 执行光流

在你感兴趣的初始图像上检测到关键点之后,就可以使用OpenCV的calcOpticalFlowPyrLK计算此图像帧(第1帧)和下一帧(第2帧)之间的光流。其中,calcOpticalFlowPyrLK可以在这里 查看:它会接收初始图像帧、下一张图像和第一组点,并返回下一帧中检测到的点和一个值,该值表示的是从一帧到下一帧之间的点匹配程度。
参数还包括窗口大小和maxLevels,它们分别表示窗口的大小以及将使用金字塔缩放比例缩放给定图像的级别数。此版本会对匹配点进行迭代搜索,此匹配条件则反映在最后一个参数中。如果使用其他图像,则可能需要更改这些值,但更改的值应适用于提供的示例。

# parameters for lucas kanade optical flow
lk_params = dict( winSize  = (5,5),
                  maxLevel = 2,
                  criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))


# calculate optical flow between first and second frame
pts_2, match, err = cv2.calcOpticalFlowPyrLK(gray_1, gray_2, pts_1, None, **lk_params)

# Select good matching points between the two image frames
good_new = pts_2[match==1]
good_old = pts_1[match==1]

接下来,让我们把生成的运动矢量显示出来吧!你应该看到第一个图像上绘有运动矢量,该运动矢量表示的是从第一帧到下一帧的运动方向。

# create a mask image for drawing (u,v) vectors on top of the second frame
mask = np.zeros_like(frame_2)

# draw the lines between the matching points (these lines indicate motion vectors)
for i,(new,old) in enumerate(zip(good_new,good_old)):
    a,b = new.ravel()
    c,d = old.ravel()
    # draw points on the mask image
    mask = cv2.circle(mask,(a,b),5,(200),-1)
    # draw motion vector as lines on the mask image
    mask = cv2.line(mask, (a,b),(c,d), (200), 3)
    # add the line image and second frame together

composite_im = np.copy(frame_2)
composite_im[mask!=0] = [0]

plt.imshow(composite_im)


光流法被用于许多跟踪技术中,比如NVIDIA Redtail无人机,它使用光流法跟踪视频流中周围物体

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351

推荐阅读更多精彩内容