Mirror

How to compare two images pixel by pixel (Views: 101)


Problem/Question/Abstract:

How can I compare an image pixel by pixel. The images have the same size. But that is accepted that the images have a fault tolerance up 10%.

Answer:

Solve 1:

{ ... }
for x := 0 to image1.width - 1 do
  for y := 0 to image1.height - 1 do
    if image1.picture.bitmap.canvas.pixels[x, y] <>
      image2.picture.bitmap.canvas.pixels[x, y] then
      inc(different);

if different > (image1.width * image1.height / 10) then
  picturedifferent;


Solve 2:

A faster approach:

{ ... }
var
  b1, b2: TBitmap;
  c1, c2: PByte;
  x, y, i, different: integer;
begin
  b1 := Image1.Picture.Bitmap;
  b2 := Image2.Picture.Bitmap;
  assert(b1.PixelFormat = b2.PixelFormat); {they have to be equal}
  different := 0;
  for y := 0 to b1.Height - 1 do
  begin
    c1 := b1.Scanline[y];
    c2 := b2.Scanline[y];
    for x := 0 to b1.Width - 1 do
      for i := 0 to BytesPerPixel - 1 do {1, to 4, dep. on pixelformat}
      begin
        inc(different, integer(c1^ <> c2^));
        inc(c1);
        inc(c2);
      end;
  end;
end;

Using an Int for "different" means your pictures can be at most 715827882 pixels large, or 26754 x 26754, which should be enough for most uses. Depending on how you want to count "equal" you could enforce 32bits per pixel and use PLongWord instead, ditching the BytesPerPixel loop.

<< Back to main page