📜 ⬆️ ⬇️

Simple image comparison using php

The algorithm may not be new, and is not ideal , but, surprisingly, it works. No graphs and correlations.

To begin with, it is worth noting that the comparison is very approximate (at least at this stage), from time to time two completely different photos turn out to be similar by 60%, and also hard modifications (turns, inversion, cropping) are not taken into account - for this you need to bring and bring. For me personally, two parameters turned out to be the most important: speed , independence from image resolution and the ability to compare “images” right in the database.

Principle


Code


In this case, there is a version that works through GD with PNG images.
// -
function getimageid($image)
{
//
$size=getimagesize($image);

//
$image=imagecreatefrompng($image);

//
$zone=imagecreate(20,20);

//
imagecopyresized($zone,$image,0,0,0,0,20,20,$size[0],$size[1]);

//
$colormap=array();

//
$average=0;

//
$result=array();

//
for ($x=0;$x<20;$x++)
for ($y=0;$y<20;$y++)
{
$color=imagecolorat($zone,$x,$y);
$color=imagecolorsforindex($zone,$color);

// Ryotsuke
$colormap[$x][$y]= 0.212671 * $color[ 'red' ] + 0.715160 * $color[ 'green' ] + 0.072169 * $color[ 'blue' ];

$average += $colormap[$x][$y];
}

//
$average /= 400;

//
for ($x=0;$x<20;$x++)
for ($y=0;$y<20;$y++)
$result[]=($x<10?$x:chr($x+97)).($y<10?$y:chr($y+97)).round(2*$colormap[$x][$y]/$average);

//
return join( ' ' ,$result);
}


* This source code was highlighted with Source Code Highlighter .

// ""
function imagediff($image,$desc)
{
$image=explode( ' ' ,$image);
$desc=explode( ' ' ,$desc);

$result=0;

foreach ($image as $bit)
if (in_array($bit,$desc))
$result++;

return $result/((count($image)+count($desc))/2);
}


* This source code was highlighted with Source Code Highlighter .

* similarity counting function is approximate - it is better to perform this action on the side of the base.

Examples


image
Surprisingly, 95% 87% similarity (with the addition of UPD-2)
')
image
52% similarity

image
28% similarity

image
100% similarity

P.S


All this is only an approximate calculation, it is not possible to achieve a particularly advanced comparison in this way, but it will come down for a quick sample from the database of similar images.

PS Comments and advice accepted.
UPD Thanks MiniM - the code is simplified.
UPD-2 A small addition:
//
for ($x=0;$x<20;$x++)
for ($y=0;$y<20;$y++)
$result[]=($x<10?$x:chr($x+97)).($y<10?$y:chr($y+97)).($colormap[$x][$y]==0? '0' :round(2*($colormap[$x][$y]>$average?$colormap[$x][$y]/$average:-1*$average/$colormap[$x][$y])));

* This source code was highlighted with Source Code Highlighter .

After that, the decrease in brightness at a point will be taken into account. Thus, the similarity in the first example will be 87% .
UPD-3 Migrated to php.

Source: https://habr.com/ru/post/55926/


All Articles