Percentage difference between images: Difference between revisions

"Ada" section: Correct reference to "Left.G" to "Right.G".
("Ada" section: Correct reference to "Left.G" to "Right.G".)
 
(38 intermediate revisions by 22 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 317 ⟶ 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 330 ⟶ 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 350 ⟶ 388:
writeln("Difference (percentage): ",
(dif / 255.0 * 100) / nData);
}</langsyntaxhighlight>
{{out}}
<pre>Difference (percentage): 1.62559</pre>
Line 358 ⟶ 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 386 ⟶ 424:
def d := imageDifference(a, b)
println(`${d * 100}% different.`)
}</langsyntaxhighlight>
 
The result on the provided images is 1.6255930981604882%.
 
=={{header|F_Sharp|F#}}==
<syntaxhighlight 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))</syntaxhighlight>
{{out}}
<pre>
1.774691
</pre>
 
=={{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 407 ⟶ 457:
 
: .bdiff ( bmp1 bmp2 -- )
cr bdiff 100e f* f. ." percent different" ;</langsyntaxhighlight>
 
=={{header|Fortran}}==
 
<langsyntaxhighlight lang="fortran">program ImageDifference
 
use RCImageBasic
Line 442 ⟶ 492:
call free_img(lenna2)
 
end program ImageDifference</langsyntaxhighlight>
 
This gives 1.6555154.
 
=={{header|Frink}}==
 
<syntaxhighlight lang="frink">
img1 = new image["file:Lenna50.jpg"]
img2 = new image["file:Lenna100.jpg"]
 
[w1, h1] = img1.getSize[]
[w2, h2] = img2.getSize[]
 
sum = 0
for x=0 to w1-1
for y=0 to h1-1
{
[r1,g1,b1] = img1.getPixel[x,y]
[r2,g2,b2] = img2.getPixel[x,y]
sum = sum + abs[r1-r2] + abs[g1-g2] + abs[b1-b2]
}
 
errors = sum / (w1 * h1 * 3)
println["Error is " + (errors->"percent")]
</syntaxhighlight>
 
This gives an error of approximately 1.625593 percent.
 
=={{header|Go}}==
Using standard image library:
<langsyntaxhighlight lang="go">package main
 
import (
Line 453 ⟶ 528:
"image/jpeg"
"os"
"log"
"image"
)
 
func loadJpeg(filename string) (image.Image, error) {
func main() {
f, err := os.Open("Lenna50.jpg"filename)
if err != nil {
fmt.Println(return nil, err)
return
}
defer f.Close()
 
i50, err := jpeg.Decode(f)
img, err := jpeg.Decode(f)
if err != nil {
fmt.Println(return nil, err)
return
}
 
if f, err = os.Open("Lenna100.jpg"); err != nil {
return img, nil
fmt.Println(err)
}
return
 
func diff(a, b uint32) int64 {
if a > b {
return int64(a - b)
}
deferreturn f.Closeint64(b - a)
}
i100, err := jpeg.Decode(f)
 
func main() {
i50, err := loadJpeg("Lenna50.jpg")
if err != nil {
fmtlog.PrintlnFatal(err)
return
}
 
i100, err := loadJpeg("Lenna100.jpg")
if err != nil {
log.Fatal(err)
}
 
if i50.ColorModel() != i100.ColorModel() {
fmtlog.PrintlnFatal("different color models")
return
}
 
b := i50.Bounds()
if !b.Eq(i100.Bounds()) {
fmtlog.PrintlnFatal("different image sizes")
return
}
 
var sum int64
for y := b.Min.Y; y < b.Max.Y; y++ {
Line 491 ⟶ 579:
r1, g1, b1, _ := i50.At(x, y).RGBA()
r2, g2, b2, _ := i100.At(x, y).RGBA()
ifsum += diff(r1 >, r2 {)
sum += int64diff(r1 -g1, r2g2)
}sum else+= {diff(b1, b2)
sum += int64(r2 - r1)
}
if g1 > g2 {
sum += int64(g1 - g2)
} else {
sum += int64(g2 - g1)
}
if b1 > b2 {
sum += int64(b1 - b2)
} else {
sum += int64(b2 - b1)
}
}
}
 
nPixels := (b.Max.X - b.Min.X) * (b.Max.Y - b.Min.Y)
fmt.Printf("Image difference: %f%%\n",
float64(sum*100)/(float64(nPixels)*0xffff*3))
}</langsyntaxhighlight>
Output:
<pre>
Line 517 ⟶ 594:
</pre>
Using code from bitmap task:
<langsyntaxhighlight lang="go">package main
 
// Files required to build supporting package raster are found in:
Line 588 ⟶ 665:
fmt.Printf("Image difference: %f%%\n",
float64(sum)*100/(float64(b1c*b1r)*255*3))
}</langsyntaxhighlight>
Output:
<pre>
Line 598 ⟶ 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 623 ⟶ 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 629 ⟶ 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 662 ⟶ 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 javaxjava.imageioio.ImageIOFile;
import java.io.IOException;
import javajavax.netimageio.URLImageIO;
 
public classenum ImgDiffPercent {
;
{
 
public static void main(String args[])
public static void main(String[] args) throws IOException {
{
// https://rosettacode.org/mw/images/3/3c/Lenna50.jpg
BufferedImage img1 = null;
// https://rosettacode.org/mw/images/b/b6/Lenna100.jpg
BufferedImage img2 = null;
BufferedImage img1 = ImageIO.read(new File("Lenna50.jpg"));
try {
URL url1 BufferedImage img2 = ImageIO.read(new URLFile("http://rosettacode.org/mw/images/3/3c/Lenna50Lenna100.jpg"));
 
URL url2 = new URL("http://rosettacode.org/mw/images/b/b6/Lenna100.jpg");
img1 double p = ImageIO.readgetDifferencePercent(url1img1, img2);
img2 = ImageIOSystem.readout.println(url2"diff percent: " + p);
} catch (IOException e) {
e.printStackTrace();
}
 
int width1 = img1.getWidth(null);
private static double getDifferencePercent(BufferedImage img1, BufferedImage img2) {
int width2 = img2.getWidth(null);
int height1width = img1.getHeightgetWidth(null);
int height2height = img2img1.getHeight(null);
if ((width1 != width2) ||int (height1width2 != height2img2.getWidth()) {;
int height2 = img2.getHeight();
System.err.println("Error: Images dimensions mismatch");
if (width != width2 || height != height2) {
System.exit(1);
throw new IllegalArgumentException(String.format("Images must have the same dimensions: (%d,%d) vs. (%d,%d)", width, height, width2, height2));
}
 
long diff = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
diff += pixelDiff(img1.getRGB(x, y), img2.getRGB(x, y));
}
}
long maxDiff = 3L * 255 * width * height;
 
return 100.0 * diff / maxDiff;
}
 
long diff = 0;
forprivate static int pixelDiff(int yrgb1, = 0; y < height1;int y++rgb2) {
for (int x = 0; x < width1; x++) {
int rgb1 = img1.getRGB(x, y);
int rgb2 = img2.getRGB(x, y);
int r1 = (rgb1 >> 16) & 0xff;
int g1 = (rgb1 >> 8) & 0xff;
int b1 = ( rgb1 ) & 0xff;
int r2 = (rgb2 >> 16) & 0xff;
int g2 = (rgb2 >> 8) & 0xff;
int b2 = ( rgb2 ) & 0xff;
diff +=return Math.abs(r1 - r2) + Math.abs(g1 - g2) + Math.abs(b1 - b2);
diff += Math.abs(g1 - g2);
diff += Math.abs(b1 - b2);
}
}
}</syntaxhighlight>
double n = width1 * height1 * 3;
 
double p = diff / n / 255.0;
=={{header|JavaScript}}==
System.out.println("diff percent: " + (p * 100.0));
 
}
<syntaxhighlight lang="javascript">function getImageData(url, callback) {
}</lang>
var img = document.createElement('img');
var canvas = document.createElement('canvas');
 
img.onload = function () {
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
callback(ctx.getImageData(0, 0, img.width, img.height));
};
 
img.src = url;
}
 
function compare(firstImage, secondImage, callback) {
getImageData(firstImage, function (img1) {
getImageData(secondImage, function (img2) {
if (img1.width !== img2.width || img1.height != img2.height) {
callback(NaN);
return;
}
 
var diff = 0;
for (var i = 0; i < img1.data.length / 4; i++) {
diff += Math.abs(img1.data[4 * i + 0] - img2.data[4 * i + 0]) / 255;
diff += Math.abs(img1.data[4 * i + 1] - img2.data[4 * i + 1]) / 255;
diff += Math.abs(img1.data[4 * i + 2] - img2.data[4 * i + 2]) / 255;
}
 
callback(100 * diff / (img1.width * img1.height * 3));
});
});
}
 
compare('Lenna50.jpg', 'Lenna100.jpg', function (result) {
console.log(result);
});</syntaxhighlight>
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">using Images, FileIO, Printf
 
absdiff(a::RGB{T}, b::RGB{T}) where T = sum(abs(col(a) - col(b)) for col in (red, green, blue))
function pctdiff(A::Matrix{Color{T}}, B::Matrix{Color{T}}) where T
size(A) != size(B) && throw(ArgumentError("images must be same-size"))
s = zero(T)
for (a, b) in zip(A, B)
s += absdiff(a, b)
end
return 100s / 3prod(size(A))
end
 
img50 = load("data/lenna50.jpg") |> Matrix{RGB{Float64}};
img100 = load("data/lenna100.jpg") |> Matrix{RGB{Float64}};
 
d = pctdiff(img50, img100)
@printf("Percentage difference: %.4f%%\n", d)</syntaxhighlight>
 
{{out}}
<pre>Percentage difference: 1.6247%</pre>
 
=={{header|Kotlin}}==
{{trans|Java}}
<syntaxhighlight lang="scala">// version 1.2.10
 
import java.awt.image.BufferedImage
import java.io.File
import javax.imageio.ImageIO
import kotlin.math.abs
 
fun getDifferencePercent(img1: BufferedImage, img2: BufferedImage): Double {
val width = img1.width
val height = img1.height
val width2 = img2.width
val height2 = img2.height
if (width != width2 || height != height2) {
val f = "(%d,%d) vs. (%d,%d)".format(width, height, width2, height2)
throw IllegalArgumentException("Images must have the same dimensions: $f")
}
var diff = 0L
for (y in 0 until height) {
for (x in 0 until width) {
diff += pixelDiff(img1.getRGB(x, y), img2.getRGB(x, y))
}
}
val maxDiff = 3L * 255 * width * height
return 100.0 * diff / maxDiff
}
 
fun pixelDiff(rgb1: Int, rgb2: Int): Int {
val r1 = (rgb1 shr 16) and 0xff
val g1 = (rgb1 shr 8) and 0xff
val b1 = rgb1 and 0xff
val r2 = (rgb2 shr 16) and 0xff
val g2 = (rgb2 shr 8) and 0xff
val b2 = rgb2 and 0xff
return abs(r1 - r2) + abs(g1 - g2) + abs(b1 - b2)
}
 
fun main(args: Array<String>) {
val img1 = ImageIO.read(File("Lenna50.jpg"))
val img2 = ImageIO.read(File("Lenna100.jpg"))
 
val p = getDifferencePercent(img1, img2)
println("The percentage difference is ${"%.6f".format(p)}%")
}</syntaxhighlight>
 
{{out}}
<pre>
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 809 ⟶ 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'''
<pre>Total Difference between both Lenas = 1.62559%</pre>
 
=={{header|MATLAB}}==
<syntaxhighlight lang="matlab">
% Percentage difference between images
function p = PercentageDifferenceBetweenImages(im1,im2)
if numel(im1)~=numel(im2),
error('Error: images have to be the same size');
end
 
d = abs(single(im1) - single(im2))./255;
p = sum(d(:))./numel(im1)*100;
 
disp(['Percentage difference between images is: ', num2str(p), '%'])</syntaxhighlight>
 
'''Output'''
<pre>Percentage difference between images is: 1.6256%</pre>
 
=={{header|MAXScript}}==
<langsyntaxhighlight lang="maxscript">fn diffImages =
(
local img1 = selectBitmap caption:"Select Image 1"
Line 840 ⟶ 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 880 ⟶ 1,159:
let diff_percent = !sum /. float !num in
Printf.printf " diff: %f percent\n" diff_percent;
;;</langsyntaxhighlight>
 
=={{header|Perl}}==
<syntaxhighlight lang="perl">use Image::Imlib2;
 
my $img1 = Image::Imlib2->load('Lenna50.jpg') || die;
my $img2 = Image::Imlib2->load('Lenna100.jpg') || die;
 
my $w = $img1->width;
my $h = $img1->height;
 
my $sum = 0;
 
for my $x (0..$w-1) {
for my $y (0..$h-1) {
my ($r1, $g1, $b1) = $img1->query_pixel($x, $y);
my ($r2, $g2, $b2) = $img2->query_pixel($x, $y);
$sum += abs($r1-$r2) + abs($g1-$g2) + abs($b1-$b2);
}
}
 
printf "%% difference = %.4f\n", 100 * $sum / ($w * $h * 3 * 255);</syntaxhighlight>
{{out}}
<pre>% difference = 1.7747</pre>
 
Alternative solution:
<syntaxhighlight lang="perl">use Imager;
use List::AllUtils qw(sum pairwise);
 
sub img_diff {
my ($file1, $file2) = @_;
 
my $img1 = Imager->new(file => $file1);
my $img2 = Imager->new(file => $file2);
 
my ($w1, $h1) = ($img1->getwidth, $img1->getheight);
my ($w2, $h2) = ($img2->getwidth, $img2->getheight);
 
if ($w1 != $w2 or $h1 != $h2) {
die "Can't compare images of different sizes";
}
 
my $sum = 0;
foreach my $y (0 .. $h1 - 1) {
foreach my $x (0 .. $w1 - 1) {
my @rgba1 = $img1->getpixel(x => $x, y => $y)->rgba;
my @rgba2 = $img2->getpixel(x => $x, y => $y)->rgba;
$sum += sum(pairwise { abs($a - $b) } @rgba1, @rgba2);
}
}
 
$sum / ($w1 * $h1 * 255 * 3);
}
 
printf "difference = %f%%\n", 100 * img_diff('Lenna50.jpg', 'Lenna100.jpg');</syntaxhighlight>
{{out}}
<pre>
difference = 1.625593%
</pre>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(notonline)-->
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Percentage_difference_between_images.exw</span>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<span style="color: #008080;">return</span> <span style="color: #008000;">"sizes do not match"</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">diff</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<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>
<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>
<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>
<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>
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<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>
<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>
<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>
1.625593098
</pre>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(call "convert" "Lenna50.jpg" (tmp "Lenna50.ppm"))
(call "convert" "Lenna100.jpg" (tmp "Lenna100.ppm"))
 
Line 896 ⟶ 1,271:
255 ) )
(inc 'Total) ) ) )
(prinl "Difference is " (format (*/ Diff Total) 4) " percent") )</langsyntaxhighlight>
Output:
<pre>Difference is 1.6256 percent</pre>
 
=={{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 952 ⟶ 1,328:
Next x
MessageRequester("Result","Diff= "+StrD(100*totalDiff/(255*w*h*3),3)+" %")</langsyntaxhighlight>
 
=={{header|Python}}==
You must install the [httphttps://wwwpillow.pythonwarereadthedocs.com/products/pilio/ Python Imaging Library] to use this example. [https://pypi.org/project/Pillow/ Install with pip] : pip install Pillow
 
{{works with|python version 3.x}}
<syntaxhighlight lang="python">from PIL import Image
 
i1 = Image.open("image1.jpg")
i2 = Image.open("image2.jpg")
assert i1.mode == i2.mode, "Different kinds of images."
assert i1.size == i2.size, "Different sizes."
 
pairs = zip(i1.getdata(), i2.getdata())
if len(i1.getbands()) == 1:
# for gray-scale jpegs
dif = sum(abs(p1-p2) for p1,p2 in pairs)
else:
dif = sum(abs(c1-c2) for p1,p2 in pairs for c1,c2 in zip(p1,p2))
 
ncomponents = i1.size[0] * i1.size[1] * 3
print ("Difference (percentage):", (dif / 255.0 * 100) / ncomponents)</syntaxhighlight>
 
{{works with|python version 2.x}}
<langsyntaxhighlight lang="python">from itertools import izip
import Image
 
Line 973 ⟶ 1,368:
 
ncomponents = i1.size[0] * i1.size[1] * 3
print "Difference (percentage):", (dif / 255.0 * 100) / ncomponents</langsyntaxhighlight>
 
=={{header|Racket}}==
Line 979 ⟶ 1,374:
Note: On OS X I get 1.6192% as the result. (soegaard)
 
<langsyntaxhighlight Racketlang="racket">#lang racket
(require racket/draw)
 
Line 1,000 ⟶ 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"
Author: oofoe
Date: 2009-12-31
URL: http://rosettacode.org/wiki/Percentage_of_difference_between_2_images
]
Line 1,054 ⟶ 1,489:
button "b" #"b" [flip 'b]
button "difference" #"d" [flip 'diff]
]</langsyntaxhighlight>
 
Output:
Line 1,066 ⟶ 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,092 ⟶ 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}}==
<syntaxhighlight lang="ruby">require('Imager')
 
func img_diff(a, b) {
 
func from_file(name) {
%s|Imager|.new(file => name)
}
 
func size(img) {
(img.getwidth, img.getheight)
}
 
func pixel_diff(p1, p2) {
[p1.rgba] »-« [p2.rgba] -> map { .abs }.sum
}
 
func read_pixel(img, x, y) {
img.getpixel(x => x, y => y)
}
 
var(img1, img2) = (from_file(a), from_file(b))
 
var(w1, h1) = size(img1)
var(w2, h2) = size(img2)
 
if ((w1 != w2) || (h1 != h2)) {
return nil
}
 
var sum = 0
for y,x in (^h1 ~X ^w1) {
sum += pixel_diff(read_pixel(img1, x, y), read_pixel(img2, x, y))
}
 
sum / (w1 * h1 * 255 * 3)
}
 
say 100*img_diff('Lenna50.jpg', 'Lenna100.jpg')</syntaxhighlight>
{{out}}
<pre>
1.62559309816048815359477124183007
</pre>
 
=={{header|Swift}}==
<syntaxhighlight lang="swift">func pixelValues(fromCGImage imageRef: CGImage?) -> [UInt8]?
{
var width = 0
var height = 0
var pixelValues: [UInt8]?
if let imageRef = imageRef {
width = imageRef.width
height = imageRef.height
let bitsPerComponent = imageRef.bitsPerComponent
let bytesPerRow = imageRef.bytesPerRow
let totalBytes = height * bytesPerRow
let bitmapInfo = imageRef.bitmapInfo
let colorSpace = CGColorSpaceCreateDeviceRGB()
var intensities = [UInt8](repeating: 0, count: totalBytes)
let contextRef = CGContext(data: &intensities,
width: width,
height: height,
bitsPerComponent: bitsPerComponent,
bytesPerRow: bytesPerRow,
space: colorSpace,
bitmapInfo: bitmapInfo.rawValue)
contextRef?.draw(imageRef, in: CGRect(x: 0.0, y: 0.0, width: CGFloat(width), height: CGFloat(height)))
pixelValues = intensities
}
return pixelValues
}
 
func compareImages(image1: UIImage, image2: UIImage) -> Double? {
guard let data1 = pixelValues(fromCGImage: image1.cgImage),
let data2 = pixelValues(fromCGImage: image2.cgImage),
data1.count == data2.count else {
return nil
}
let width = Double(image1.size.width)
let height = Double(image1.size.height)
return zip(data1, data2)
.enumerated()
.reduce(0.0) {
$1.offset % 4 == 3 ? $0 : $0 + abs(Double($1.element.0) - Double($1.element.1))
}
* 100 / (width * height * 3.0) / 255.0
}
 
let image1 = UIImage(named: "Lenna50")
let image2 = UIImage(named: "Lenna100")
 
compareImages(image1: image1, image2: image2)
 
</syntaxhighlight>
 
=={{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,125 ⟶ 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,132 ⟶ 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,161 ⟶ 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,168 ⟶ 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
<syntaxhighlight 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!"));
img1.data.howza(0).walker().zip(img2.data.howza(0)) // lazy bytes, not strings
.reduce(fcn(totalDiff,[(a,b)]){ totalDiff + (a - b).abs() },0)
.toFloat()/img1.w/img1.h/3/255; // or: .toFloat()/img1.data.len()/255
}</syntaxhighlight>
Take the bytes in each image, zip them together [lazily], sum the differences between each byte and normalize.
<syntaxhighlight lang="zkl">fcn readJPG2PPM(fileName){
p:=System.popen("convert \"%s\" ppm:-".fmt(fileName),"r");
img:=PPM.readPPM(p);
p.close();
img
}</syntaxhighlight>
Use the convert utility from ImageMagick to convert a JPEG image to PPM.
<syntaxhighlight lang="zkl">imageDiff(readJPG2PPM("lenna50.jpg"),readJPG2PPM("lenna100.jpg")) :
"Image difference = %f%%".fmt(_*100).println();</syntaxhighlight>
Compute the diff between the two Lennas, format and print it. More conventionally, this would be written as
<syntaxhighlight lang="zkl">println("Image difference = %f%%".fmt(
imageDiff(readJPG2PPM("lenna50.jpg"),readJPG2PPM("lenna100.jpg")) * 100)
);</syntaxhighlight>
{{out}}
<pre>
512 512 # verbiage from convert
512 512
Image difference = 1.624730%
</pre>
 
6

edits