主要内容

使用点特征匹配的视频稳定

此示例显示如何稳定从抖动平台捕获的视频。稳定视频的一种方法是跟踪图像中的突出特征,并使用它作为锚点,以取消相对于它的所有扰动。然而,此过程必须以这种突出特征在于第一视频帧的位置引导。在这个例子中,我们探索了一种有效的视频稳定方法,没有任何此类先天的知识。相反,它会自动搜索视频序列中的“背景平面”,并利用其观测到的失真来校正摄像机的运动。

该稳定算法包括两个步骤。首先,利用该方法确定视频序列中所有相邻帧之间的仿射图像变换estimateGeometricTransform2D函数应用于两个图像之间的点对应关系。其次,我们经过视频帧来实现稳定的视频。我们将使用计算机Vision Toolbox™用于算法和显示。

步骤1.从电影文件中读取帧

这里我们读一个视频序列的前两帧。我们将它们作为强度图像读取,因为稳定算法不需要颜色,而且使用灰度图像可以提高速度。下面我们将两个帧并排显示,并生成一个红青色组合来说明它们之间的像素差异。很明显,这两个画面之间有很大的垂直和水平偏移。

filename =“shaky_car.avi”;hVideoSrc = VideoReader(文件名);imgA = rgb2gray (im2single (readFrame (hVideoSrc)));%读取第一帧到imgAIMGB = RGB2GRAY(IM2single(ReadFrame(HVideOSRC))));%读取第二帧到imgB图;imshowpair (imgA imgB,'剪辑');标题([“帧”repmat (''[70]),'框架b']);

图;imshowpair (imgA imgB,“ColorChannels”“red-cyan”);标题('彩色复合(框架a =红色,框架b =青色)');

步骤2.从每个帧收集突出点

我们的目标是确定一个转换,将纠正两个帧之间的失真。我们可以使用estimateGeometricTransform2D函数,它将返回一个仿射变换。作为输入,我们必须为这个函数提供两帧之间的一组点对应。为了生成这些通信,我们首先从两个帧中收集感兴趣的点,然后选择它们之间可能的通信。

在此步骤中,我们为每个帧生成这些候选点。为了使这些点在另一帧中有相应点的最佳机会,我们希望各种突出图像特征(如角)围绕。为此,我们使用detectFASTFeatures函数,实现了最快的角点检测算法之一。

两帧中检测到的点如下图所示。观察它们中有多少覆盖了相同的图像特征,例如沿着树线的点、大路标的拐角和汽车的拐角。

ptthresh = 0.1;pointsa = detectfatfeatures(IMGA,“MinContrast”, ptThresh);pointsB = detectFASTFeatures (imgB,“MinContrast”, ptThresh);在图像A和B中发现的%显示角。图;imshow (imgA);抓住;情节(pointsA);标题(在一个角落的);

图;imshow(imgb);抓住;绘图(指点);标题(“B角落”);

步骤3.选择点之间的对应关系

接下来我们选择上面推导的点之间的对应关系。对于每个点,我们提取一个以其为中心的快速视网膜关键点(FREAK)描述符。由于FREAK描述符是二进制的,所以我们使用的点之间的匹配代价是汉明距离。假定坐标系A和坐标系B中的点是匹配的。注意,没有唯一性约束,所以坐标系B中的点可以对应坐标系A中的多个点。

提取边角的怪物描述符[featuresA, pointsA] = extractFeatures(imgA, pointsA);[featuresB, pointsB] = extractFeatures(imgB, pointsB);

匹配当前帧和之前帧中发现的特征。由于FREAK描述符是二进制的,所以matchFeatures函数使用汉明距离来找到相应的点。

indexPairs = matchFeatures(featuresA, featuresB);pointsA = pointsA(indexPairs(:, 1),:);pointb = pointb (indexPairs(:, 2),:);

下面的图片显示了上面给出的相同的颜色组合,但是添加了来自框架A的点(红色)和来自框架B的点(绿色)。在点之间画黄线,以显示上述程序选择的对应关系。这些对应中有许多是正确的,但也有相当数量的异常值。

