Search code examples
imageimage-processingimage-comparison

Image Comparison in Android.


I'm Android learner. I was trying Image Comparison. It showed the images are not same for the same image of different size so I rescaled the image using createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter). Even after rescaling, when I compared the result I got was both images are different. Please help me out.

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

Solution

  • Updated Answer

    In order to answer the question in your comment, there are various approaches - it depends what you are actually trying to achieve... do you need to detect images that have been rotated relative to each other for example, or blurred, or smoothed, or tampered with. Some methods are...

    Perceptual Hashing - you create a hash for all your images and calculate the distance between images. See here and also the comment about pHash.

    Mean Colour - you calculate the mean (or average) colour of your images and compare the means - this method is quite simple.

    RMSE or similar - you calculate the Root Mean Squre Error for all pixels and look for a low value to indicate images are similar. This method and all the ones above are easily done with ImageMagick. See, and vote for, Kurt's (@KurtPfeifle) excellent, thorough answer here.

    Features - you find shapes and features in your image and compare those - try Googling "SIFT".

    Original Answer

    It's not a problem of your code, it is a fundamental issue of information loss. If you resize an image down to a smaller size, in general you will lose information since the smaller image cannot contain the same amount of information as a larger one. There are many things that could be going on...

    Colour Loss

    Imagine you have a lovely big 1000x1000 image with a smooth gradient and correspondingly millions of colours like this:

    enter image description here

    If you now resize it down to an image of 32x32, it can now only contain 1,024 colours as a maximum, so when you resize it up again you might get something like this:

    enter image description here

    And now you can see that banding has happened - where the colours have clumped together into the smaller number of colours that the smaller image can hold.

    Format

    When you resize an image, the program that does it may change from a true-colour 24 bits per pixel image to a palettised image with just 256, or fewer, colours. The image may look the same, but it won't necessarily compare identically.

    Also related to format, you may resize an image and usea different image format that cannot contain all the features of the original and they will be lost when you resize up again afterwards. For example, your original image may be a PNG with transparency, and you may have resized it down to a JPEG which cannot contain transparency, and then resize back up to a PNG and it will be lost.

    Resolution/Detail

    If you have some sharp text, or details in your image, they may be lost. Say you start with this:

    enter image description here

    and resize down and then back up again, you may get this because the smaller image cannot hold the details. Again, this will mean that your comparison will fail to spot that they are the same image.

    enter image description here

    Likewise with simple lines..

    enter image description here

    and downsized and re-upsized

    enter image description here