【发布时间】:2013-05-30 18:20:43
【问题描述】:
我有一个摄像头,我从它接收每个帧的 ByteBuffer。我从 ByteBuffer 中提取 640px x 480px 11 位灰度图像并将其保存到一个短 [640] [480] 中。我这样做是因为我不需要它作为图像并且我认为这会更快(如果我错了请纠正我)。
现在每秒大约执行 30 次。对于每一帧,程序会将任何相差超过 20 且小于当前像素的现有值的值保存到该像素的值中。它有效地在我的 short[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 个角加上中心进行采样来解决此问题,并查看是否在现有图像中找到匹配项。您的样本需要足够大以排除某些东西从角落框架中移出,但要足够小以使其快速。为了排除相机光圈的光照变化或一般光照的变化,我会使用从最亮到最暗的百分比进行匹配。
-
@CodeChimp 的问题是你怎么知道相机是向左还是向右移动?如果它向右移动,左边的角会消失,右边的角会是新的,如果背景足够平淡,所有这些都将是彼此无法确定的。
标签: java algorithm image-processing computer-vision video-processing