图;showMatchedFeatures(imgA, imgB, pointsA, pointb);传奇('一种''B');

步骤4。从噪声通信中估计变换

在前一步中得到的许多点对应是不正确的。但是,我们仍然可以使用RANSAC算法的变体M-estimator SAmple Consensus (MSAC)算法对两幅图像之间的几何变换进行稳健估计。文中实现了MSAC算法estimateGeometricTransform2D功能。此功能,当给定一组点对应关系时,将搜索有效的Inlier对应关系。从这些中,它将导出仿射变换,使第一组点从第一组点与第二组中的最匹配最密切地匹配。这款仿射变换将是表格的3×3矩阵:

(a_1 a_3 0;a₂a_4 0;t_x t_y 1]

参数 一种 定义缩放、旋转和变换的剪切效果,同时参数 T. 是翻译参数。这个变换可以用来扭曲图像,使其相应的特征将被移动到相同的图像位置。

仿射变换的一个局限性是它只能改变成像平面。因此,它不适用于寻找3d场景的两帧之间的一般失真,例如这段从移动的汽车上拍摄的视频。但它确实在某些条件下起作用,我们稍后将描述。

[tform,inlieridx] = estimateGeometricTransform2D(......指点,指出,'仿射');pointsBm = pointsB(inlierIdx,:);pointsAm = pointsA(inlierIdx,:);imgBp = imwarp(imgB, tform,“OutputView”imref2d(大小(imgB)));点= TransformPointSforward(tform,potionbm.location);

下面是一个颜色合成图,显示了帧a与重投影帧B的叠加,以及重投影的对应点。结果是极好的,与早期的对应几乎完全一致。图像的核心都对齐得很好,这样红青色的复合色在那个区域几乎变成纯黑白。

注意,早期的对应都在图像的背景中,而不是在前景中,前景本身并没有对齐。这是因为背景特征是足够远的,他们的行为就像他们在一个无限远的平面上。因此,即使仿射变换仅限于改变成像平面,在这里,这足以对齐两个图像的背景平面。此外,如果我们假设背景平面在帧之间没有移动或显著改变,那么这个变换实际上捕获了相机的运动。因此,纠正这一点将稳定视频。只要摄像机在帧间的运动足够小,或者相反,如果视频帧率足够高,这种情况就会持续。

图;ShowMatchedFeatures(IMGA,IMGBP,点,点数);传奇('一种''B');

第5步。变换近似与平滑

给定一组视频帧 T. 一世 一世 = 0. 1 2 ...... ,我们现在可以使用上述过程来估计所有帧之间的失真 T. 一世 T. 一世 + 1 仿射变换, H 一世 .因此帧的累积变形 一世 相对于第一帧的,将是前面所有帧间变换的乘积,或

H C M. L. 一种 T. 一世 V. E. 一世 = H 一世 π. j = 0. 一世 - 1

我们可以使用上述仿射变换的所有六个参数,但是,为了数值的简单性和稳定性,我们选择将矩阵重新拟合为一个更简单的尺度-旋转-平移变换。与全仿射变换的六个参数相比,它只有四个自由参数:一个比例因子、一个角度和两个平移。这个新的变换矩阵的形式为:

[s * cos (ang) s * sin (ang) 0;* sin (ang) s * cos (ang) 0;t_x t_y 1]

下面我们通过拟合上面得到的变换来说明这个转换过程 H 用等量-旋转-平移, H S. R. T. .为了表明转换变换的误差是最小的,我们将框架B恢复为变换,并将下面的两个图像显示为Red-Cyan Color Composite。由于图像看起来黑白,显然不同重新注入之间的像素明显差异可忽略不计。

