0

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

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

现在对于这个问题,相机可能会移动,从而改变背景。我从一个不动的相机得到的背景已经改变了很多(也有很大的边距)每一帧。实际上,它仅足够稳定以提取大型前景对象。所以我需要一个算法来告诉我相机和图像发生了多少变化,所以我知道图像中哪些区域是新的,但大多数区域仍然可用。

我能想到的唯一方法是扫描每个可能的班次的图像,看看哪个最匹配,因为就像我说的那样,它可能只是不太匹配,但仍然是最好的匹配。有没有更好的方法来解决这个问题?因为这样我必须每帧扫描整个图像大约 120 万次......

此外,我不使用处理或 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() 是字节缓冲区中的字节数。frame.get 从我的字节缓冲区中获取一个字节。出于某种原因,kinect 以倒序的方式向我发送字节......

4

2 回答 2

1

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

于 2013-06-04T14:51:01.423 回答
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];
    }
}
于 2013-06-04T14:23:10.560 回答