Android 中的图像比较。

Image Comparison in Android.

我是 Android 学习者。我正在尝试图像比较。它显示不同大小的相同图像的图像不相同,因此我使用 createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter) 重新缩放了图像。即使在重新缩放之后,当我比较我得到的结果时,两个图像都是不同的。请帮帮我。

            bmpimg1 = BitmapFactory.decodeFile(path1);
            bmpimg2 = BitmapFactory.decodeFile(path2);

            int bm1Height = bmpimg1.getHeight();
            int bm1Width = bmpimg1.getWidth();
            int bm1Res = bm1Height * bm1Width;

            int bm2Height = bmpimg2.getHeight();
            int bm2Width = bmpimg2.getWidth();
            int bm2Res = bm2Height * bm2Width;

            if(bm1Res==bm2Res){
                Toast.makeText(getApplicationContext(), "Both Images Same Size", Toast.LENGTH_SHORT).show();

                if(bmpimg1.sameAs(bmpimg2)){
                    Toast.makeText(getApplicationContext(), "Same", Toast.LENGTH_LONG).show();
                }else{
                    Toast.makeText(getApplicationContext(), "Not Same", Toast.LENGTH_LONG).show();
                }
            }


           if (bm1Res > bm2Res)
            {
                    Bitmap rbm1 = Bitmap.createScaledBitmap(bmpimg1, bmpimg2.getWidth(), bmpimg2.getHeight(), true);
                    ImageView imageView1 = (ImageView) findViewById(R.id.image1);
                    imageView1.setImageBitmap(rbm1);
                    Toast.makeText(getApplicationContext(), "Image1 has to be Scaled", Toast.LENGTH_SHORT).show();

                    if(rbm1.sameAs(bmpimg2)){
                        Toast.makeText(getApplicationContext(), "Same", Toast.LENGTH_LONG).show();
                    }else{
                        Toast.makeText(getApplicationContext(), "Not Same", Toast.LENGTH_LONG).show();
                    }
            }

            if(bm1Res<bm2Res)
            {
                    Bitmap rbm2 = Bitmap.createScaledBitmap(bmpimg2, bmpimg1.getWidth(), bmpimg1.getHeight(), true);
                    ImageView imageView2 = (ImageView) findViewById(R.id.image2);
                    imageView2.setImageBitmap(rbm2);
                    Toast.makeText(getApplicationContext(), "Image2 has to be Scaled", Toast.LENGTH_SHORT).show();

                    if(bmpimg1.sameAs(rbm2)) {
                        Toast.makeText(getApplicationContext(), "Same", Toast.LENGTH_LONG).show();
                    }else{
                        Toast.makeText(getApplicationContext(), "Not Same", Toast.LENGTH_LONG).show();
                    }
            }

更新答案

为了回答您评论中的问题,有多种方法 - 这取决于您实际想要实现的目标......例如,您是否需要检测相对于彼此旋转的图像,或者模糊、平滑或篡改。有些方法是...

感知散列 - 您为所有图像创建散列并计算图像之间的距离。请参阅 here 以及关于 pHash 的评论。

平均颜色 - 您计算图像的平均(或平均)颜色并比较平均值 - 这种方法非常简单。

RMSE 或类似的 - 您计算所有像素的均方根误差并寻找低值以指示图像相似。使用 ImageMagick 可以轻松完成此方法和上述所有方法。查看并投票支持 Kurt (@KurtPfeifle) 出色而详尽的回答

特征 - 您在图像中找到形状和特征并进行比较 - 尝试谷歌搜索 "SIFT".

原答案

不是你代码的问题,是信息丢失的根本问题。如果将图像缩小到较小的尺寸,通常会丢失信息,因为较小的图像不能包含与较大图像相同的信息量。有很多事情可能会发生...

掉色

假设您有一张可爱的 1000x1000 大图片,具有平滑的渐变和相应的数百万种颜色,如下所示:

如果您现在将它的大小调整为 32x32 的图像,它现在最多只能包含 1,024 种颜色,因此当您再次调整它的大小时,您可能会得到这样的结果:

现在您可以看到出现了条带 - 颜色聚集在一起形成较小图像可以容纳的较少数量的颜色。

格式

当您调整图像大小时,执行此操作的程序可能会从每像素 24 位的真彩色图像变为只有 256 种或更少颜色的调色图像。图像可能看起来相同,但不一定完全相同。

同样与格式有关,您可以调整图像大小并使用不同的图像格式,该格式不能包含原始图像的所有特征,之后再次调整大小时它们将丢失。例如,您的原始图像可能是具有透明度的 PNG,您可能已将其缩小为不能包含透明度的 JPEG,然后再重新调整为 PNG,并且它会丢失。

Resolution/Detail

如果您的图像中有一些清晰的文字或细节,它们可能会丢失。假设你从这个开始:

然后缩小尺寸然后再备份,你可能会得到这个,因为较小的图像无法容纳细节。同样,这意味着您的比较将无法发现它们是同一张图片。

同样使用简单的线条..

缩小并重新放大