主要内容

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

这个例子展示了如何稳定从一个紧张的平台捕获的视频。稳定视频的一种方法是跟踪图像中的一个显著特征,并将其作为锚点来抵消与它相关的所有扰动。然而,在引导这个过程时,必须知道在第一个视频帧中这个显著特征在哪里。在这个例子中,我们探索了一种不需要任何这样的方法的视频稳定先验知识。相反,它会自动搜索视频序列中的“背景平面”,并利用其观测到的失真来校正摄像机的运动。

该稳定算法包括两个步骤。首先,利用该方法确定视频序列中所有相邻帧之间的仿射图像变换estimateGeometricTransform2d.函数用于两个图像之间的点对应。其次,我们扭曲视频帧来实现稳定的视频。我们将使用计算机视觉工具箱™,用于算法和显示。

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

在这里,我们读到了视频序列的前两个帧中。我们将它们读取为强度图像,因为稳定算法不需要颜色,并且因为使用灰度图像提高了速度。下面我们并排显示两个框架,我们生产一个红星色彩复合材料,以说明它们之间的像素方面的差异。两帧之间显然存在大的垂直和水平偏移。

文件名='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”);标题('Color composite (frame A =红色,frame B =青色)');

步骤2。收集每一帧的突出点

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

在这个步骤中,我们为每一帧生成候选点。为了使这些点有最好的机会在另一帧中有相应的点,我们希望在图像显著特征(如角)周围有点。为此,我们使用检测到空间函数,它实现最快的角落检测算法之一。

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

ptThresh = 0.1;pointsA = detectFASTFeatures (imgA,“MinContrast”, ptThresh);pointsB = detectFASTFeatures (imgB,“MinContrast”, ptThresh);%显示图像A和B中的角。图;imshow(Imga);持有;情节(pointsA);标题('拐角处');

图;imshow (imgB);持有;情节(pointsB);标题(“B角落”);

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

接下来我们选择在上面导出的点之间的对应关系。对于每个点,我们提取一个快速视网膜键点(Freak)描述符以其为中心。我们在点之间使用的匹配成本是汉明距离,因为怪胎描述符是二进制的。框架A和帧B中的点符合匹配。注意,没有唯一性约束,因此来自帧B的点可以对应于框架A中的多个点。

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

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

indexPairs = MatchFeatures(特点,功能);pointsa = pointipta(IndexPairs(:,1),:);指点= pointb(indexPairs(:,2),:);

下图显示了上面给出的相同颜色复合,但是添加的是来自帧A中的帧A的点,以及来自帧B的点为绿色。在点之间绘制黄线以显示通过上述过程选择的对应关系。许多这些相应关系是正确的,但也有很多异常值。

图;showMatchedFeatures(imgA, imgB, pointsA, pointb);传奇(“一个”“B”);

步骤4.从嘈杂的对应关系估算变换

在前一步中得到的许多点对应是不正确的。但是,我们仍然可以使用RANSAC算法的变体M-estimator SAmple Consensus (MSAC)算法对两幅图像之间的几何变换进行稳健估计。文中实现了MSAC算法estimateGeometricTransform2d.函数。当给定一组点对应时,该函数将搜索有效的内部对应。然后,它将从这些派生出仿射变换,使第一组点的内嵌线与第二组点的内嵌线最接近匹配。这个仿射变换将是一个3 × 3的矩阵,形式如下:

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

的参数 一个 定义缩放、旋转和变换的剪切效果,同时参数 t 是翻译参数。该变换可用于横跨图像,使得它们的对应特征将被移动到相同的图像位置。

对仿射变换的限制是它只能改变成像平面。因此,它不适用于找到由3-D场景的两个帧之间的一般变形,例如从移动的汽车拍摄的视频。但它确实在某些条件下工作,我们很快就会描述。

[tform, inlierIdx] = estimateGeometricTransform2D(...pointsB pointsA,仿射的);pointsBm = pointsB(inlierIdx,:);pointsAm = pointsA(inlierIdx,:);imgBp = imwarp(imgB, tform,“OutputView”imref2d(大小(imgB)));pointbmp = transformpointforward (tform, pointbmp . location);

