【问题标题】:Image Comparison in Android.Android中的图像比较。
【发布时间】:2015-10-27 17:57:19
【问题描述】:

我是 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();
                    }
            }

【问题讨论】:

    标签: image image-processing image-comparison


    【解决方案1】:

    更新答案

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

    Perceptual Hashing - 您为所有图像创建一个哈希并计算图像之间的距离。请参阅here 以及关于pHash 的评论。

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

    RMSE 或类似 - 您计算所有像素的均方根误差并寻找一个低值来表示图像相似。这个方法和上面所有的方法都可以用 ImageMagick 轻松完成。请参阅并投票支持 Kurt (@KurtPfeifle) 出色、全面的回答 here

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

    原答案

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

    色彩损失

    想象一下,您有一个可爱的 1000x1000 大图像,具有平滑的渐变和相应的数百万种颜色,如下所示:

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

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

    格式

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

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

    分辨率/细节

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

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

    简单的线条也是如此..

    缩小规模和重新扩大规模

    【讨论】:

    • @Mark Setchell - 感谢您的回复。那我怎么能比较两个图像。推荐一些比较方法。我看到了opencv,但我不明白如何实现。我将不胜感激任何帮助。再次感谢您。
    • @Mark Setchell - 感谢您的回复。那我怎么能比较两个图像。推荐一些比较方法。我看到了opencv,但我不明白如何实现。我将不胜感激任何帮助。再次感谢您
    • @Mark Setchell - 谢谢
    猜你喜欢
    • 2023-03-11
    • 2011-09-01
    • 2013-01-29
    • 1970-01-01
    • 2012-04-04
    • 2016-09-19
    • 1970-01-01
    • 2023-03-07
    相关资源
    最近更新 更多