%提取比例和旋转部分子矩阵。h = tform.t;r = h(1:2,1:2);%从两个可能的arctan的均值计算θ=意味着([量化(R(2),(1)量化(R - R (3), (4))));%从两个稳定平均值的平均值计算比例尺Scale =平均值(r([1 4])/ cos(θ));%翻译保持不变:翻译= h(3,1:2);%重构新的s-R-t变换:hsrt = [[scale * [cos(theta)-sin(θ);罪(θ)cos(θ)];......翻译],[0 0 1]'];tformsRT = affine2d (HsRt);imgBold = imwarp(imgB, tform,“OutputView”imref2d(大小(imgB)));imgBsRt = imwarp(imgB, tformsRT,“OutputView”imref2d(大小(imgB)));图(2)中,clf;imshowpair (imgBold imgBsRt,“ColorChannels”“red-cyan”),轴图片;标题(“仿射和s-R-t变换输出的颜色合成”);

步骤6.在完整的视频上运行

现在我们应用上面的步骤平滑一个视频序列。为便于阅读,上述估计两幅图像之间的变换的程序已放置在MATLAB®函数中cvexEstStabilizationTform.功能cvexTformToSRT还将一般仿射变换转换为刻度转换变换。

在每一步我们计算变换 H 在现在的框架之间。我们把它写成s-R-t变换, H S. R. T. .然后我们结合这个累积变换, H C M. L. 一种 T. 一世 V. E. ,它描述了自第一帧以来的所有相机运动。平滑视频的最后两个帧显示在视频播放器中作为红星复合材料。

使用这段代码,您还可以去掉早期退出条件,使循环处理整个视频。

%将视频源重置为文件的开头。读(hVideoSrc, 1);hVPlayer = vision.VideoPlayer;创建视频查看器%处理视频中的所有帧movMean = rgb2gray (im2single (readFrame (hVideoSrc)));imgB = movMean;imgBp = imgB;correctedMean = imgBp;2 = 2;Hcumulative =眼(3);hasFrame(hVideoSrc) && ii < 10%读取新帧imgA = imgB;% z ^ 1imgAp = imgBp;% z ^ 1IMGB = RGB2GRAY(IM2single(ReadFrame(HVideOSRC))));movmean = movmean + imgb;%估计从帧A到帧B的变换,并适合为s-R-tH = CVEXESTSTABILIZEDTFORM(IMGA,IMGB);hsrt = cvextformtosrt(h);hcumulative = hsrt * hcululative;IMGBP = IMWARP(IMGB,AFFINE2D(HCUMULIVE),“OutputView”imref2d(大小(imgB)));%显示为彩色合成与最后校正的帧步骤(hVPlayer imfuse (imgAp imgBp,“ColorChannels”“red-cyan”));correctedMean = correctedMean + imgBp;2 = 2 + 1;结束correctedMean = correctedMean / (ii-2);movMean = movMean / (ii-2);在这里,你调用对象的release方法来关闭任何打开的文件%和释放内存。释放(hVPlayer);

在计算期间,我们计算了原始视频帧和校正帧的平均值。这些平均值在下方并排示出。左图像显示了原始输入帧的平均值,证明了原始视频中存在很大的失真。然而,右侧校正帧的平均值显示了几乎没有失真的图像核心。虽然前景细节已经模糊(作为汽车前进运动的必要结果),但这显示了稳定算法的功效。

图;imshowpair (movMean correctedMean,'剪辑');标题([“原始输入的意思”repmat (''50 [1]),“修正序列的意思”]);

参考文献

[1] Tordoff, B;穆雷,DW。"运动估计的引导采样和共识"计算机视觉,2002。

[2]李,肯塔基州;壮族,YY;陈,;Ouhyoung, M。“使用鲁棒特征轨迹的视频稳定。”国立台湾大学,2009。

[3] Litvin,A;konrad,j;Karl,WC。“概率视频稳定使用卡尔曼滤波和摩西思考。”IS&T / SPIE专题讨论会在电子成像,图像和视频通信和PROC。,2003年。

[4]松下,Y;Ofek E;唐,X;Shum HY。“帧视频稳定。”微软®亚洲研究院。CVPR 2005。