下面是一种彩色复合物,其显示框架A覆盖着被训斥的框架B,以及Repeteed Point对应关系。结果非常好,与Inlier的对应几乎完全一致。图像的核心均均良好对齐,使得红蓝色复合材料在该区域中几乎纯粹是黑白的。

请注意,Inlier对应关系如何在图像的背景中,而不是在前景中,本身未对齐。这是因为背景特征足够远,以至于它们表现得像它们在无限遥远的平面上。因此,即使仿射变换仅限于仅改变成像平面,这里也足以对准两个图像的背景平面。此外,如果我们假设背景平面在帧之间没有显着移动或改变,则该变换实际上是捕获相机运动。因此,纠正这将稳定视频。只要帧之间的相机的运动足够小,或者相反,如果视频帧速率足够高,则该条件将保持。

图;showMatchedFeatures(imgA, imgBp, pointsAm, pointsBmp);传奇(“一个”“B”);

第5步。变换近似与平滑

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

H c u u 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 年代 R t .为了表明转换变换的误差是最小的,我们用两个变换重新投影B帧,并将下面的两幅图像显示为红青色合成。由于图像是黑白的,很明显,不同重投影之间的像素差异是可以忽略不计的。

%提取比例和旋转部分子矩阵。H = tform.T;R = H (1:2, 1:2);%从两个可能的突出件的平均值计算θθ=平均值([atan2(r(2),R(1))Atan2(-3(3),R(4))]);从两个稳定平均计算的平均值计算尺度scale = mean(R([1 4])/cos(theta));%翻译保持不变:平移= H(3, 1:2);%重构新的s-R-t变换:HsRt = [[scale*[cos(theta) -sin(theta));罪(θ)因为(θ)];...翻译],[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 年代 R t .然后我们结合这个累积变换, H c u u l 一个 t v e ,它描述了自第一帧以来摄像机的所有运动。平滑视频的最后两帧在视频播放器中显示为红青色合成。

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

%将视频源重置为文件的开头。读(hVideoSrc, 1);hVPlayer = vision.VideoPlayer;%创建视频查看器%处理视频中的所有帧movMean = rgb2gray (im2single (readFrame (hVideoSrc)));imgB = movMean;imgBp = imgB;correctedMean = imgBp;2 = 2;Hcumulative =眼(3);Hasfame(HVIDESSRC)&& II <10%读取新帧IMGA = IMGB;% z ^ 1imgAp = imgBp;% z ^ 1imgB = rgb2gray (im2single (readFrame (hVideoSrc)));movMean = movMean + imgB;%估计从帧A到帧B的变换,并适合为s-R-tH = cvexEstStabilizationTform (imgA imgB);HsRt = cvexTformToSRT (H);Hcumulative = HsRt * Hcumulative;imgBp = imwarp (imgB affine2d (Hcumulative),“OutputView”imref2d(大小(imgB)));%显示为上次校正帧的颜色复合步骤(hVPlayer imfuse (imgAp imgBp,'colorchannels'“red-cyan”));纠正级=纠正剧+ IMGBP;II = II + 1;结束correctedMean = correctedMean / (ii-2);movMean = movMean / (ii-2);在这里,你调用对象的release方法来关闭任何打开的文件%和释放内存。释放(hVPlayer);

在计算过程中,我们计算原始视频帧和校正帧的均值。这些平均值在下面并排显示。左边的图像是原始输入帧的均值,说明原始视频存在较大的失真。然而,右边校正帧的平均值显示的图像核心几乎没有失真。虽然前景细节已经被模糊(作为汽车前进的必要结果),这显示了稳定算法的效力。

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

参考

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

[2] Lee,Ky;庄,yy;陈,由;Ouhyoung,M。“使用鲁棒特征轨迹的视频稳定”。2009年国立台湾大学。

[3] Litvin,;康拉德,J;卡尔,WC。"利用卡尔曼滤波和马赛克的概率视频稳定"电子图像、图像和视频通信技术研讨会,2003。

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