关于视频剪辑算法的简单实现

    xiaoxiao2025-02-27  21

    前段时间看到一个有关视频剪辑的算法,主要用来剪辑那种循环播放的视频片断,关键就是开始和结束画面要非常的相似。思路是将每一帧看作很多象素点构成N维空间的一个点,然后寻找距离小于某一个阀值两个点。由于这种视频不能太长,所以只需要在某一帧的前面k帧寻找就可以,而不需要和其他所有对比。

    直接编程比较很简单,但是耗时很大,因为一个1024*1024的画面就有10^6个像素点,如果是剪辑一个1小时的视频,那么一共有3600*24帧,要剪辑的视频片断在5s以内的话,那么最终的计算量是 1013 。如果视频的画质,时间更长的话,运算时间还要多很多。

    (a) 所以采取的一个解决思路就是利用平面几何的一些定理来减少运算。假设有f1,f2,f3三个帧,那么设它们之间的距离是 f12,f13,f23 ,则根据三角形的性质有:

    f13>max(f12f23,f23f12) f13<min(f12+f23)

    (b) 再计算每一个帧 fi 它的范式: di=ixi2 ,则 fijdi+dj,dij|didj| 可以计算出每一个帧之间距离的初始上下界,那么最终可以得到这个式子:

    f13max=min(f13max,f23max+f12)

    f13min=max(f13min,f12f23max,f23minf12)

    (c) 上面这个式子有点复杂,需要自己好好理解。稍微说明一下, f13max 是f1和f3距离的上界,在确定了1,2的距离时,就可以来更新和1,2有关联的第三个点的距离的估计了。注意到, f13f12+f23 ,但是由于f_23本身的距离可能尚未确定,所以必须要确保这个等式的正确性,那么就应该取 f12+f23 的最大值才能确保。之后的min代表上界缩小了才能更新它。

    (d): 利用上下界和阀值的比较可以省略很多不必要的计算。

    return x def clip(video,k = 5): distance = 50 def test_near_far(l,u): nonlocal is_confirmed if l > distance:is_confirmed[f2][f1] = -1 elif u < distance:is_confirmed[f2][f1] = 1 def update_ul(f1,f2,f3,f21): nonlocal lower,upper upper[f3][f1] = min(upper[f3][f1],f21+upper[f2][f3]) lower[f3][f1] = max(lower[f3][f1],f21-upper[f2][f3],lower[f2][f3]-f21) n = len(video) upper,lower,ini = [[None]*n for i in range(n)]*n,[[None]*n for i in range(n)]*n,[0]*n is_confirmed = [[None]*n for i in range(n)] D = [[-1]*n for i in range(n)] for f1 in range(n): ini[f1] = (sum([i*i for i in video[f1]]))**(0.5) for f2 in range(0,f1): lower[f2][f1] = abs(ini[f1]-ini[f2]) upper[f2][f1] = ini[f1]+ini[f2] test_near_far(lower[f2][f1],upper[f2][f1]) for f1 in range(n): fra1 = video[f1] for f2 in range(max(f1-k,0),f1): fra2 = video[f2] if is_confirmed[f2][f1]!=None: if is_confirmed[f2][f1]==1:print(f2,f1,'near') continue d_12 = sum([(fra1[i]-fra2[i])**2 for i in range(len(fra1))])**0.5 upper[f2][f1],lower[f2][f1] = d_12,d_12 if d_12<distance:is_confirmed[f2][f1] = 1 else:is_confirmed[f2][f1]=-1 for f3 in range(f2+1,f1): update_ul(f1,f2,f3,d_12) test_near_far(lower[f3][f1],upper[f3][f1]) def createdata(): from random import randint n1,n2 = 50,1000 ans = [[randint(0,10) for i in range(n2)]] for i in range(n1): t = ans[-1] if i%3==0:ans.append([j+randint(-1,1) for j in t]) else:ans.append([j+randint(-3,3) for j in t]) return [ans] test(clip,randargs = createdata,case=10)
    转载请注明原文地址: https://ju.6miu.com/read-1296707.html
    最新回复(0)