Percentage difference between images: Difference between revisions

"Ada" section: Correct reference to "Left.G" to "Right.G".
(→‎{{header|C#}}: GetPixel is an expensive call, optimized to minimize calls (Code is now 2.8x faster by BenchmarkDotNet test). Also optimized to remove repeated floating point rounding errors. .Net's Math.Abs is optimized, repeated calls can be left.)
("Ada" section: Correct reference to "Left.G" to "Right.G".)
 
(13 intermediate revisions by 10 users not shown)
Line 20:
 
=={{header|Ada}}==
<langsyntaxhighlight lang="ada">type Count is mod 2**64;</langsyntaxhighlight>
[[wp:Distance|1-norm distance]] in the luminance space:
<langsyntaxhighlight lang="ada">function "-" (Left, Right : Luminance) return Count is
begin
if Left > Right then
Line 29:
return Count (Right) - Count (Left);
end if;
end "-";</langsyntaxhighlight>
1-norm distance in the color space multiplied to 3:
<langsyntaxhighlight lang="ada">function "-" (Left, Right : Pixel) return Count is
begin
return (Left.R - Right.R) + (Left.G - LeftRight.G) + (Left.B - Right.B);
end "-";</langsyntaxhighlight>
Mean of 1-norm distances. Constraint_Error is propagated when images have different size.
<langsyntaxhighlight lang="ada">function Diff (Left, Right : Image) return Float is
Offs_I : constant Integer := Right'First (1) - Left'First (1);
Offs_J : constant Integer := Right'First (2) - Left'First (2);
Line 50:
end loop;
return Float (Sum) / (3.0 * Float (Left'Length (1) * Left'Length (2)));
end Diff;</langsyntaxhighlight>
Example of use:
<langsyntaxhighlight lang="ada"> F1, F2 : File_Type;
begin
Open (F1, In_File, "city.ppm");
Line 58:
Ada.Text_IO.Put_Line ("Diff" & Float'Image (Diff (Get_PPM (F1), Get_PPM (F2))));
Close (F1);
Close (F2);</langsyntaxhighlight>
 
=={{header|AutoHotkey}}==
{{works with | AutoHotkey_L}}
uses [http://www.autohotkey.com/forum/topic32238.html gdip.ahk]
<langsyntaxhighlight AutoHotkeylang="autohotkey">startup()
dibSection := getPixels("lenna100.jpg")
dibSection2 := getPixels("lenna50.jpg") ; ("File-Lenna100.jpg")
Line 147 ⟶ 148:
}
#Include Gdip.ahk ; Thanks to tic (Tariq Porter) for his GDI+ Library
</syntaxhighlight>
</lang>
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
I would have preferred to calculate the RMS difference but it would be inconsistent with other results.
<langsyntaxhighlight lang="bbcbasic"> hbm1% = FNloadimage("C:lenna50.jpg")
hbm2% = FNloadimage("C:lenna100.jpg")
Line 199 ⟶ 200:
SYS !(!pic%+12), pic%, ^hbm% : REM. IPicture::get_Handle
SYS "FreeLibrary", ole%
= hbm%</langsyntaxhighlight>
'''Output:'''
<pre>
Line 209 ⟶ 210:
The <tt>read_image</tt> function is from [[Read image file through a pipe|here]].
 
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <math.h>
Line 253 ⟶ 254:
free_img(im1);
free_img(im2);
}</langsyntaxhighlight>
 
The output on Lenna is:
Line 260 ⟶ 261:
1.625587
</pre>
 
=={{header|C sharp|C#}}==
 
<syntaxhighlight lang="csharp">using System;
using System.Drawing;
 
class Program
{
static void Main()
{
Bitmap img1 = new Bitmap("Lenna50.jpg");
Bitmap img2 = new Bitmap("Lenna100.jpg");
 
if (img1.Size != img2.Size)
{
Console.Error.WriteLine("Images are of different sizes");
return;
}
 
float diff = 0;
 
for (int y = 0; y < img1.Height; y++)
{
for (int x = 0; x < img1.Width; x++)
{
Color pixel1 = img1.GetPixel(x, y);
Color pixel2 = img2.GetPixel(x, y);
 
diff += Math.Abs(pixel1.R - pixel2.R);
diff += Math.Abs(pixel1.G - pixel2.G);
diff += Math.Abs(pixel1.B - pixel2.B);
}
}
 
Console.WriteLine("diff: {0} %", 100 * (diff / 255) / (img1.Width * img1.Height * 3));
}
}</syntaxhighlight>
 
=={{header|C++}}==
 
based upon C version, using Qt 4.4
<langsyntaxhighlight Cpplang="cpp">#include <QImage>
#include <cstdlib>
#include <QColor>
Line 306 ⟶ 344:
(totaldiff * 100) / (w * h * 3) << " % !\n" ;
return 0 ;
}</langsyntaxhighlight>
 
output on pictures given;
Line 312 ⟶ 350:
The difference of the two pictures is 1.62559 % !
</pre>
 
=={{header|C#}}==
 
<lang Csharp>using System;
using System.Drawing;
 
class Program
{
static void Main()
{
Bitmap img1 = new Bitmap("Lenna50.jpg");
Bitmap img2 = new Bitmap("Lenna100.jpg");
 
if (img1.Size != img2.Size)
{
Console.Error.WriteLine("Images are of different sizes");
return;
}
 
float diff = 0;
 
for (int y = 0; y < img1.Height; y++)
{
for (int x = 0; x < img1.Width; x++)
{
Color pixel1 = img1.GetPixel(x, y);
Color pixel2 = img2.GetPixel(x, y);
 
diff += Math.Abs(pixel1.R - pixel2.R);
diff += Math.Abs(pixel1.G - pixel2.G);
diff += Math.Abs(pixel1.B - pixel2.B);
}
}
 
Console.WriteLine("diff: {0} %", 100 * (diff / 255) / (img1.Width * img1.Height * 3));
}
}</lang>
 
=={{header|Common Lisp}}==
Line 354 ⟶ 355:
This is based upon the C version. Strangely enough, the percentage is 1.77% which is off by about a tenth of a percent.
 
<langsyntaxhighlight lang="lisp">(require 'cl-jpeg)
;;; the JPEG library uses simple-vectors to store data. this is insane!
(defun compare-images (file1 file2)
Line 367 ⟶ 368:
 
CL-USER> (* 100 (compare-images "Lenna50.jpg" "Lenna100.jpg"))
1.774856467652165d0</langsyntaxhighlight>
 
=={{header|D}}==
{{trans|Python}}
<langsyntaxhighlight lang="d">import std.stdio, std.exception, std.range, std.math, bitmap;
 
void main() {
Line 387 ⟶ 388:
writeln("Difference (percentage): ",
(dif / 255.0 * 100) / nData);
}</langsyntaxhighlight>
{{out}}
<pre>Difference (percentage): 1.62559</pre>
Line 395 ⟶ 396:
By dividing only at the end, we work with integers only as the sum and avoid floating-point error from adding small numbers (per-pixel difference) to large ones (sum of differences).
 
<langsyntaxhighlight lang="e">def imageDifference(a, b) {
require(a.width() == b.width())
require(a.height() == b.height())
Line 423 ⟶ 424:
def d := imageDifference(a, b)
println(`${d * 100}% different.`)
}</langsyntaxhighlight>
 
The result on the provided images is 1.6255930981604882%.
 
=={{header|F_Sharp|F#}}==
<langsyntaxhighlight lang="fsharp">
//Percentage difference between 2 images. Nigel Galloway April 18th., 2018
let img50 = new System.Drawing.Bitmap("Lenna50.jpg")
let img100 = new System.Drawing.Bitmap("Lenna100.jpg")
let diff=Seq.cast<System.Drawing.Color*System.Drawing.Color>(Array2D.init img50.Width img50.Height (fun n g->(img50.GetPixel(n,g),img100.GetPixel(n,g))))|>Seq.fold(fun i (e,l)->i+abs(int(e.R)-int(l.R))+abs(int(e.B)-int(l.B))+abs(int(e.G)-int(l.G))) 0
printfn "%f" ((float diff)*100.00/(float(img50.Height*img50.Width)*255.0*3.0))</langsyntaxhighlight>
{{out}}
<pre>
Line 440 ⟶ 441:
 
=={{header|Forth}}==
<langsyntaxhighlight lang="forth">: pixel-diff ( pixel1 pixel2 -- n )
over 255 and over 255 and - abs >r 8 rshift swap 8 rshift
over 255 and over 255 and - abs >r 8 rshift swap 8 rshift
Line 456 ⟶ 457:
 
: .bdiff ( bmp1 bmp2 -- )
cr bdiff 100e f* f. ." percent different" ;</langsyntaxhighlight>
 
=={{header|Fortran}}==
 
<langsyntaxhighlight lang="fortran">program ImageDifference
 
use RCImageBasic
Line 491 ⟶ 492:
call free_img(lenna2)
 
end program ImageDifference</langsyntaxhighlight>
 
This gives 1.6555154.
Line 497 ⟶ 498:
=={{header|Frink}}==
 
<langsyntaxhighlight lang="frink">
img1 = new image["file:Lenna50.jpg"]
img2 = new image["file:Lenna100.jpg"]
Line 515 ⟶ 516:
errors = sum / (w1 * h1 * 3)
println["Error is " + (errors->"percent")]
</syntaxhighlight>
</lang>
 
This gives an error of approximately 1.625593 percent.
Line 521 ⟶ 522:
=={{header|Go}}==
Using standard image library:
<langsyntaxhighlight lang="go">package main
 
import (
Line 587 ⟶ 588:
fmt.Printf("Image difference: %f%%\n",
float64(sum*100)/(float64(nPixels)*0xffff*3))
}</langsyntaxhighlight>
Output:
<pre>
Line 593 ⟶ 594:
</pre>
Using code from bitmap task:
<langsyntaxhighlight lang="go">package main
 
// Files required to build supporting package raster are found in:
Line 664 ⟶ 665:
fmt.Printf("Image difference: %f%%\n",
float64(sum)*100/(float64(b1c*b1r)*255*3))
}</langsyntaxhighlight>
Output:
<pre>
Line 674 ⟶ 675:
This implementation takes PPMs as input. It uses modules defined in [[Basic bitmap storage]] and [[Write ppm file]].
 
<langsyntaxhighlight lang="haskell">import Bitmap
import Bitmap.Netpbm
import Bitmap.RGB
Line 699 ⟶ 700:
toEnum (3 * 255 * length i1)
where (RGB (r1, g1, b1)) `minus` (RGB (r2, g2, b2)) =
abs (r1 - r2) + abs (g1 - g2) + abs (b1 - b2)</langsyntaxhighlight>
 
=={{header|Icon}} and {{header|Unicon}}==
Line 705 ⟶ 706:
The Icon and Unicon graphics facilities are under documented with respect to some features. Unicon can support reading and writing to a number of additional image formats. I'm not sure if this will run under Icon or not. Some minor reworking of the open would be the minimum requirement; however, Icon may not have read support for jpg files.
 
<langsyntaxhighlight Uniconlang="unicon">link printf # for main only
 
procedure main() # % difference between images
Line 738 ⟶ 739:
}
return L
end</langsyntaxhighlight>
 
Output:<pre>%difference of files "Lenna100.jpg" & "Lenna50.jpg" = 1.625587</pre>
 
=={{header|J}}==
<langsyntaxhighlight lang="j"> require 'media/image3'
'Lenna50.jpg' (+/@,@:|@:- % 2.55 * */@$@])&read_image 'Lenna100.jpg'
1.62559</langsyntaxhighlight>
 
 
 
=={{header|Java}}==
 
<langsyntaxhighlight lang="java">import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
Line 798 ⟶ 797:
return Math.abs(r1 - r2) + Math.abs(g1 - g2) + Math.abs(b1 - b2);
}
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
 
<langsyntaxhighlight lang="javascript">function getImageData(url, callback) {
var img = document.createElement('img');
var canvas = document.createElement('canvas');
Line 840 ⟶ 839:
compare('Lenna50.jpg', 'Lenna100.jpg', function (result) {
console.log(result);
});</langsyntaxhighlight>
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">using Images, FileIO, Printf
{{works with|Julia|0.6}}
 
<lang julia>using Images, FileIO
 
absdiff(a::RGB{T}, b::RGB{T}) where T = sum(abs(col(a) - col(b)) for col in (red, green, blue))
Line 861 ⟶ 858:
 
d = pctdiff(img50, img100)
@printf("Percentage difference: %.4f%%\n", d)</langsyntaxhighlight>
 
{{out}}
Line 868 ⟶ 865:
=={{header|Kotlin}}==
{{trans|Java}}
<langsyntaxhighlight lang="scala">// version 1.2.10
 
import java.awt.image.BufferedImage
Line 910 ⟶ 907:
val p = getDifferencePercent(img1, img2)
println("The percentage difference is ${"%.6f".format(p)}%")
}</langsyntaxhighlight>
 
{{out}}
Line 916 ⟶ 913:
The percentage difference is 1.625593%
</pre>
 
=={{header|Lua}}==
Using the Bitmap class from [[Bitmap/Bresenham%27s_line_algorithm#Lua|here]] and ImageMagick to preprocess jpg->ppm to simplify loading:
<syntaxhighlight lang="lua">Bitmap.loadPPM = function(self, filename)
local fp = io.open( filename, "rb" )
if fp == nil then return false end
local head, width, height, depth, tail = fp:read("*line", "*number", "*number", "*number", "*line")
self.width, self.height = width, height
self:alloc()
self:clear( {0,0,0} )
for y = 1, self.height do
for x = 1, self.width do
self.pixels[y][x] = { string.byte(fp:read(1)), string.byte(fp:read(1)), string.byte(fp:read(1)) }
end
end
fp:close()
return true
end
 
Bitmap.percentageDifference = function(self, other)
if self.width ~= other.width or self.height ~= other.height then return end
local dif, abs, spx, opx = 0, math.abs, self.pixels, other.pixels
for y = 1, self.height do
for x = 1, self.width do
local sp, op = spx[y][x], opx[y][x]
dif = dif + abs(sp[1]-op[1]) + abs(sp[2]-op[2]) + abs(sp[3]-op[3])
end
end
return dif/255/self.width/self.height/3*100
end
 
local bm50 = Bitmap(0,0)
bm50:loadPPM("Lenna50.ppm")
 
local bm100 = Bitmap(0,0)
bm100:loadPPM("Lenna100.ppm")
 
print("%diff:", bm100:percentageDifference(bm50))</syntaxhighlight>
{{out}}
<pre>%diff: 1.6255930981605</pre>
 
=={{header|Liberty BASIC}}==
LB uses here a DLL to allow loading the jpgs. I get the 'other' result if I use LB's native bmp load and convert the jpgs to bmp with the Gimp!
The GUI shows the 'difference image'. [http://www.diga.me.uk/right.gif SceenDisplay]
<syntaxhighlight lang="lb">
<lang lb>
now =time$( "seconds")
nomainwin
Line 1,002 ⟶ 1,039:
close #j
end
</syntaxhighlight>
</lang>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">img50 = ImageData@Import[NotebookDirectory[] <> "Lenna50.jpg"];
img100 = ImageData@Import[NotebookDirectory[] <> "Lenna100.jpg"];
diff = img50 - img100;
Print["Total Difference between both Lenas = ",
Total@Abs@Flatten@diff/Times @@ Dimensions@img50*100, "%"]</langsyntaxhighlight>
 
'''Output'''
Line 1,015 ⟶ 1,052:
 
=={{header|MATLAB}}==
<syntaxhighlight lang="matlab">
<lang MATLAB>
% Percentage difference between images
function p = PercentageDifferenceBetweenImages(im1,im2)
Line 1,026 ⟶ 1,063:
p = sum(d(:))./numel(im1)*100;
 
disp(['Percentage difference between images is: ', num2str(p), '%'])</langsyntaxhighlight>
 
'''Output'''
Line 1,032 ⟶ 1,069:
 
=={{header|MAXScript}}==
<langsyntaxhighlight lang="maxscript">fn diffImages =
(
local img1 = selectBitmap caption:"Select Image 1"
Line 1,050 ⟶ 1,087:
)
format "Diff: %\%\n" (totalDiff / ((img1.width * img1.height * 3) as float) * 100)
)</langsyntaxhighlight>
 
=={{header|Nim}}==
{{libheader|imageman}}
We use the procedure <code>loadImage</code> which sets default values for JPEG decoding parameters. With these parameters, the difference between the images is about 1.7747 %. Using the less convenient procedure <code>readImage</code> which works on an open file, it is possible to change the parameters in order to get the smaller difference of 1.6256 %.
<syntaxhighlight lang="nim">import strformat
import imageman
 
var img50, img100: Image[ColorRGBU]
try:
img50 = loadImage[ColorRGBU]("Lenna50.jpg")
img100 = loadImage[ColorRGBU]("Lenna100.jpg")
except IOError:
echo getCurrentExceptionMsg()
quit QuitFailure
 
let width = img50.width
let height = img50.height
if img100.width != width or img100.height != height:
quit "Images have different sizes.", QuitFailure
 
var sum = 0
for x in 0..<height:
for y in 0..<width:
let color1 = img50[x, y]
let color2 = img100[x, y]
for i in 0..2:
sum += abs(color1[i].int - color2[i].int)
 
echo &"Image difference: {sum * 100 / (width * height * 3 * 255):.4f} %"</syntaxhighlight>
 
{{out}}
<pre>Image difference: 1.7747 %</pre>
 
=={{header|OCaml}}==
{{libheader|glMLite}}
 
<langsyntaxhighlight lang="ocaml">#! /usr/bin/env ocaml
#directory "+glMLite/"
#load "jpeg_loader.cma"
Line 1,090 ⟶ 1,159:
let diff_percent = !sum /. float !num in
Printf.printf " diff: %f percent\n" diff_percent;
;;</langsyntaxhighlight>
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">use Image::Imlib2;
 
my $img1 = Image::Imlib2->load('Lenna50.jpg') || die;
Line 1,111 ⟶ 1,180:
}
 
printf "%% difference = %.4f\n", 100 * $sum / ($w * $h * 3 * 255);</langsyntaxhighlight>
{{out}}
<pre>% difference = 1.7747</pre>
 
Alternative solution:
<langsyntaxhighlight lang="perl">use Imager;
use List::AllUtils qw(sum pairwise);
 
Line 1,144 ⟶ 1,213:
}
 
printf "difference = %f%%\n", 100 * img_diff('Lenna50.jpg', 'Lenna100.jpg');</langsyntaxhighlight>
{{out}}
<pre>
difference = 1.625593%
</pre>
 
=={{header|Perl 6}}==
<lang perl6>#!/usr/bin/env perl6
 
use v6;
use GD::Raw;
 
# Reference:
# https://github.com/dagurval/perl6-gd-raw
 
my $fh1 = fopen('./Lenna50.jpg', "rb") or die;
my $img1 = gdImageCreateFromJpeg($fh1);
my $fh2 = fopen('./Lenna100.jpg', "rb") or die;
my $img2 = gdImageCreateFromJpeg($fh2);
 
my $img1X = gdImageSX($img1);
my $img1Y = gdImageSY($img1);
my $img2X = gdImageSX($img2);
my $img2Y = gdImageSY($img2);
 
($img1X == $img2X and $img1Y == $img2Y) or die "Image dimensions must match.";
 
my $diff = 0;
my ($px1, $px2);
loop (my $i = 0; $i < $img1X; $i++) {
loop (my $j = 0; $j < $img1Y; $j++) {
 
$px1 = gdImageGetPixel($img1, $i, $j);
$px2 = gdImageGetPixel($img2, $i, $j);
 
$diff += abs(gdImageRed($img1, $px1) - gdImageRed($img2, $px2));
$diff += abs(gdImageGreen($img1, $px1) - gdImageGreen($img2, $px2));
$diff += abs(gdImageBlue($img1, $px1) - gdImageBlue($img2, $px2));
}
}
 
say "%difference = ", $diff/($img1X*$img1Y*3*255)*100;
 
gdImageDestroy($img1);
gdImageDestroy($img2);
</lang>
{{out}}
<pre>
%difference = 1.625593098
</pre>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(notonline)-->
<lang Phix>-- demo\rosetta\Percentage_difference_between_images.exw
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Percentage_difference_between_images.exw</span>
include ppm.e
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (file i/o)</span>
 
<span style="color: #008080;">include</span> <span style="color: #000000;">ppm</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
function split_colour(integer c)
return sq_div(sq_and_bits(c, {#FF0000,#FF00,#FF}),
<span style="color: #008080;">function</span> <span style="color: #000000;">split_colour</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
{#010000,#0100,#01})
<span style="color: #008080;">return</span> <span style="color: #7060A8;">sq_div</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">#FF0000</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#FF00</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#FF</span><span style="color: #0000FF;">}),</span>
end function
<span style="color: #0000FF;">{</span><span style="color: #000000;">#010000</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#0100</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#01</span><span style="color: #0000FF;">})</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function percentage_diff(sequence img1, img2)
if length(img1)!=length(img2)
<span style="color: #008080;">function</span> <span style="color: #000000;">percentage_diff</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">img1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">img2</span><span style="color: #0000FF;">)</span>
or length(img1[1])!=length(img2[1]) then
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img1</span><span style="color: #0000FF;">)!=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img2</span><span style="color: #0000FF;">)</span>
return "sizes do not match"
<span style="color: #008080;">or</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])!=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span>
end if
<span style="color: #008080;">return</span> <span style="color: #008000;">"sizes do not match"</span>
atom diff = 0
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
for i=1 to length(img1) do
<span style="color: #004080;">atom</span> <span style="color: #000000;">diff</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
for j=1 to length(img1[i]) do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img1</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
integer {r1,g1,b1} = split_colour(img1[i,j]),
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">do</span>
{r2,g2,b2} = split_colour(img2[i,j])
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">r1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">g1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b1</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">split_colour</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]),</span>
diff += abs(r1-r2)+abs(g1-g2)+abs(b1-b2)
<span style="color: #0000FF;">{</span><span style="color: #000000;">r2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">g2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b2</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">split_colour</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span>
end for
<span style="color: #000000;">diff</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">r2</span><span style="color: #0000FF;">)+</span><span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">g1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">g2</span><span style="color: #0000FF;">)+</span><span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">b2</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
return 100*diff/(length(img1)*length(img1[1]))/3/255
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">100</span><span style="color: #0000FF;">*</span><span style="color: #000000;">diff</span><span style="color: #0000FF;">/(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img1</span><span style="color: #0000FF;">)*</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]))/</span><span style="color: #000000;">3</span><span style="color: #0000FF;">/</span><span style="color: #000000;">255</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
sequence img1 = read_ppm("Lenna50.ppm"),
img2 = read_ppm("Lenna100.ppm")
<span style="color: #004080;">sequence</span> <span style="color: #000000;">img1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">read_ppm</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Lenna50.ppm"</span><span style="color: #0000FF;">),</span>
?percentage_diff(img1,img2)</lang>
<span style="color: #000000;">img2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">read_ppm</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Lenna100.ppm"</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">percentage_diff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">img2</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,229 ⟶ 1,258:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(call "convert" "Lenna50.jpg" (tmp "Lenna50.ppm"))
(call "convert" "Lenna100.jpg" (tmp "Lenna100.ppm"))
 
Line 1,242 ⟶ 1,271:
255 ) )
(inc 'Total) ) ) )
(prinl "Difference is " (format (*/ Diff Total) 4) " percent") )</langsyntaxhighlight>
Output:
<pre>Difference is 1.6256 percent</pre>
Line 1,248 ⟶ 1,277:
=={{header|PureBasic}}==
This program downloads both jpg files, decodes them & saves them in 2D-arrays for simple comparison which part is comparable with the other languages.
<langsyntaxhighlight PureBasiclang="purebasic">#URL1="http://rosettacode.org/mw/images/3/3c/Lenna50.jpg"
#URL2="http://rosettacode.org/mw/images/b/b6/Lenna100.jpg"
Line 1,299 ⟶ 1,328:
Next x
MessageRequester("Result","Diff= "+StrD(100*totalDiff/(255*w*h*3),3)+" %")</langsyntaxhighlight>
 
=={{header|Python}}==
You must install the [https://pillow.readthedocs.io/ Python Imaging Library] to use this example. [https://pypi.org/project/Pillow/ Install with pip] : pip install Pillow
 
{{works with|python version 3.x}}
<langsyntaxhighlight lang="python">from PIL import Image
 
i1 = Image.open("image1.jpg")
Line 1,320 ⟶ 1,349:
 
ncomponents = i1.size[0] * i1.size[1] * 3
print ("Difference (percentage):", (dif / 255.0 * 100) / ncomponents)</langsyntaxhighlight>
 
{{works with|python version 2.x}}
<langsyntaxhighlight lang="python">from itertools import izip
import Image
 
Line 1,339 ⟶ 1,368:
 
ncomponents = i1.size[0] * i1.size[1] * 3
print "Difference (percentage):", (dif / 255.0 * 100) / ncomponents</langsyntaxhighlight>
 
=={{header|Racket}}==
Line 1,345 ⟶ 1,374:
Note: On OS X I get 1.6192% as the result. (soegaard)
 
<langsyntaxhighlight Racketlang="racket">#lang racket
(require racket/draw)
 
Line 1,366 ⟶ 1,395:
(define lenna100 (read-bitmap "lenna100.jpg"))
 
(percentage-difference lenna50 lenna100) ;-> 1.7749329408009846</langsyntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
 
Using [https://modules.raku.org/search/?q=GD%3A%3ARaw GD::Raw from the Raku ecosystem].
<syntaxhighlight lang="raku" line>use GD::Raw;
 
my $fh1 = fopen('./Lenna50.jpg', "rb") or die;
my $img1 = gdImageCreateFromJpeg($fh1);
my $fh2 = fopen('./Lenna100.jpg', "rb") or die;
my $img2 = gdImageCreateFromJpeg($fh2);
 
my $img1X = gdImageSX($img1);
my $img1Y = gdImageSY($img1);
my $img2X = gdImageSX($img2);
my $img2Y = gdImageSY($img2);
 
($img1X == $img2X and $img1Y == $img2Y) or die "Image dimensions must match.";
 
my $diff = 0;
my ($px1, $px2);
loop (my $i = 0; $i < $img1X; $i++) {
loop (my $j = 0; $j < $img1Y; $j++) {
 
$px1 = gdImageGetPixel($img1, $i, $j);
$px2 = gdImageGetPixel($img2, $i, $j);
 
$diff += abs(gdImageRed($img1, $px1) - gdImageRed($img2, $px2));
$diff += abs(gdImageGreen($img1, $px1) - gdImageGreen($img2, $px2));
$diff += abs(gdImageBlue($img1, $px1) - gdImageBlue($img2, $px2));
}
}
 
say "%difference = ", $diff/($img1X*$img1Y*3*255)*100;
 
gdImageDestroy($img1);
gdImageDestroy($img2);
</syntaxhighlight>
{{out}}
<pre>
%difference = 1.625593098
</pre>
 
=={{header|REBOL}}==
<langsyntaxhighlight REBOLlang="rebol">REBOL [
Title: "Percent Image Difference"
URL: http://rosettacode.org/wiki/Percentage_of_difference_between_2_images
Line 1,418 ⟶ 1,489:
button "b" #"b" [flip 'b]
button "difference" #"d" [flip 'diff]
]</langsyntaxhighlight>
 
Output:
Line 1,430 ⟶ 1,501:
=={{header|Ruby}}==
uses the <code>[[Raster graphics operations/Ruby|raster_graphics]]</code> library
<langsyntaxhighlight lang="ruby">require 'raster_graphics'
 
class RGBColour
Line 1,456 ⟶ 1,527:
lenna100 = Pixmap.open_from_jpeg('Lenna100.jpg')
 
puts "difference: %.5f%%" % (100.0 * (lenna50 - lenna100))</langsyntaxhighlight>
 
produces:
<pre>difference: 1.62559%</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">extern crate image;
 
use image::{GenericImageView, Rgba};
 
fn diff_rgba3(rgba1 : Rgba<u8>, rgba2 : Rgba<u8>) -> i32 {
(rgba1[0] as i32 - rgba2[0] as i32).abs()
+ (rgba1[1] as i32 - rgba2[1] as i32).abs()
+ (rgba1[2] as i32 - rgba2[2] as i32).abs()
}
 
fn main() {
let img1 = image::open("Lenna100.jpg").unwrap();
let img2 = image::open("Lenna50.jpg").unwrap();
let mut accum = 0;
let zipper = img1.pixels().zip(img2.pixels());
for (pixel1, pixel2) in zipper {
accum += diff_rgba3(pixel1.2, pixel2.2);
}
println!("Percent difference {}", accum as f64 * 100.0/ (255.0 * 3.0 * (img1.width() * img1.height()) as f64));
}</syntaxhighlight>
 
produces:
<pre>Percent difference 1.6260633281632966</pre>
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">require('Imager')
 
func img_diff(a, b) {
Line 1,499 ⟶ 1,595:
}
 
say 100*img_diff('Lenna50.jpg', 'Lenna100.jpg')</langsyntaxhighlight>
{{out}}
<pre>
Line 1,506 ⟶ 1,602:
 
=={{header|Swift}}==
<langsyntaxhighlight lang="swift">func pixelValues(fromCGImage imageRef: CGImage?) -> [UInt8]?
{
var width = 0
Line 1,561 ⟶ 1,657:
compareImages(image1: image1, image2: image2)
 
</syntaxhighlight>
</lang>
 
=={{header|Tcl}}==
{{libheader|Tk}}
This version uses the '''Img''' package, but only to provide a convenient JPEG loader; it's utterly unnecessary for the process of actually computing the difference.
<langsyntaxhighlight lang="tcl">package require Tk
 
proc imageDifference {img1 img2} {
Line 1,591 ⟶ 1,687:
image create photo lenna100 -file lenna100.jpg
puts "difference is [expr {[imageDifference lenna50 lenna100]*100.}]%"
exit ;# Need explicit exit here; don't want a GUI</langsyntaxhighlight>
It produces this output:
difference is 1.6255930981604882%
Line 1,598 ⟶ 1,694:
This implementation compares two BMP images.
 
<langsyntaxhighlight lang="vedit">Chdir("|(USER_MACRO)\Rosetta\data")
File_Open("Lenna50.bmp", BROWSE)
#10 = Buf_Num // #10 = buffer for 1st image
Line 1,627 ⟶ 1,723:
 
Buf_Switch(#10) Buf_Quit(OK)
Buf_Switch(#20) Buf_Quit(OK)</langsyntaxhighlight>
 
Output, when comparing the Lenna images that were converted to BMP:
Line 1,634 ⟶ 1,730:
Total bytes: 786432
Difference: 1.619%
</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|DOME}}
<syntaxhighlight lang="wren">import "graphics" for Canvas, Color, ImageData
import "dome" for Window
 
class PercentageDifference {
construct new(width, height, image1, image2) {
Window.title = "Perecentage difference between images"
Window.resize(width, height)
Canvas.resize(width, height)
_img1 = ImageData.loadFromFile(image1)
_img2 = ImageData.loadFromFile(image2)
// display images side by side
_img1.draw(0, 0)
_img2.draw(550, 0)
Canvas.print(image1, 200, 525, Color.white)
Canvas.print(image2, 750, 525, Color.white)
}
 
init() {
var dpc = (getDifferencePercent(_img1, _img2) * 1e5).round / 1e5
System.print("Percentage difference between images: %(dpc)\%")
}
 
getDifferencePercent(img1, img2) {
var width = img1.width
var height = img1.height
var width2 = img2.width
var height2 = img2.height
if (width != width2 || height != height2) {
var f = "(%(width), %(height)) vs. (%(width2), %(height2))"
Fiber.abort("Images must have the same dimensions: %(f)")
}
var diff = 0
for (y in 0...height) {
for (x in 0...width) {
diff = diff + pixelDiff(img1.pget(x, y), img2.pget(x, y))
}
}
var maxDiff = 3 * 255 * width * height
return 100 * diff / maxDiff
}
 
pixelDiff(c1, c2) { (c1.r - c2.r).abs + (c1.g - c2.g).abs + (c1.b - c2.b).abs }
 
update() {}
 
draw(alpha) {}
}
 
var Game = PercentageDifference.new(1100, 550, "Lenna50.jpg", "Lenna100.jpg")</syntaxhighlight>
 
{{out}}
<pre>
Percentage difference between images: 1.62607%
</pre>
 
=={{header|zkl}}==
Uses the PPM class from http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#zkl
<langsyntaxhighlight lang="zkl">fcn imageDiff(img1,img2){
if(img1.w!=img2.w or img1.h!=img2.h)
throw(Exception.ValueError("width/height of the images must match!"));
Line 1,644 ⟶ 1,798:
.reduce(fcn(totalDiff,[(a,b)]){ totalDiff + (a - b).abs() },0)
.toFloat()/img1.w/img1.h/3/255; // or: .toFloat()/img1.data.len()/255
}</langsyntaxhighlight>
Take the bytes in each image, zip them together [lazily], sum the differences between each byte and normalize.
<langsyntaxhighlight lang="zkl">fcn readJPG2PPM(fileName){
p:=System.popen("convert \"%s\" ppm:-".fmt(fileName),"r");
img:=PPM.readPPM(p);
p.close();
img
}</langsyntaxhighlight>
Use the convert utility from ImageMagick to convert a JPEG image to PPM.
<langsyntaxhighlight lang="zkl">imageDiff(readJPG2PPM("lenna50.jpg"),readJPG2PPM("lenna100.jpg")) :
"Image difference = %f%%".fmt(_*100).println();</langsyntaxhighlight>
Compute the diff between the two Lennas, format and print it. More conventionally, this would be written as
<langsyntaxhighlight lang="zkl">println("Image difference = %f%%".fmt(
imageDiff(readJPG2PPM("lenna50.jpg"),readJPG2PPM("lenna100.jpg")) * 100)
);</langsyntaxhighlight>
{{out}}
<pre>
6

edits