Percentage difference between images: Difference between revisions
Content added Content deleted
m (→{{header|Phix}}: syntax coloured, marked p2js incompatible) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 20: | Line 20: | ||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
< |
<syntaxhighlight lang="ada">type Count is mod 2**64;</syntaxhighlight> |
||
[[wp:Distance|1-norm distance]] in the luminance space: |
[[wp:Distance|1-norm distance]] in the luminance space: |
||
< |
<syntaxhighlight lang="ada">function "-" (Left, Right : Luminance) return Count is |
||
begin |
begin |
||
if Left > Right then |
if Left > Right then |
||
Line 29: | Line 29: | ||
return Count (Right) - Count (Left); |
return Count (Right) - Count (Left); |
||
end if; |
end if; |
||
end "-";</ |
end "-";</syntaxhighlight> |
||
1-norm distance in the color space multiplied to 3: |
1-norm distance in the color space multiplied to 3: |
||
< |
<syntaxhighlight lang="ada">function "-" (Left, Right : Pixel) return Count is |
||
begin |
begin |
||
return (Left.R - Right.R) + (Left.G - Left.G) + (Left.B - Right.B); |
return (Left.R - Right.R) + (Left.G - Left.G) + (Left.B - Right.B); |
||
end "-";</ |
end "-";</syntaxhighlight> |
||
Mean of 1-norm distances. Constraint_Error is propagated when images have different size. |
Mean of 1-norm distances. Constraint_Error is propagated when images have different size. |
||
< |
<syntaxhighlight lang="ada">function Diff (Left, Right : Image) return Float is |
||
Offs_I : constant Integer := Right'First (1) - Left'First (1); |
Offs_I : constant Integer := Right'First (1) - Left'First (1); |
||
Offs_J : constant Integer := Right'First (2) - Left'First (2); |
Offs_J : constant Integer := Right'First (2) - Left'First (2); |
||
Line 50: | Line 50: | ||
end loop; |
end loop; |
||
return Float (Sum) / (3.0 * Float (Left'Length (1) * Left'Length (2))); |
return Float (Sum) / (3.0 * Float (Left'Length (1) * Left'Length (2))); |
||
end Diff;</ |
end Diff;</syntaxhighlight> |
||
Example of use: |
Example of use: |
||
< |
<syntaxhighlight lang="ada"> F1, F2 : File_Type; |
||
begin |
begin |
||
Open (F1, In_File, "city.ppm"); |
Open (F1, In_File, "city.ppm"); |
||
Line 58: | Line 58: | ||
Ada.Text_IO.Put_Line ("Diff" & Float'Image (Diff (Get_PPM (F1), Get_PPM (F2)))); |
Ada.Text_IO.Put_Line ("Diff" & Float'Image (Diff (Get_PPM (F1), Get_PPM (F2)))); |
||
Close (F1); |
Close (F1); |
||
Close (F2);</ |
Close (F2);</syntaxhighlight> |
||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
{{works with | AutoHotkey_L}} |
{{works with | AutoHotkey_L}} |
||
uses [http://www.autohotkey.com/forum/topic32238.html gdip.ahk] |
uses [http://www.autohotkey.com/forum/topic32238.html gdip.ahk] |
||
< |
<syntaxhighlight lang="autohotkey">startup() |
||
dibSection := getPixels("lenna100.jpg") |
dibSection := getPixels("lenna100.jpg") |
||
dibSection2 := getPixels("lenna50.jpg") ; ("File-Lenna100.jpg") |
dibSection2 := getPixels("lenna50.jpg") ; ("File-Lenna100.jpg") |
||
Line 148: | Line 148: | ||
} |
} |
||
#Include Gdip.ahk ; Thanks to tic (Tariq Porter) for his GDI+ Library |
#Include Gdip.ahk ; Thanks to tic (Tariq Porter) for his GDI+ Library |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|BBC BASIC}}== |
=={{header|BBC BASIC}}== |
||
{{works with|BBC BASIC for Windows}} |
{{works with|BBC BASIC for Windows}} |
||
I would have preferred to calculate the RMS difference but it would be inconsistent with other results. |
I would have preferred to calculate the RMS difference but it would be inconsistent with other results. |
||
< |
<syntaxhighlight lang="bbcbasic"> hbm1% = FNloadimage("C:lenna50.jpg") |
||
hbm2% = FNloadimage("C:lenna100.jpg") |
hbm2% = FNloadimage("C:lenna100.jpg") |
||
Line 200: | Line 200: | ||
SYS !(!pic%+12), pic%, ^hbm% : REM. IPicture::get_Handle |
SYS !(!pic%+12), pic%, ^hbm% : REM. IPicture::get_Handle |
||
SYS "FreeLibrary", ole% |
SYS "FreeLibrary", ole% |
||
= hbm%</ |
= hbm%</syntaxhighlight> |
||
'''Output:''' |
'''Output:''' |
||
<pre> |
<pre> |
||
Line 210: | Line 210: | ||
The <tt>read_image</tt> function is from [[Read image file through a pipe|here]]. |
The <tt>read_image</tt> function is from [[Read image file through a pipe|here]]. |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
#include <math.h> |
#include <math.h> |
||
Line 254: | Line 254: | ||
free_img(im1); |
free_img(im1); |
||
free_img(im2); |
free_img(im2); |
||
}</ |
}</syntaxhighlight> |
||
The output on Lenna is: |
The output on Lenna is: |
||
Line 264: | Line 264: | ||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
using System.Drawing; |
using System.Drawing; |
||
Line 297: | Line 297: | ||
Console.WriteLine("diff: {0} %", 100 * (diff / 255) / (img1.Width * img1.Height * 3)); |
Console.WriteLine("diff: {0} %", 100 * (diff / 255) / (img1.Width * img1.Height * 3)); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C++}}== |
=={{header|C++}}== |
||
based upon C version, using Qt 4.4 |
based upon C version, using Qt 4.4 |
||
< |
<syntaxhighlight lang="cpp">#include <QImage> |
||
#include <cstdlib> |
#include <cstdlib> |
||
#include <QColor> |
#include <QColor> |
||
Line 344: | Line 344: | ||
(totaldiff * 100) / (w * h * 3) << " % !\n" ; |
(totaldiff * 100) / (w * h * 3) << " % !\n" ; |
||
return 0 ; |
return 0 ; |
||
}</ |
}</syntaxhighlight> |
||
output on pictures given; |
output on pictures given; |
||
Line 355: | Line 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. |
This is based upon the C version. Strangely enough, the percentage is 1.77% which is off by about a tenth of a percent. |
||
< |
<syntaxhighlight lang="lisp">(require 'cl-jpeg) |
||
;;; the JPEG library uses simple-vectors to store data. this is insane! |
;;; the JPEG library uses simple-vectors to store data. this is insane! |
||
(defun compare-images (file1 file2) |
(defun compare-images (file1 file2) |
||
Line 368: | Line 368: | ||
CL-USER> (* 100 (compare-images "Lenna50.jpg" "Lenna100.jpg")) |
CL-USER> (* 100 (compare-images "Lenna50.jpg" "Lenna100.jpg")) |
||
1.774856467652165d0</ |
1.774856467652165d0</syntaxhighlight> |
||
=={{header|D}}== |
=={{header|D}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="d">import std.stdio, std.exception, std.range, std.math, bitmap; |
||
void main() { |
void main() { |
||
Line 388: | Line 388: | ||
writeln("Difference (percentage): ", |
writeln("Difference (percentage): ", |
||
(dif / 255.0 * 100) / nData); |
(dif / 255.0 * 100) / nData); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Difference (percentage): 1.62559</pre> |
<pre>Difference (percentage): 1.62559</pre> |
||
Line 396: | Line 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). |
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). |
||
< |
<syntaxhighlight lang="e">def imageDifference(a, b) { |
||
require(a.width() == b.width()) |
require(a.width() == b.width()) |
||
require(a.height() == b.height()) |
require(a.height() == b.height()) |
||
Line 424: | Line 424: | ||
def d := imageDifference(a, b) |
def d := imageDifference(a, b) |
||
println(`${d * 100}% different.`) |
println(`${d * 100}% different.`) |
||
}</ |
}</syntaxhighlight> |
||
The result on the provided images is 1.6255930981604882%. |
The result on the provided images is 1.6255930981604882%. |
||
=={{header|F_Sharp|F#}}== |
=={{header|F_Sharp|F#}}== |
||
< |
<syntaxhighlight lang="fsharp"> |
||
//Percentage difference between 2 images. Nigel Galloway April 18th., 2018 |
//Percentage difference between 2 images. Nigel Galloway April 18th., 2018 |
||
let img50 = new System.Drawing.Bitmap("Lenna50.jpg") |
let img50 = new System.Drawing.Bitmap("Lenna50.jpg") |
||
let img100 = new System.Drawing.Bitmap("Lenna100.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 |
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))</ |
printfn "%f" ((float diff)*100.00/(float(img50.Height*img50.Width)*255.0*3.0))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 441: | Line 441: | ||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
< |
<syntaxhighlight 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 |
||
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 457: | Line 457: | ||
: .bdiff ( bmp1 bmp2 -- ) |
: .bdiff ( bmp1 bmp2 -- ) |
||
cr bdiff 100e f* f. ." percent different" ;</ |
cr bdiff 100e f* f. ." percent different" ;</syntaxhighlight> |
||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
< |
<syntaxhighlight lang="fortran">program ImageDifference |
||
use RCImageBasic |
use RCImageBasic |
||
Line 492: | Line 492: | ||
call free_img(lenna2) |
call free_img(lenna2) |
||
end program ImageDifference</ |
end program ImageDifference</syntaxhighlight> |
||
This gives 1.6555154. |
This gives 1.6555154. |
||
Line 498: | Line 498: | ||
=={{header|Frink}}== |
=={{header|Frink}}== |
||
< |
<syntaxhighlight lang="frink"> |
||
img1 = new image["file:Lenna50.jpg"] |
img1 = new image["file:Lenna50.jpg"] |
||
img2 = new image["file:Lenna100.jpg"] |
img2 = new image["file:Lenna100.jpg"] |
||
Line 516: | Line 516: | ||
errors = sum / (w1 * h1 * 3) |
errors = sum / (w1 * h1 * 3) |
||
println["Error is " + (errors->"percent")] |
println["Error is " + (errors->"percent")] |
||
</syntaxhighlight> |
|||
</lang> |
|||
This gives an error of approximately 1.625593 percent. |
This gives an error of approximately 1.625593 percent. |
||
Line 522: | Line 522: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
Using standard image library: |
Using standard image library: |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 588: | Line 588: | ||
fmt.Printf("Image difference: %f%%\n", |
fmt.Printf("Image difference: %f%%\n", |
||
float64(sum*100)/(float64(nPixels)*0xffff*3)) |
float64(sum*100)/(float64(nPixels)*0xffff*3)) |
||
}</ |
}</syntaxhighlight> |
||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 594: | Line 594: | ||
</pre> |
</pre> |
||
Using code from bitmap task: |
Using code from bitmap task: |
||
< |
<syntaxhighlight lang="go">package main |
||
// Files required to build supporting package raster are found in: |
// Files required to build supporting package raster are found in: |
||
Line 665: | Line 665: | ||
fmt.Printf("Image difference: %f%%\n", |
fmt.Printf("Image difference: %f%%\n", |
||
float64(sum)*100/(float64(b1c*b1r)*255*3)) |
float64(sum)*100/(float64(b1c*b1r)*255*3)) |
||
}</ |
}</syntaxhighlight> |
||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 675: | Line 675: | ||
This implementation takes PPMs as input. It uses modules defined in [[Basic bitmap storage]] and [[Write ppm file]]. |
This implementation takes PPMs as input. It uses modules defined in [[Basic bitmap storage]] and [[Write ppm file]]. |
||
< |
<syntaxhighlight lang="haskell">import Bitmap |
||
import Bitmap.Netpbm |
import Bitmap.Netpbm |
||
import Bitmap.RGB |
import Bitmap.RGB |
||
Line 700: | Line 700: | ||
toEnum (3 * 255 * length i1) |
toEnum (3 * 255 * length i1) |
||
where (RGB (r1, g1, b1)) `minus` (RGB (r2, g2, b2)) = |
where (RGB (r1, g1, b1)) `minus` (RGB (r2, g2, b2)) = |
||
abs (r1 - r2) + abs (g1 - g2) + abs (b1 - b2)</ |
abs (r1 - r2) + abs (g1 - g2) + abs (b1 - b2)</syntaxhighlight> |
||
=={{header|Icon}} and {{header|Unicon}}== |
=={{header|Icon}} and {{header|Unicon}}== |
||
Line 706: | Line 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. |
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. |
||
< |
<syntaxhighlight lang="unicon">link printf # for main only |
||
procedure main() # % difference between images |
procedure main() # % difference between images |
||
Line 739: | Line 739: | ||
} |
} |
||
return L |
return L |
||
end</ |
end</syntaxhighlight> |
||
Output:<pre>%difference of files "Lenna100.jpg" & "Lenna50.jpg" = 1.625587</pre> |
Output:<pre>%difference of files "Lenna100.jpg" & "Lenna50.jpg" = 1.625587</pre> |
||
=={{header|J}}== |
=={{header|J}}== |
||
< |
<syntaxhighlight lang="j"> require 'media/image3' |
||
'Lenna50.jpg' (+/@,@:|@:- % 2.55 * */@$@])&read_image 'Lenna100.jpg' |
'Lenna50.jpg' (+/@,@:|@:- % 2.55 * */@$@])&read_image 'Lenna100.jpg' |
||
1.62559</ |
1.62559</syntaxhighlight> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
< |
<syntaxhighlight lang="java">import java.awt.image.BufferedImage; |
||
import java.io.File; |
import java.io.File; |
||
import java.io.IOException; |
import java.io.IOException; |
||
Line 797: | Line 797: | ||
return Math.abs(r1 - r2) + Math.abs(g1 - g2) + Math.abs(b1 - b2); |
return Math.abs(r1 - r2) + Math.abs(g1 - g2) + Math.abs(b1 - b2); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
< |
<syntaxhighlight lang="javascript">function getImageData(url, callback) { |
||
var img = document.createElement('img'); |
var img = document.createElement('img'); |
||
var canvas = document.createElement('canvas'); |
var canvas = document.createElement('canvas'); |
||
Line 839: | Line 839: | ||
compare('Lenna50.jpg', 'Lenna100.jpg', function (result) { |
compare('Lenna50.jpg', 'Lenna100.jpg', function (result) { |
||
console.log(result); |
console.log(result); |
||
});</ |
});</syntaxhighlight> |
||
=={{header|Julia}}== |
=={{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)) |
absdiff(a::RGB{T}, b::RGB{T}) where T = sum(abs(col(a) - col(b)) for col in (red, green, blue)) |
||
Line 858: | Line 858: | ||
d = pctdiff(img50, img100) |
d = pctdiff(img50, img100) |
||
@printf("Percentage difference: %.4f%%\n", d)</ |
@printf("Percentage difference: %.4f%%\n", d)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 865: | Line 865: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
{{trans|Java}} |
{{trans|Java}} |
||
< |
<syntaxhighlight lang="scala">// version 1.2.10 |
||
import java.awt.image.BufferedImage |
import java.awt.image.BufferedImage |
||
Line 907: | Line 907: | ||
val p = getDifferencePercent(img1, img2) |
val p = getDifferencePercent(img1, img2) |
||
println("The percentage difference is ${"%.6f".format(p)}%") |
println("The percentage difference is ${"%.6f".format(p)}%") |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 916: | Line 916: | ||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
Using the Bitmap class from [[Bitmap/Bresenham%27s_line_algorithm#Lua|here]] and ImageMagick to preprocess jpg->ppm to simplify loading: |
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" ) |
local fp = io.open( filename, "rb" ) |
||
if fp == nil then return false end |
if fp == nil then return false end |
||
Line 950: | Line 950: | ||
bm100:loadPPM("Lenna100.ppm") |
bm100:loadPPM("Lenna100.ppm") |
||
print("%diff:", bm100:percentageDifference(bm50))</ |
print("%diff:", bm100:percentageDifference(bm50))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>%diff: 1.6255930981605</pre> |
<pre>%diff: 1.6255930981605</pre> |
||
Line 957: | Line 957: | ||
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! |
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] |
The GUI shows the 'difference image'. [http://www.diga.me.uk/right.gif SceenDisplay] |
||
<syntaxhighlight lang="lb"> |
|||
<lang lb> |
|||
now =time$( "seconds") |
now =time$( "seconds") |
||
nomainwin |
nomainwin |
||
Line 1,039: | Line 1,039: | ||
close #j |
close #j |
||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
< |
<syntaxhighlight lang="mathematica">img50 = ImageData@Import[NotebookDirectory[] <> "Lenna50.jpg"]; |
||
img100 = ImageData@Import[NotebookDirectory[] <> "Lenna100.jpg"]; |
img100 = ImageData@Import[NotebookDirectory[] <> "Lenna100.jpg"]; |
||
diff = img50 - img100; |
diff = img50 - img100; |
||
Print["Total Difference between both Lenas = ", |
Print["Total Difference between both Lenas = ", |
||
Total@Abs@Flatten@diff/Times @@ Dimensions@img50*100, "%"]</ |
Total@Abs@Flatten@diff/Times @@ Dimensions@img50*100, "%"]</syntaxhighlight> |
||
'''Output''' |
'''Output''' |
||
Line 1,052: | Line 1,052: | ||
=={{header|MATLAB}}== |
=={{header|MATLAB}}== |
||
<syntaxhighlight lang="matlab"> |
|||
<lang MATLAB> |
|||
% Percentage difference between images |
% Percentage difference between images |
||
function p = PercentageDifferenceBetweenImages(im1,im2) |
function p = PercentageDifferenceBetweenImages(im1,im2) |
||
Line 1,063: | Line 1,063: | ||
p = sum(d(:))./numel(im1)*100; |
p = sum(d(:))./numel(im1)*100; |
||
disp(['Percentage difference between images is: ', num2str(p), '%'])</ |
disp(['Percentage difference between images is: ', num2str(p), '%'])</syntaxhighlight> |
||
'''Output''' |
'''Output''' |
||
Line 1,069: | Line 1,069: | ||
=={{header|MAXScript}}== |
=={{header|MAXScript}}== |
||
< |
<syntaxhighlight lang="maxscript">fn diffImages = |
||
( |
( |
||
local img1 = selectBitmap caption:"Select Image 1" |
local img1 = selectBitmap caption:"Select Image 1" |
||
Line 1,087: | Line 1,087: | ||
) |
) |
||
format "Diff: %\%\n" (totalDiff / ((img1.width * img1.height * 3) as float) * 100) |
format "Diff: %\%\n" (totalDiff / ((img1.width * img1.height * 3) as float) * 100) |
||
)</ |
)</syntaxhighlight> |
||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
{{libheader|imageman}} |
{{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 %. |
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 |
import imageman |
||
Line 1,116: | Line 1,116: | ||
sum += abs(color1[i].int - color2[i].int) |
sum += abs(color1[i].int - color2[i].int) |
||
echo &"Image difference: {sum * 100 / (width * height * 3 * 255):.4f} %"</ |
echo &"Image difference: {sum * 100 / (width * height * 3 * 255):.4f} %"</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,124: | Line 1,124: | ||
{{libheader|glMLite}} |
{{libheader|glMLite}} |
||
< |
<syntaxhighlight lang="ocaml">#! /usr/bin/env ocaml |
||
#directory "+glMLite/" |
#directory "+glMLite/" |
||
#load "jpeg_loader.cma" |
#load "jpeg_loader.cma" |
||
Line 1,159: | Line 1,159: | ||
let diff_percent = !sum /. float !num in |
let diff_percent = !sum /. float !num in |
||
Printf.printf " diff: %f percent\n" diff_percent; |
Printf.printf " diff: %f percent\n" diff_percent; |
||
;;</ |
;;</syntaxhighlight> |
||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
< |
<syntaxhighlight lang="perl">use Image::Imlib2; |
||
my $img1 = Image::Imlib2->load('Lenna50.jpg') || die; |
my $img1 = Image::Imlib2->load('Lenna50.jpg') || die; |
||
Line 1,180: | Line 1,180: | ||
} |
} |
||
printf "%% difference = %.4f\n", 100 * $sum / ($w * $h * 3 * 255);</ |
printf "%% difference = %.4f\n", 100 * $sum / ($w * $h * 3 * 255);</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>% difference = 1.7747</pre> |
<pre>% difference = 1.7747</pre> |
||
Alternative solution: |
Alternative solution: |
||
< |
<syntaxhighlight lang="perl">use Imager; |
||
use List::AllUtils qw(sum pairwise); |
use List::AllUtils qw(sum pairwise); |
||
Line 1,213: | Line 1,213: | ||
} |
} |
||
printf "difference = %f%%\n", 100 * img_diff('Lenna50.jpg', 'Lenna100.jpg');</ |
printf "difference = %f%%\n", 100 * img_diff('Lenna50.jpg', 'Lenna100.jpg');</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,220: | Line 1,220: | ||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
<!--< |
<!--<syntaxhighlight lang="phix">(notonline)--> |
||
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Percentage_difference_between_images.exw</span> |
<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;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (file i/o)</span> |
||
Line 1,251: | Line 1,251: | ||
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</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}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,258: | Line 1,258: | ||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
< |
<syntaxhighlight lang="picolisp">(call "convert" "Lenna50.jpg" (tmp "Lenna50.ppm")) |
||
(call "convert" "Lenna100.jpg" (tmp "Lenna100.ppm")) |
(call "convert" "Lenna100.jpg" (tmp "Lenna100.ppm")) |
||
Line 1,271: | Line 1,271: | ||
255 ) ) |
255 ) ) |
||
(inc 'Total) ) ) ) |
(inc 'Total) ) ) ) |
||
(prinl "Difference is " (format (*/ Diff Total) 4) " percent") )</ |
(prinl "Difference is " (format (*/ Diff Total) 4) " percent") )</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>Difference is 1.6256 percent</pre> |
<pre>Difference is 1.6256 percent</pre> |
||
Line 1,277: | Line 1,277: | ||
=={{header|PureBasic}}== |
=={{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. |
This program downloads both jpg files, decodes them & saves them in 2D-arrays for simple comparison which part is comparable with the other languages. |
||
< |
<syntaxhighlight lang="purebasic">#URL1="http://rosettacode.org/mw/images/3/3c/Lenna50.jpg" |
||
#URL2="http://rosettacode.org/mw/images/b/b6/Lenna100.jpg" |
#URL2="http://rosettacode.org/mw/images/b/b6/Lenna100.jpg" |
||
Line 1,328: | Line 1,328: | ||
Next x |
Next x |
||
MessageRequester("Result","Diff= "+StrD(100*totalDiff/(255*w*h*3),3)+" %")</ |
MessageRequester("Result","Diff= "+StrD(100*totalDiff/(255*w*h*3),3)+" %")</syntaxhighlight> |
||
=={{header|Python}}== |
=={{header|Python}}== |
||
Line 1,334: | Line 1,334: | ||
{{works with|python version 3.x}} |
{{works with|python version 3.x}} |
||
< |
<syntaxhighlight lang="python">from PIL import Image |
||
i1 = Image.open("image1.jpg") |
i1 = Image.open("image1.jpg") |
||
Line 1,349: | Line 1,349: | ||
ncomponents = i1.size[0] * i1.size[1] * 3 |
ncomponents = i1.size[0] * i1.size[1] * 3 |
||
print ("Difference (percentage):", (dif / 255.0 * 100) / ncomponents)</ |
print ("Difference (percentage):", (dif / 255.0 * 100) / ncomponents)</syntaxhighlight> |
||
{{works with|python version 2.x}} |
{{works with|python version 2.x}} |
||
< |
<syntaxhighlight lang="python">from itertools import izip |
||
import Image |
import Image |
||
Line 1,368: | Line 1,368: | ||
ncomponents = i1.size[0] * i1.size[1] * 3 |
ncomponents = i1.size[0] * i1.size[1] * 3 |
||
print "Difference (percentage):", (dif / 255.0 * 100) / ncomponents</ |
print "Difference (percentage):", (dif / 255.0 * 100) / ncomponents</syntaxhighlight> |
||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
Line 1,374: | Line 1,374: | ||
Note: On OS X I get 1.6192% as the result. (soegaard) |
Note: On OS X I get 1.6192% as the result. (soegaard) |
||
< |
<syntaxhighlight lang="racket">#lang racket |
||
(require racket/draw) |
(require racket/draw) |
||
Line 1,395: | Line 1,395: | ||
(define lenna100 (read-bitmap "lenna100.jpg")) |
(define lenna100 (read-bitmap "lenna100.jpg")) |
||
(percentage-difference lenna50 lenna100) ;-> 1.7749329408009846</ |
(percentage-difference lenna50 lenna100) ;-> 1.7749329408009846</syntaxhighlight> |
||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
Line 1,401: | Line 1,401: | ||
Using [https://modules.raku.org/search/?q=GD%3A%3ARaw GD::Raw from the Raku ecosystem]. |
Using [https://modules.raku.org/search/?q=GD%3A%3ARaw GD::Raw from the Raku ecosystem]. |
||
<lang |
<syntaxhighlight lang="raku" line>use GD::Raw; |
||
my $fh1 = fopen('./Lenna50.jpg', "rb") or die; |
my $fh1 = fopen('./Lenna50.jpg', "rb") or die; |
||
Line 1,433: | Line 1,433: | ||
gdImageDestroy($img1); |
gdImageDestroy($img1); |
||
gdImageDestroy($img2); |
gdImageDestroy($img2); |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,440: | Line 1,440: | ||
=={{header|REBOL}}== |
=={{header|REBOL}}== |
||
< |
<syntaxhighlight lang="rebol">REBOL [ |
||
Title: "Percent Image Difference" |
Title: "Percent Image Difference" |
||
URL: http://rosettacode.org/wiki/Percentage_of_difference_between_2_images |
URL: http://rosettacode.org/wiki/Percentage_of_difference_between_2_images |
||
Line 1,489: | Line 1,489: | ||
button "b" #"b" [flip 'b] |
button "b" #"b" [flip 'b] |
||
button "difference" #"d" [flip 'diff] |
button "difference" #"d" [flip 'diff] |
||
]</ |
]</syntaxhighlight> |
||
Output: |
Output: |
||
Line 1,501: | Line 1,501: | ||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
uses the <code>[[Raster graphics operations/Ruby|raster_graphics]]</code> library |
uses the <code>[[Raster graphics operations/Ruby|raster_graphics]]</code> library |
||
< |
<syntaxhighlight lang="ruby">require 'raster_graphics' |
||
class RGBColour |
class RGBColour |
||
Line 1,527: | Line 1,527: | ||
lenna100 = Pixmap.open_from_jpeg('Lenna100.jpg') |
lenna100 = Pixmap.open_from_jpeg('Lenna100.jpg') |
||
puts "difference: %.5f%%" % (100.0 * (lenna50 - lenna100))</ |
puts "difference: %.5f%%" % (100.0 * (lenna50 - lenna100))</syntaxhighlight> |
||
produces: |
produces: |
||
Line 1,533: | Line 1,533: | ||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
< |
<syntaxhighlight lang="rust">extern crate image; |
||
use image::{GenericImageView, Rgba}; |
use image::{GenericImageView, Rgba}; |
||
Line 1,552: | Line 1,552: | ||
} |
} |
||
println!("Percent difference {}", accum as f64 * 100.0/ (255.0 * 3.0 * (img1.width() * img1.height()) as f64)); |
println!("Percent difference {}", accum as f64 * 100.0/ (255.0 * 3.0 * (img1.width() * img1.height()) as f64)); |
||
}</ |
}</syntaxhighlight> |
||
produces: |
produces: |
||
Line 1,558: | Line 1,558: | ||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
< |
<syntaxhighlight lang="ruby">require('Imager') |
||
func img_diff(a, b) { |
func img_diff(a, b) { |
||
Line 1,595: | Line 1,595: | ||
} |
} |
||
say 100*img_diff('Lenna50.jpg', 'Lenna100.jpg')</ |
say 100*img_diff('Lenna50.jpg', 'Lenna100.jpg')</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,602: | Line 1,602: | ||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
< |
<syntaxhighlight lang="swift">func pixelValues(fromCGImage imageRef: CGImage?) -> [UInt8]? |
||
{ |
{ |
||
var width = 0 |
var width = 0 |
||
Line 1,657: | Line 1,657: | ||
compareImages(image1: image1, image2: image2) |
compareImages(image1: image1, image2: image2) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
{{libheader|Tk}} |
{{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. |
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. |
||
< |
<syntaxhighlight lang="tcl">package require Tk |
||
proc imageDifference {img1 img2} { |
proc imageDifference {img1 img2} { |
||
Line 1,687: | Line 1,687: | ||
image create photo lenna100 -file lenna100.jpg |
image create photo lenna100 -file lenna100.jpg |
||
puts "difference is [expr {[imageDifference lenna50 lenna100]*100.}]%" |
puts "difference is [expr {[imageDifference lenna50 lenna100]*100.}]%" |
||
exit ;# Need explicit exit here; don't want a GUI</ |
exit ;# Need explicit exit here; don't want a GUI</syntaxhighlight> |
||
It produces this output: |
It produces this output: |
||
difference is 1.6255930981604882% |
difference is 1.6255930981604882% |
||
Line 1,694: | Line 1,694: | ||
This implementation compares two BMP images. |
This implementation compares two BMP images. |
||
< |
<syntaxhighlight lang="vedit">Chdir("|(USER_MACRO)\Rosetta\data") |
||
File_Open("Lenna50.bmp", BROWSE) |
File_Open("Lenna50.bmp", BROWSE) |
||
#10 = Buf_Num // #10 = buffer for 1st image |
#10 = Buf_Num // #10 = buffer for 1st image |
||
Line 1,723: | Line 1,723: | ||
Buf_Switch(#10) Buf_Quit(OK) |
Buf_Switch(#10) Buf_Quit(OK) |
||
Buf_Switch(#20) Buf_Quit(OK)</ |
Buf_Switch(#20) Buf_Quit(OK)</syntaxhighlight> |
||
Output, when comparing the Lenna images that were converted to BMP: |
Output, when comparing the Lenna images that were converted to BMP: |
||
Line 1,735: | Line 1,735: | ||
{{trans|Kotlin}} |
{{trans|Kotlin}} |
||
{{libheader|DOME}} |
{{libheader|DOME}} |
||
< |
<syntaxhighlight lang="ecmascript">import "graphics" for Canvas, Color, ImageData |
||
import "dome" for Window |
import "dome" for Window |
||
Line 1,783: | Line 1,783: | ||
} |
} |
||
var Game = PercentageDifference.new(1100, 550, "Lenna50.jpg", "Lenna100.jpg")</ |
var Game = PercentageDifference.new(1100, 550, "Lenna50.jpg", "Lenna100.jpg")</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,792: | Line 1,792: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
Uses the PPM class from http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#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) |
if(img1.w!=img2.w or img1.h!=img2.h) |
||
throw(Exception.ValueError("width/height of the images must match!")); |
throw(Exception.ValueError("width/height of the images must match!")); |
||
Line 1,798: | Line 1,798: | ||
.reduce(fcn(totalDiff,[(a,b)]){ totalDiff + (a - b).abs() },0) |
.reduce(fcn(totalDiff,[(a,b)]){ totalDiff + (a - b).abs() },0) |
||
.toFloat()/img1.w/img1.h/3/255; // or: .toFloat()/img1.data.len()/255 |
.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. |
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"); |
p:=System.popen("convert \"%s\" ppm:-".fmt(fileName),"r"); |
||
img:=PPM.readPPM(p); |
img:=PPM.readPPM(p); |
||
p.close(); |
p.close(); |
||
img |
img |
||
}</ |
}</syntaxhighlight> |
||
Use the convert utility from ImageMagick to convert a JPEG image to PPM. |
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();</ |
"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 |
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) |
imageDiff(readJPG2PPM("lenna50.jpg"),readJPG2PPM("lenna100.jpg")) * 100) |
||
);</ |
);</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |