积分图像 - 在位图中有效地找到大小宽度和高度的空白空间

时间:2014-07-29 19:34:18

标签: java image algorithm bitmap

我试图找到一种算法,在Bitmap中找到一个足够大的空间来包含一个新的位图。目前我正在迭代每个x和y像素,看看我的小位图是否会与背景发生冲突。它有效,但速度极慢。我最近发现了一种称为积分图像的东西来解析背景图像,然后检查其中的空间是否在恒定时间内可用。

我使用的算法是:

public class IntegralImage 
{
private int[][] integralImage = null;

public IntegralImage(Bitmap image) 
{
    int originalImageHeight = image.getHeight();
    int originalImageWidth = image.getWidth();
    integralImage = new int[originalImageHeight][originalImageWidth];
    int[][] originalPixels = new int[image.getHeight()][image.getWidth()];
    for(int i = 0; i < image.getHeight(); i++)
    {
        for(int j = 0; j < image.getWidth(); j++)
        {
            originalPixels[i][j] = image.getPixel(j, i);
        }
    }
    int originalPixelValue = 0;
    for (int row = 0; row < originalImageHeight; row++) 
    {
        for (int column = 0; column < originalImageWidth; column++) 
        {
            originalPixelValue = originalPixels[column][row];

            if (row == 0 && column == 0) 
            {
                integralImage[row][column] = originalPixelValue;
            }

            else if (row == 0) 
            {
                integralImage[row][column] = originalPixelValue + integralImage[row][column - 1];
            }


            else if (column == 0) 
            {
                integralImage[row][column] = originalPixelValue + integralImage[row - 1][column];
            }
            else 
            {
                integralImage[row][column] = originalPixelValue + integralImage[row][column - 1] + integralImage[row - 1][column] - integralImage[row - 1][column - 1];
            }
        }
    }
}

public int total(int x1, int y1, int x2, int y2) 
{
    int a = x1 > 0 && y1 > 0 ? integralImage[x1-1][y1-1] : 0;
    int b = x1 > 0 ? integralImage[x1-1][y2] : 0;
    int c = y1 > 0 ? integralImage[x2][y1-1] : 0;
    int d = integralImage[x2][y2];
    return a + d - b - c;
}

}

然而,当我用它来称呼它时:

if(imageIntegral.total(i, j, i + _imageBitmap.getWidth(), j + _imageBitmap.getHeight()) == 0)

它总是返回true ,只是将所有文本位图堆叠在一起。

有没有人尝试在位图中调整位图而不会有效重叠?

我的理解是,如果子数组只包含白色像素,它应该返回零。

谢谢。

1 个答案:

答案 0 :(得分:0)

我建议你的方法很少改进,以加快速度。

首先,我们可以更快地找到可能的位置:

int w = _imageBitmap.getWidth();
int h = _imageBitmap.getHeight();

for (int i = originalImageWidth - 1; i >= w/4; i -= w/2)
    for (int j = originalImageHeight  - 1; j >= h/4; j -= h/2)
    {
        //it may be a bit strange to check (i - w/2, j - h/2, i, j) instead of ( i, j, i + w/2, j + h/2)
        // but it's simpler considering your integral image implementation.
        if (imageIntegral.total(i - w/2, j - h/2, i, j) == 0)
        {
            //check if there is enough space around
        }
    }

如果_imageBitmap有一个位置,它应至少包含一个w / 2 x h / 2个tile。 在这种情况下,你最多可以减少h * w / 4次的支票数量。

也无需检查(h / 2 x w / 2)平铺内的每个像素是否为位图的中心位置。如果存在空位(i-w1,j-h1,i,j),则假设w1&lt; w和h1 < h,我们想检查周围是否有(w x h)位图的位置我们可以检查下面的中型矩形的展示位置

(i - w1, j - h1, i - w1 + (w + w1)/2, j - h1 + (h + h1)/2)
(i - w1, j - (h + h1)/2, i- w1 + (w + w1)/2, j)
(i - (w + w1)/2, j - h1, i, j - h1 + (h + h1)/2)
(i - (w + w1)/2, j - (h + h1)/2, i, j)

(每个是(w + w1)/ 2 x(h + h1)/ 2大小的矩形,在某些角落与内部矩形匹配) 如果其中四个中没有一个是空闲的,那么(w x h)矩形也没有自由的位置,否则它会缩小四次进一步搜索的区域。 您可以循环重复此检查以在对数时间内检查位置。

我不完全确定它总是返回true 是什么意思,如果它在其他地方不包含未被注意的错误,你的代码应该正常工作(如果0对应于白色像素等等) )。也许你在没有更新积分图像的情况下在位图上放置一些新图片后再次搜索自由位置?如果你正在画画。在位图和再次搜索自由位置完整更新积分图像可能会很慢,你可能会尝试只更新使用的积分图像的区域,或尝试使用一些其他方法 - 可能与物体碰撞检测有关,但最佳方法取决于任务的具体细节。