compare two images in android
1. Check that the height matches, if not return false. Then, check if the width matches, and if not, return false. Then check each pixel until you find one that doesn't match. When you do, return false. If every pixel matches, return true.
Pseudocode:
bool imagesAreEqual(Image i1, Image i2)
{
if (i1.getHeight() != i2.getHeight()) return false;
if (i1.getWidth() != i2.getWidth()) return false;
for (int y = 0; y < i1.getHeight(); ++y)
for (int x = 0; x < i1.getWidth(); ++x)
if (i1.getPixel(x, y) != i2.getPixel(x, y)) return false;
return true;
}
in reality, you probably want to treat the image as a two dimensional array if you can, and just compare bytes. I don't know the Android image API, but getPixel might be slow.
2. maybe you convert the images in to byte64 Strings and then compare them.
3.**OpenCV lib for Android :
have to functions for images compression
**a. Core.absdiff()
b. Core.compare()
for more details see comparing two images
Android compare imageView with image
Thanks Morrison, that was it.
First
final ImageView test = (ImageView) findViewById(R.id.imageview1);
final Bitmap bmap = ((BitmapDrawable)test.getDrawable()).getBitmap();
Drawable myDrawable = getResources().getDrawable(R.drawable.red);
final Bitmap myLogo = ((BitmapDrawable) myDrawable).getBitmap();
Next
if(bmap.sameAs(myLogo))
{
do sthng
}
best way to compare images for similarity in android
First off, let's correct you. Neither your OpenCV snippet not Android can directly compare if two images are "similar". They can compare if they are exactly the same. That's not the same thing. You'd have to decide if its good enough.
Secondly, OpenCV is overkill for this. If the two images are Bitmaps in memory, just loop over the byte arrays of the two files. If they're on disk, just compare the byte by byte data of the two files.
You said you "got the paths of all images, then converted to Bitmap". Yeah, that would take a ton of memory. Instead, if you want to compare all the files, do this:
val map = mutableMapOf()
fileNames.each {
val hash = hash_file(it)
if (map.contains(hash)) {
//In this case, the two file stored in it and map[hash] are the same
}
else {
map[hash] = it
}
}
Here hash_file is any well known hash function. MD5 would work fine.
Now if you actually want similarity- good luck, you're going to need to learn a lot of AI and machine learning to determine that. Or find someone who already has a model for an appropriate training set.
android compare 2 images and highlight difference
With the help of digital color meter I detected there is very slight difference between colors of visually looking similar images quite similar what @taarraas also suggested. so I took a threshold value and solved it like this.
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);
}
Image Comparison in Android.
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:
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:
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:
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.
Likewise with simple lines..
and downsized and re-upsized
Related Topics
Very Large Soap Response - Android- Out of Memory Error
How to Disable Home Button in Android
Noclassdeffounderror at Google Play Services V2 Library
Android Opengl Es Transparent Background
Error Java.Lang.Runtimeexception: Stub! in Android with Fitnesse Testing
Android Youtubeplayer with Unauthorized Overlay on Top of Player
Android Internet Connectivity Check Problem
How to Hide a Folder in Sdcard in Android
Error Non-Default Constructors in Fragments
How to Handle Asynctask's in Actionbaractivity Fragments When Viewpager Is Used
Android: How to Maximize Preferencefragment Width (Or Get Rid of Margin)
How to Add Crosswalk Webview in My Own Android Library Module
How to Shutdown an Android Mobile Programmatically
Can't Update Android Studio - Only Download
How to Use Dialog Fragment? (Showdialog Deprecated) Android