比较两个图像以进行运动检测

时间:2012-05-07 18:28:35

标签: java android detection motion getpixel

我已经开始通过使用简单的算法计算不同像素的数量来区分两个图像:

private int returnCountOfDifferentPixels(String pic1, String pic2)
    {
        Bitmap i1 = loadBitmap(pic1);
        Bitmap i2 = loadBitmap(pic2);
        int count=0;

        for (int y = 0; y < i1.getHeight(); ++y)
               for (int x = 0; x < i1.getWidth(); ++x)
                    if (i1.getPixel(x, y) != i2.getPixel(x, y)) 
                        {
                        count++;
                        }

          return count;

    }

然而,这种方法在其初始形式中似乎效率低下,因为即使在非常相似的照片中也总是存在非常多的像素。 我正在考虑一种确定两个像素是否真的不同的方法。 android中的bitmap.getpixel(x,y)返回一个Color对象。

如何在两个Color对象之间实现适当区分,以帮助我进行运动检测?

2 个答案:

答案 0 :(得分:2)

你是对的,由于噪音和其他因素,视频流中通常会有很多原始像素变化。以下是您可能需要考虑的一些选项:

  1. 首先模糊图像,理想情况下使用高斯滤波器或简单的盒式滤波器。这只意味着您对相邻像素和像素本身采用(加权)平均值。这应该会减少传感器的噪音。

  2. 如果差异大于某个阈值,则只将差异添加到count。这具有仅考虑真正改变很多的像素的效果。这很容易实现,可能已经单独解决了您的问题。

  3. 考虑一下,首先尝试这两个选项。如果他们没有成功,我可以给你更多选择。

    编辑:我刚刚看到你实际上并没有总结差异,只计算不同的像素。如果你将它与选项2结合使用就没问题了。选项1仍然有效,但可能是一种过度杀伤。

    另外,要找出两种颜色之间的差异,请使用Color class

    的方法
    int p1 = i1.getPixel(x, y);
    int p2 = i2.getPixel(x, y);
    int totalDiff = Color.red(p1) - Color.red(p2) + Color.green(p1) - Color.green(p2) + Color.blue(p1) - Color.blue(p2);
    

    现在,您可以提出totalDiff必须超过的阈值,以便为count做出贡献。

    当然,您可以通过各种方式使用这些数字。例如,上述代码仅计算像素强度(亮度)的变化。如果您还想考虑色调和饱和度的变化,则必须像这样计算totalDiff

    int totalDiff = Math.abs(Color.red(p1) - Color.red(p2)) + Math.abs(Color.green(p1) - Color.green(p2)) + Math.abs(Color.blue(p1) - Color.blue(p2));
    

    另外,请查看Color的其他方法,例如RGBToHSV(...)

答案 1 :(得分:0)

我知道这与此处的另一个答案基本相似,但我认为应该以不同的形式重申它,它可能对那些寻求解决方案的人有用。这包括随着时间的推移有两个以上的图像。如果你只是字面意思,那么这将不起作用,但一个等效的方法将。

为每个帧上的所有像素创建历史记录。例如,对于每个像素: history[x, y] = (history[x, y] * (w - 1) + get_pixel(x, y)) / w

w可能是w = 20的位置。运动峰值越大w,但重置时必须缺少更长的运动。

然后,要确定某些内容是否已更改,您可以为每个像素执行此操作:

changed_delta = abs(history[x, y] - get_pixel(x, y))

total_delta += changed_delta

你会发现它可以稳定大部分噪音,当运动发生时,你会得到很大的差异。你实际上是采用了很多帧并且从最近的帧中检测出许多帧的运动。

另外,为了检测运动位置,考虑将图像分成更小的部分并单独进行。然后,您可以通过将单个图像视为单独图像的网格来查找对象并在屏幕上跟踪它们。