概念插值算法

时间:2012-06-06 14:35:46

标签: c algorithm math interpolation

G'早上好 -

我正试图在视频上移动一些边界框。我有点难以理解。如果我每15帧在数据文件上有一个帧,那么我必须在每个真实帧之间创建14帧。由于它是一个工具(实际上是ffmpeg插件的一部分),它需要适用于任何间隙大小。

我写了一个函数,它取两点之间的距离,以及它从开始点到结束点平滑过渡的帧数。理想情况下,此函数返回的是从前一帧移位的像素数组

例如,如果第1帧的x是50,而第16帧是65,那么我将拥有一个所有1的数组,以便每个帧在之前的帧中添加一个。这是我到目前为止所得到的:

int* generateSequence(int difference, int numStep){
  int* sequence = (int*)malloc(sizeof(int*)*numStep);
  int i;
  for(i=0; i<numStep; i++){ 
    sequence[i] = 0;
  }
  while(difference > numStep){
    for(i=0; i<numStep; i++){ 
      sequence[i]++;
    }
    difference -= numStep;
  }

我对这部分感到满意​​(对于两者之间的距离,两者之间的每一个倍数会增加一个到EACH帧之间)。

但现在我已经到了需要在SOME帧中添加一个但不是全部的一个点。我所拥有的只是这些陪审团操纵的算法,对于产生不同帧距离的工具而言,这些算法不是很便携......

double delta = difference/numStep;
if(delta >=.05 && delta< .20){
  for(i=0; i<numStep; i+=6){ 
    sequence[i]++;
  }
}

我应该使用模数运算符还是以不同的方式接近它?看起来像任意值的硬编码并不适合我。

2 个答案:

答案 0 :(得分:1)

为了使此框动画平滑,您需要能够在每个框架上绘制矩形,使得矩形的坐标不会被整数量化。换句话说,如果插值计算导致(例如)X值为21.354且Y值为50.813,则将这些值分别舍入为21和51将不起作用;由此产生的矩形运动将非常不稳定和不规则。

问题是视频的帧是基于像素的,这意味着通常没有内置的方法来绘制具有真实(也就是浮点,而不是整数)坐标的线条或矩形。如果你用来在每个帧上绘制矩形的库只支持整数坐标而不是浮点坐标(你应该检查一下,因为许多图形库支持浮点坐标,会让你的这项任务变得非常轻松),那么你必须自己动手。

您使用什么库将这些矩形实际绘制到视频的每一帧上?

答案 1 :(得分:1)

更一般地说,听起来你想要生成“最平滑”的x个整数系列,其总和为y。 (平滑度是系列中元素之间的平均距离最小。)

这可以通过以下算法实现。

given sum and steps
float step = sum/steps
float delta = 0
sequence = []
for x:
    int integerstep = round(step + delta)
    delta += step - integerstep
    sequence.push(round(integerstep))

python中的示例实现(抱歉,不是c人)可以在下面找到。

def renderSmoothIntegerSequence(steps, distance):
    step = float(distance)/steps
    delta = 0
    sequence = []
    for _ in xrange(steps):
        integerstep = int(round(step + delta))
        delta += step - integerstep
        sequence.append(integerstep)
    return sequence

示例调用:

>>> print renderSmoothIntegerSequence(5,8)
[2, 1, 2, 1, 2]
>>> print renderSmoothIntegerSequence(5,7)
[1, 2, 1, 2, 1]
>>> print renderSmoothIntegerSequence(32,1)
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
>>> print renderSmoothIntegerSequence(1,50)
[50]