将视频里物体移动轨迹绘制到2D平面图中

2019-05-30 19:25:05 浏览数 (1)

数据挖掘是一个非常重要的技术。在近些年,数据挖掘为整个社会创造了巨大的财富。但是通过视频信息实现数据挖掘一直是一个比较艰难的过程。本文介绍的将视频中的信息转成平面信息非常有利于进一步的数据挖掘工作。

为什么要将视频里的信息投影到2D平面中呢?

在2D平面中的数据能够更轻松的实现数据挖掘任务,例如平面交通图中车流的运动状态或者一天中常见的堵塞地点。这些信息很容易通过平面图片得到,拥有这些数据,我们就可以推断出运输的产品可以什么时间到达,在哪个位置投放广告收效最高以及何时应该增派交警协助指挥等重要决策。

同时将视频中的信息投影到2D平面中,可以更加容易的现实出物体的运动模式,而不是通过含有畸变的相机成像显示。因为在图像顶部(或者远处)一个像素的移动对应于现实世界中的距离比图像底部(或者近处)一个像素的移动对应于现实世界中的距离更大。

为解决这个问题,我们首先要意识到我们正在解决的是欧几里德空间中两个平面的转换问题。一个平面式在相机中的平面,另一个平面是投影的2D平面。因为我们需要了解两者之间存在着怎样的数学映射关系。

为了表述更加清晰,我们拿一个相机拍摄的棋盘举例说明

我们要将上图中的棋盘通过变换得到右面的场景,同时能够标记出小人所处的位置

接下来的工作便是推出变换之间数学模型,首先我们先了解一些图像变换的类型

上图中,第一个是平移变换,直在x和y方向上平移;第二个变换时欧几里德变换,其不仅产生平移,还发生了旋转;第三个是仿射变换,是平移、旋转、缩放和剪切的组和,他可以改变点之间的距离,但是平行线在转换后还是保持平行。最后一个是单映变换,他可以将正方形变为任意的四边形。这种变换方式是我们解决问题的关键。

单映变换可以用如下公式表式

其中(x,y)表示一个平面中的像素坐标,(x',y')表示另一个平面中的像素坐标,H是表示为3×3矩阵的单应矩阵:

等式表明:给定一个平面中的点(x',y'),将它乘以单应矩阵H,将从另一个平面得到其对应的点(x,y)。因此,如果我们计算出两个平面之间的H,我们可以相机图像任意像素坐标到平面图像的像素的坐标。

为了避免一些复杂的数学公式,我们只讲述能够求取的条件,感兴趣的小伙伴可以自行去百度。我们需要的是从两个图像中至少4个点对(4个对应点)来获得H的最小解(一个“足够接近”的解)。但是我们提供的点数越多,H的估计就越好。

从图像中获取相应的点对也很容易。可以使用像GIMP这样的图像编辑应用程序。将鼠标移到图像上,则鼠标位置的像素坐标将显示在窗口的底部。记下一个图像的像素坐标和匹配图像中的相应像素坐标。获得至少四个这样的点对,便可以得到H的估计值并使用它来计算任何其他对应的点对。

现在便可以通过跟踪相机中移动的物体在平面图中绘制出物体的移动路线,用与后续的数据挖掘。为了简便,我们可以直接盗用OpenCV库里的函数实现该功能

代码语言:javascript复制
import cv2      # import the OpenCV library            
import numpy as np  # import the numpy library
                      
# provide points from image 1
pts_src = np.array([[154, 174], [702, 349], [702, 572],[1, 572], [1, 191]])
# corresponding points from image 2 (i.e. (154, 174) matches (212, 80))
pts_dst = np.array([[212, 80],[489, 80],[505, 180],[367, 235], [144,153]])
 
# calculate matrix H
h, status = cv2.findHomography(pts_src, pts_dst)
 
# provide a point you wish to map from image 1 to image 2
a = np.array([[154, 174]], dtype='float32')
a = np.array([a])
 
# finally, get the mapping
pointsOut = cv2.perspectiveTransform(a, h)

我们来看一下程序运行的结果

是不是非常的神奇!!!

0 人点赞