安卓比较两张图片并突出显示不同之处。

5

我们将提供2张图片。我们需要找出它们之间的差异并加以突出。

目前我已经在JAVA中找到了这个解决方案,但由于Android不支持BufferedImage,因此我无法继续进行下去。我已经接近比较两个位图的像素,但是遇到了问题。

我还尝试过比较两个位图的像素,但它会突出显示所有非白色的颜色。

void findDifference(Bitmap firstImage, Bitmap secondImage)
{
    if (firstImage.getHeight() != secondImage.getHeight() && firstImage.getWidth() != secondImage.getWidth())
        Toast.makeText(this, "Images size are not same", Toast.LENGTH_LONG).show();

    boolean isSame = true;

    for (int i = 0; i < firstImage.getWidth(); i++)
    {
        for (int j = 0; j < firstImage.getHeight(); j++)
        {
            if (firstImage.getPixel(i,j) == secondImage.getPixel(i,j))
            {
            }
            else
            {
                differentPixels.add(new Pixel(i,j));
                secondImage.setPixel(i,j, Color.YELLOW); //for now just changing difference to yello color
                isSame = false;
            }
        }
    }
    imgOutput.setImageBitmap(secondImage);
}

提前致谢。


你遇到了什么问题?你能提供任何代码帮助我们看到你已经尝试过什么吗?有任何堆栈跟踪或错误日志吗? - Cruceo
我已经添加了代码的详细信息以及我所得到的结果。谢谢。 - Haris
1
只是一条注释,但是你用来验证图像是否具有相同大小的测试是错误的。应该使用“||”而不是“&&”。 - Sunreef
2
@Sunreef,您能否也发布一些图片吗?也许它们是不同的?通常您需要允许一些eps差异,例如(Color.red(firstImage.getPixel(i,j)) - Color.red(secondImage.getPixel(i,j))) < eps && (Color.blue(firstImage.getPixel(i,j)) - Color.blue(secondImage.getPixel(i,j))) < eps && (Color.green(firstImage.getPixel(i,j)) - Color.green(secondImage.getPixel(i,j))) < eps,尝试eps=3。 - taarraas
2个回答

7

借助数字颜色计,我发现在看起来相似的图像之间存在非常微小的差异,与@taarraas提出的观点相当相似。因此,我设置了一个阈值并按照以下方式解决了这个问题。

private static final int threashold = 10;

void findDifference(Bitmap firstImage, Bitmap secondImage)
{
    if (firstImage.getHeight() != secondImage.getHeight() || firstImage.getWidth() != secondImage.getWidth())
        Toast.makeText(this, "Images size are not same", Toast.LENGTH_LONG).show();

    boolean isSame = true;

    for (int i = 0; i < firstImage.getWidth(); i++)
    {
        for (int j = 0; j < firstImage.getHeight(); j++)
        {
            int pixel = firstImage.getPixel(i,j);
            int redValue = Color.red(pixel);
            int blueValue = Color.blue(pixel);
            int greenValue = Color.green(pixel);

            int pixel2 = secondImage.getPixel(i,j);
            int redValue2 = Color.red(pixel2);
            int blueValue2 = Color.blue(pixel2);
            int greenValue2 = Color.green(pixel2);

            if (Math.abs(redValue2 - redValue) + Math.abs(blueValue2 - blueValue) + Math.abs(greenValue2 - greenValue) <= threashold)
//                if (firstImage.getPixel(i,j) == secondImage.getPixel(i,j))
            {
            }
            else
            {
                differentPixels.add(new Pixel(i,j));
                secondImage.setPixel(i,j, Color.YELLOW); //for now just changing difference to yello color
                isSame = false;
            }
        }
    }
    imgOutput.setImageBitmap(secondImage);
}

1
为了获得最佳性能,请使用getPixels()而不是getPixel(),并使用while()匹配数组中的每个键。在处理高清图像时,可以节省约2秒的时间,在实时处理视频时需要更快的速度。 - e-info128

1

如果你想逐像素比较图像,可以这样做:

private void findDifference(Bitmap firstImage, Bitmap secondImage) {
    Bitmap bmp = secondImage.copy(secondImage.getConfig(), true);

    if (firstImage.getWidth() != secondImage.getWidth()
            || firstImage.getHeight() != secondImage.getHeight()) {
        return;
    }

    for (int i = 0; i < firstImage.getWidth(); i++) {
        for (int j = 0; j < firstImage.getHeight(); j++) {
            if (firstImage.getPixel(i, j) != secondImage.getPixel(i, j)) {
                bmp.setPixel(i, j, Color.YELLOW);
            }
        }
    }

    imgOutput.setImageBitmap(bmp);
}

我看到了一些重构,但逻辑没有改变。我有什么遗漏吗? - taarraas
@taarraas 你说得对。我之前没有测试过Haris的代码,但是我刚刚测试了一下,它可以正常工作。 - antonio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接