2010. december 22., szerda

How to compare two images pixel by pixel


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.

Nincsenek megjegyzések:

Megjegyzés küldése