【问题标题】:How to find rotation angle of a stabilized video frame on Matlab如何在 Matlab 上找到稳定视频帧的旋转角度
【发布时间】:2017-04-07 20:20:58
【问题描述】:

考虑我有以下稳定的视频帧,其中仅通过旋转和平移(无缩放)完成稳定:

如图所示,图像的右侧与之前的像素对称,即旋转后的黑色区域被对称填充。我添加了一条红线以更清楚地表明它。

我想找到稍后将使用的旋转角度。我可以通过 SURF 或 SIFT 功能完成此操作,但是,在实际情况下,我不会拥有原始帧。

我可能可以通过蛮力找到角度,但我想知道是否有更好更优雅的解决方案。请注意,对称部分的强度值与原始部分并不完全相同。我检查了一些值,例如,键盘上 V 字符的右上角像素原始部分中是 [51 49 47],但在 对称副本中是 [50 50 47] 这意味着相应的像素不能保证是相同的RGB 值。

我将在 Matlab 或 python 上实现这一点,并使用ffmpeg 完成视频稳定。

编辑:我只有稳定的视频,无法访问原始视频或ffmpeg制作的文件。

感谢任何帮助/建议,

【问题讨论】:

  • 最好的方法是使用与ffmpeg 相同的转换。我假设您正在为 ffmpeg 使用VidStab 插件?如果是这样,您可能在进程的某处生成了一个 'transforms.trf' 文件。我会研究这个文件的格式,并从中提取值。
  • @Aaron 我应该提到我只有stabilized video。现在更新了问题。我正在使用deshake 插件,我使用的命令是ffmpeg.exe -i infile -vf deshake -c:v libx264 -crf 0 -preset veryslow outfile

标签: python matlab matrix image-rotation image-stabilization


【解决方案1】:

如果一个像素(可能)位于搜索到的对称线上

  • 它的(first/second/thrid/...)左右点相等(=> dG,图 1 左)
  • 它的 (first/second/thrid/...) 左(或右)值不同(=> dGs,图 1 中间)

因此,兴趣点的特点是 |dGs| - |dG| 的值较高(=> dGs_dG,图 1 右)

从图 1 的右图可以看出,仍然存在很多误报。因此,Hough 变换(图 2 左)将用于检测最强线对应的所有点(图 2 右)。绿线确实是搜索到的线。

调整

  • 更改n:更高的值会丢弃更多的误报,但也会排除n 边框像素。这可以通过对边框像素使用较低的n 来避免。

  • 更改阈值:dGs_dG 的更高阈值将丢弃更多误报。丢弃 dG 的高值也可能对丢弃原始图像中的边缘位置很有趣。

  • 对称线的先验知识:利用霍夫变换的定义,可以丢弃所有通过图像中心部分的线。

生成图片的matlab代码为:

I = imread('bnuqb.png');
G = int16(rgb2gray(I));

n = 3; % use the first, second and third left/right point
dG = int16(zeros(size(G) - [0 2*n+2]));
dGs = int16(zeros(size(G) - [0 2*n+2]));
for i=0:n
  dG = dG + abs(G(:, 1+n-i:end-2-n-i) - G(:, 3+n+i:end-n+i));
  dGs = dGs + abs(G(:, 1+n-i:end-2-n-i) - G(:, 2+n:end-n-1));
end
dGs_dG = dGs - dG;
dGs_dG(dGs_dG < 0) = 0;
figure
subplot(1,3,1);
imshow(dG, [])
subplot(1,3,2);
imshow(dGs, [])
subplot(1,3,3);
imshow(dGs_dG, [])

BW = dGs_dG > 0;
[H,theta,rho] = hough(BW);
P = houghpeaks(H,1);
lines = houghlines(BW,theta,rho,P,'FillGap',50000,'MinLength',7);

figure
subplot(1,2,1);
imshow(H, [])
hold on
plot(P(:, 2),P(:, 1),'r.');

subplot(1,2,2);
imshow(I(:, n+2:end-n-1, :))
hold on
max_len = 0;
for k = 1:length(lines)
   xy = [lines(k).point1; lines(k).point2];
   plot(xy(:,1),xy(:,2),'g');
end

【讨论】:

  • 感谢您的代码。不幸的是,它在很多情况下都不起作用:(在很多情况下它非常接近但不是很准确。dropbox.com/s/dontiwcwrj4lwwy/img55.PNG?dl=0dropbox.com/s/zr0tv2m4i0od911/img125.PNG?dl=0。但在某些情况下它工作得很好。我认为,假设对称性不是在图像的中心可能会提高性能。但是有没有办法最小化边缘对我共享的图像的影响。它们肯定会增加误报。
  • 另外,在以下两张图片中,它并不完全准确。 dropbox.com/s/vt5mmt4wss0tog4/img4a.PNG?dl=0 是原始图像,其缩放版本是dropbox.com/s/dff1hprvzoxmq1n/img4b.PNG?dl=0。在放大图像右侧边缘的文件夹附近,有 10 个像素偏移。我增加了n,还是没有变化。
  • 我添加了一些调整选项,尤其是丢弃霍夫变换中的一些区域并在dG 上应用阈值可能会很有趣。
  • 请注意,增加n 也会丢弃更多的边框像素。这可以通过更改已编辑帖子中指出的算法来避免。我目前没有克服这种不准确性的想法。也许一些后处理可以稍微调整线条以更好地与dGs_dG 的高值相吻合?你确定对称线应该是直线吗?
  • 我同意n。但我认为将其增加 1-2 可能会稍微好一些。我认为线条应该是直的,因为旋转是全局的,所以我看不出它不应该是直的任何理由。 (另外,我还没有看到任何not straight 行)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-03
  • 1970-01-01
  • 2013-02-13
  • 2017-08-19
  • 1970-01-01
  • 1970-01-01
  • 2019-03-10
相关资源
最近更新 更多