. Net to compare whether the two images are the same

Source: Internet
Author: User

In. net, GDI + is very convenient for image processing, but does not directly provide a class or method for image comparison. The purpose of this article is to explore how to compare images.

The first thing to note is that the two images to be compared must have the same format, and preferably the uncompressed image format. Otherwise, we cannot make a full comparison of the same sex, and we can only make an approximate judgment. For example, if the differences between different color components are 5%, we think they are the same.

Google it before you do it yourself and find the following two typical articles:Article:

(1)Http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/msg/4c8beaa229c2cbd6

In this article, we use the image. getpixel method to obtain the color of each pixel and combine each vertex into a hash value. KeyCodeSection:

[Clscompliant (false)]
Public static uint getbitmaphashvalue (
Bitmap image)
{
Uint result = 0 xffffffff;

 

For (INT x = 0; x <image. width; X ++)
For (INT y = 0; y <image. height; y ++)
Result =
Bitmaphasher. crctable [
(Result ^ image. getpixel (x, y). toargb () & 0xff] ^
(Result> 8 );

Return result ^ 0 xffffffff;
}

 

 

 

 

(2)Http://topic.csdn.net/u/20080808/09/c92a057e-ebd0-438c-bc1d-64d0a78127f7.html

This post on the csdn forum has many ideas for image comparison, such:

(A) memcmp is used directly, and the data within 10 MB cannot exceed 1 millisecond.

Of course, you cannot use getpix. getpix is very slow. You should retrieve the memory block for comparison,
Image compression can subtract the first and second images and then compress them.AlgorithmResult of compression Subtraction
On the other side, the result is a new image.
(B) divide the screen into several fixed blocks, numbers them separately, and compares them in blocks. Each time, only the changed blocks are transmitted.
(C) Please refer to his VNC open-source project.
They are usually installed with hooks to monitor the changes in the screen area, and then compress the image area that transmits the changes.
The method for determining image changes is too inefficient and rarely used.
(D) Save the previous image. After capturing a new image, compare the block in the memory with memcmp. If there are differences, send the block and assemble it on the client.

Since this article only discusses image comparison, the installation system hooks in all (c) are not considered. Other points are simply compared by getpixel in pixels, or get the memory block of the image and compare whether the memory block is consistent.

1. Use getpixel to get the pixels and compare them one by one:

/// <Summary>
/// Compare the two images
/// </Summary>
/// <Param name = "bitmap1"> image 1 </param>
/// <Param name = "bitmap2"> Image 2 </param>
/// <Returns> If the two images are the same, 0 is returned. If image 1 is smaller than Image 2, a value smaller than 0 is returned. If image 1 is greater than Image 2, returns a value greater than 0. </Returns>
Public static int bitmapcompare (Bitmap bitmap1, bitmap bitmap2)
{
Int result = 0; // assume the two images are the same
If (bitmap1 = NULL | bitmap2 = NULL)
Return-1;
If (bitmap1.width = bitmap2.width & bitmap1.height = bitmap2.height)
{
For (INT I = 0; I <bitmap1.width; I ++)
{
For (Int J = 0; j <bitmap1.height; j ++)
{
Color color1 = bitmap1.getpixel (I, j );
Color color2 = bitmap2.getpixel (I, j );
If (color1! = Color2)
{
Result = color1.toargb ()-color2.toargb ();
Break;
}
}
If (result! = 0)
Break;
}
}
Else if (bitmap1.width! = Bitmap2.width)
{
Result = bitmap1.width-bitmap2.width;
}
Else if (bitmap1.height! = Bitmap2.height)
{
Result = bitmap1.height-bitmap2.height;
}
Return result;
}

 

2. Obtain the image data memory block and compare whether the memory block is consistent:

Use bitmap.LockbitsThe bitmapdata method can be used to obtain bitmapdata. bitmapdata. scan0 points to the base address of the bitmap data part. Bitmapdata. stride provides the number of bytes occupied by each row in the image. Pay attention to bitmapdata. stride is not equal to bitmapdata. width for the following reasons: (1) bitmapdata. width indicates the number of pixels in each row. The number of bytes occupied by each pixel is related to pixelformat, it can be 1, 4, 8, 16, 24, 32, 48, 64, and so on. (2) The system alignment the image data row in the memory, each row occupies a multiple of 4 and is always greater than or equal to width * bitsperpixel/8. The marshal. COPY method copies memory blocks to byte arrays.

the code for getting the image data memory block is as follows:

bitmapdata bmd1 = bitmap1.lockbits (New rectangle (0, 0, bitmap1.width, bitmap1.height), imagelockmode. readonly, bitmap1.pixelformat); // obtain the image data object
int bytes = bmd1.stride * bitmap1.height; // the image data size
byte [] buff1 = new byte [bytes]; // The byte array for storing image data
marshal. copy (bmd1.scan0, buff1, 0, Marshal. sizeof (typeof (byte) * bytes); // copy the image data block
// perform the operation on the image data block here
bitmap1.unlockbits (bmd1 ); // unlock the image data block

The following methods are used to compare memory blocks:

(1) c API function memcmp, Which is prototype:

Int memcmp (const void *Buf1, Const void *Buf2, Size_tCount);

Pinvoke reference method:

[Dllimport ("msvcrt. dll")]
Private Static extern intptr memcmp (byte [] B1, byte [] B2, intptr count );

(2) read the bytes in the memory using the marshal. readbyte method, and then compare them by byte.

Bitmapdata bmd1 = bitmap1.lockbits (New rectangle (0, 0, bitmap1.width, bitmap1.height), imagelockmode. readonly, bitmap1.pixelformat );
Intptr start1 = bmd1.scan0;
Int sizeofbyte = marshal. sizeof (typeof (byte ));
For (INT I = 0; I <sizeofbyte * bmd1.stride * bitmap1.height; I ++)
{
Byte b1 = marshal. readbyte (start1, I );

// Perform operations on the byte here. You can also use marshal. writebyte to modify the byte content.
}
Bitmap1.unlockbits (bmd1 );

(3) Comparison of byte Arrays Using custom functions:

Public static int memorycompare2 (byte [] B1, byte [] B2)
{
Int result = 0;
If (b1.length! = B2.length)
Result = b1.length-b2.length;
Else
{
For (INT I = 0; I <b1.length; I ++)
{
If (b1 [I]! = B2 [I])
{
Result = (INT) (b1 [I]-B2 [I]);
Break;
}
}
}
Return result;
}

 

3. Comparison of efficiency of various image comparison methods

I wrote a short test code to compare the efficiency of the above four image comparison methods. The picture is a 24-bit 1024x768 pixel bitmap. The results are shown in the following table:

Unit: milliseconds

Image Comparison Method First time Second Third time First time Second Third time Average time Remarks
Bitmap. getpixel 4466 4296 4878 4416 4530 4584 4528.3 Each time you compare a pixel, the memory usage is low, and the time consumed is the longest
Memcmp 31 30 40 70 41 31 40.5 Compare the memory data of all images at a time. The memory usage is high and the time consumed is shortest;
If the image memory data is compared in multiple parts, the memory usage can be reduced, but the processing time will be increased.
Marshal. readbyte 2103 1943 2103 2043 2068 2083 2057.2 One byte is compared each time, and the memory usage is the lowest, which takes a long time.
Comparison of custom byte Arrays 60 60 70 110 95 67 77 Compare the memory data of all images at a time. The memory usage is high and the time consumed is short;
If the image memory data is compared in multiple parts, the memory usage can be reduced, but the processing time will be increased.

 

4.Source codeDownload

Http://files.cnblogs.com/xrwang/ImageCompare/ImageCompare.rar

From: http://www.cnblogs.com/xrwang/articles/1276826.html

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.