Thursday, October 28, 2010

Comparing two Images

Few days back I was looking to compare two image and find difference between them in WPF. After searching and reading few articles I realized that comparing two image and find difference is much easier using methods of Graphics Class (i.e. using GDI+).  So I decide to compare and find difference between two images using GDI+ and then convert into a BitmapImage. For faster comparing we have to use pointer and write code in unsafe block. As pointer and unsafe block are not supported in VB.NET so comparing code has to be in C# or C++.

CompareImage1

CompareImage2

Code

public static Bitmap BitmapDifference(Bitmap first, Bitmap second)
{
BitmapData data1 = first.LockBits(new Rectangle(0, 0, first.Width, first.Height), ImageLockMode.ReadWrite, first.PixelFormat);
BitmapData data2 = second.LockBits(new Rectangle(0, 0, second.Width, second.Height), ImageLockMode.ReadWrite, second.PixelFormat);
Bitmap bmpresult = new Bitmap(first.Width, first.Height);

BitmapData data3 = bmpresult.LockBits(new Rectangle(0, 0, bmpresult.Width, bmpresult.Height), ImageLockMode.ReadWrite, first.PixelFormat);

unsafe
{
int remain1 = data1.Stride - data1.Width * 3;
int remain2 = data2.Stride - data2.Width * 3;
int remain3 = data3.Stride - data3.Width * 3;

byte* ptr1 = (byte*)data1.Scan0;
byte* ptr2 = (byte*)data2.Scan0;
byte* ptr3 = (byte*)data3.Scan0;

for (int i = 0; i < first.Height; i++)
{
for (int j = 0; j < first.Width * 3; j++)
{
byte ac = (byte)(Math.Abs(ptr1[0] - ptr2[0]));
if (ac < 15)
{
//Change Pixel Color to Black for all the pixel whose value is
ptr3[0] = 0;
}
else
{
ptr3[0] = ac;
}
ptr1++;
ptr2++;
ptr3++;
}
ptr1 += remain1;
ptr2 += remain2;
ptr3 += remain3;
}
}
first.UnlockBits(data1);
second.UnlockBits(data2);
bmpresult.UnlockBits(data3);

bmpresult.MakeTransparent(Color.Black);
return bmpresult;
}
Above function will return the difference between two images using following code 

public void GetDifference()
{
Bitmap bmp1 = new Bitmap(@"C:\1.jpg");
Bitmap bmp2 = new Bitmap(@"C:\2.jpg");
Bitmap result = BitmapDifference(bmp1, bmp2);
result.Save(@"C:\new.jpg");
}