我有一台相机,每帧都会收到一个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以向后的顺序向我发送字节...
答案 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)
您应该使用图像库,它比您自己的实现更容易,更健壮,更高效。为了检测背景偏移,我会计算图像的渐变并将其与之前的图像进行比较。模糊图像可能会很有趣。您可以使用二次函数比较前一个梯度和当前梯度之间的误差。