什么是找到图像移位的好算法(Java)

时间:2013-06-04 11:15:35

标签: java algorithm image-processing computer-vision video-processing

我有一台相机,每帧都会收到一个ByteBuffer。我从ByteBuffer中提取640px x 480px 11位灰度图像并将其保存到短[640] [480]。我这样做是因为我不想将它作为一个图像而且我认为这会更快(如果我错了,请纠正我)。

现在每秒大约做30次。对于每个帧,程序将保存任何相差20以上的值,并且小于当前像素的现有值到该像素的值。它在我的短[640] [480]中有效地创建了一个背景图像。

现在问题是,相机可能会移动,从而改变背景。我从一个不动的相机中获得的背景已经在每帧中发生了很大变化(也有很大的余量)。真的,它只是足够稳定,可以提取大型的前景物体。所以我需要一种算法,可以告诉我摄像机的数量和图像的移动程度,因此我知道图像中哪些区域是新的,但大多数区域仍然可用。

我能想到的唯一方法就是扫描图像中的每个可能的移位,看看哪个匹配最好,因为就像我说的那样,它可能不是很好,但仍然是最佳匹配。还有什么更好的办法吗?因为这样我每帧大约需要扫描整个图像大约1,200万次......

此外,我不使用处理或openCV或任何此类库。

编辑: 我忘了提一个非常重要的细节,图像是深度图,因此光照不会影响它。

编辑:这里有一些代码,我使用Open Kinect库从Kinect中检索深度图。我还不确定如何解析这些信息,这是我到目前为止工作的唯一方法:

public static short[][] background = new short[640][480];

public void onFrameReceived(FrameMode format, ByteBuffer frame, int timestamp) {

    for(int n=0; n<frame.limit()/2; n++) {

        int index = n*2;
        short Gray = (0xff - frame.get(index) & 0xff) | ((3-frame.get(index+1) & 0x3) * 255);

        short x = n%640;
        short y = n/640;

        if(background[x][y] > Gray + 10 || background[x][y] == 0) {
            background[x][y] = Gray;
        }
    }
}

我每帧得到2个字节,我尝试从中提取一个11位值,表示对象离我的kinect有多远。我不知道怎么回事,但它的工作方式是这样的,所以我稍后会保存这个问题。

附加信息:frame.limit()是bytebuffer中的字节数。 frame.get从我的bytebuffer中获取一个字节。由于某种原因,kinect以向后的顺序向我发送字节...

2 个答案:

答案 0 :(得分:1)

这就是我如何确定相机是否移动的方法。当然,一些填充和差异将要添加到“detectChange()”,但由于我不熟悉您的数据结果,我无法确定:

//pick 100 points at random
private static Point[] keys = new Point[100];

//initially set to the values of background at the key points
private static short[] keyValues = new short[100];


private bool detectChange()
{
    boolean changed = false;
    int amtchanged = 0;
    for(int i = 0; i < 100; i++)
    {
        //point some variance here for leeway
        if(background[keys[i].x][keys[i].y] != keyValues[i])
            amtchanged++;
    }

    if(amtchanged > 75)
        changed = true;

    return changed
}

public void onFrameReceived(FrameMode format, ByteBuffer frame, int timestamp) {

    if(detectChange())
    {
        //find where they went to determine
        //the camera's pan
    }

    //the rest of your code.

    for(int i = 0; i < 100; i++)
    {
        //update the keys to the new data
        keyValues[i] = background[keys[i].x][keys[i].y];
    }
}

答案 1 :(得分:1)

您应该使用图像库,它比您自己的实现更容易,更健壮,更高效。为了检测背景偏移,我会计算图像的渐变并将其与之前的图像进行比较。模糊图像可能会很有趣。您可以使用二次函数比较前一个梯度和当前梯度之间的误差。