Python 如何在Matlab上求稳定视频帧的旋转角

Python 如何在Matlab上求稳定视频帧的旋转角,python,matlab,matrix,image-rotation,image-stabilization,Python,Matlab,Matrix,Image Rotation,Image Stabilization,假设我有以下稳定的视频帧,其中稳定仅通过旋转和平移(无缩放)完成: 如图所示,图像的右侧与前面的像素对称,即旋转后的黑色区域充满对称性。我加了一条红线,以便更清楚地表明这一点。 我想找到旋转角度,稍后我会用到。我可以通过冲浪或筛选功能来实现这一点,但是,在实际情况下,我不会使用原始帧 我可能可以用蛮力找到角度,但我想知道是否有更好更优雅的解决方案。请注意,对称部分的强度值与原始部分的强度值并不完全相同。我检查了一些值,例如,键盘上V字符的右上角像素在原始部分是[51 49 47],但在对称副

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

如图所示,图像的右侧与前面的像素对称,即旋转后的黑色区域充满对称性。我加了一条红线,以便更清楚地表明这一点。

我想找到旋转角度,稍后我会用到。我可以通过冲浪或筛选功能来实现这一点,但是,在实际情况下,我不会使用原始帧

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

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

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

如果有任何帮助/建议,我们将不胜感激。

如果

  • 其(第一个/第二个/第三个/…)左点和右点相等(=>
    dG
    ,图1左)
  • 其(第一个/第二个/第三个/…)左(或右)值不同(=>
    dGs
    ,图1中间)
因此,兴趣点的特征是
|dGs |-|dG |
(=>
dGs|dG
,图1右侧)的高值

如图1右图所示,仍然存在大量误报。因此,Hough变换(图2左)将用于检测与最强线(图2右)对应的所有点。绿线确实是搜索到的线

调整

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

  • 更改阈值:在
    dgsdg
    上设置更高的阈值将丢弃更多的误报。丢弃较高的
    dG
    值也可能会对丢弃原始图像中的边缘位置感兴趣

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

用于生成图像的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
I=imread('bnuqb.png');
G=int16(rgb2gray(I));
n=3;%使用第一个、第二个和第三个左/右点
dG=int16(零(大小(G)-[02*n+2]);
dGs=int16(零(大小(G)-[02*n+2]);
对于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));
结束
dGs_dG=dGs-dG;
dGs_dG(dGs_dG<0)=0;
图形
子批次(1,3,1);
imshow(dG,[]))
子批次(1,3,2);
imshow(dGs,[]))
子批次(1,3,3);
imshow(dGs_dG,[])
BW=dGs_dG>0;
[H,θ,rho]=hough(BW);
P=小时峰值(H,1);
直线=houghlines(BW、θ、rho、P、'FillGap',50000、'MinLength',7);
图形
子批次(1,2,1);
imshow(H,[])
等等
图(P(:,2),P(:,1),‘r.);
子批次(1,2,2);
imshow(I(:,n+2:end-n-1,:)
等等
最大长度=0;
对于k=1:长度(线)
xy=[行(k).point1;行(k).point2];
图(xy(:,1),xy(:,2),'g');
结束

最好的方法是使用与
ffmpeg
相同的转换。我想你是在用ffmpeg的插件吧?如果是这样,您可能在过程中的某个地方生成了一个“transforms.trf”文件。我将研究此文件的格式,并从中提取值。@Aaron我应该提到的是,我只有
稳定视频
。现在更新问题。我使用的是
deshake
插件,我使用的命令是
ffmpeg.exe-I infle-vf deshake-c:v libx264-crf 0-preset veryslow outfile
。谢谢你的代码。不幸的是,它在许多情况下都不起作用:(在许多情况下,它非常接近,但不是非常精确。而且,在某些情况下,它工作得非常完美。我认为,假设对称性不在图像的中心,可能会提高性能。但是有没有办法将边缘对我共享的图像的影响降至最低。它们肯定会增加假阳性。另外,在以下两种情况下图像,它不是完全准确的。是原始图像,它的缩放版本是。在缩放图像右边缘的文件夹附近,有10个像素偏移。我增加了
n
,仍然没有变化。我添加了一些调整选项,特别是丢弃了hough变换中的一些区域,并在
dG可能很有趣。请注意,增加
n
也会丢弃更多的边界像素。这可以通过修改编辑后的文章中指出的算法来避免。目前我没有办法克服这种不精确性。可能需要进行一些后处理,使线条稍微适应,以便更好地与
dGs\dG的高值吻合?你确定对称线应该是一条直线吗?我同意
n
。但我认为增加1-2可能会稍微好一点。我认为这些线应该是直线,因为旋转是全局的,所以我看不到任何不应该是直线的原因。(另外,我还没有看到任何
非直的
线)。