Author |
Topic  |
|
jccruz
 
Brazil
30 Posts |
Posted - May 24 2012 : 07:38:22
|
Please, is there some method that I can use to create a image hash that I use it to find a similar image?
JCC |
|
Uwe
  
284 Posts |
Posted - May 24 2012 : 09:29:04
|
Create a CRC or GUID for each image and save it to a custom (meta) tag in the XMP section of the file. |
 |
|
jccruz
 
Brazil
30 Posts |
Posted - May 24 2012 : 12:16:21
|
Thanks Uwe! But how to compare two CRC and get the percentage difference between them? I mean, say that one CRC or any hash is n% different of the other?
JCC |
 |
|
Uwe
  
284 Posts |
Posted - May 24 2012 : 13:22:55
|
Sorry, I thought you were looking for duplicates. The CRC cannot tell you by what percentage two files differ; it just tells you that they differ. You might want to google for "delphi compare images". That comes up with quite a few hits.
Uwe |
 |
|
fab
   
1310 Posts |
Posted - May 25 2012 : 11:46:27
|
Unfortunately comparing images is not a simple task and ImageEn hasn't the magic algorithm to do it. It is possible to get an hash (MD2, MD4, MD5 or SHA) of a bitmap using TIEBitmap.GetHash. Of course even if two images differ by one pixel the hash will be completely different.
ImageEn has following methods to compare images: - TImageEnProc.CompareWith - TImageEnProc.CompareHistogramWith - TImageEnProc.ComputeImageEquality
Of course they need full images as input, so this doesn't help.
You could extract some info from the images and then compare this data. Maybe these functions could help: - ImageEnProc.CalcAverageRGB : just three numbers to compare, very poor comparing way! - TImageEnProc.CalcDensityHistogram : image_width+image_height values to compare, not so bad - TImageEnProc.GetHistogram : 256 RGB triplets (or 256 gray scale values) to compare, often used Perhaps you could use both CalcDensityHistogram and GetHistogram.
Remains the problem for a way to compare extracted info. There are several algorithms (even sophisticated) to compare vectors. If you choice to compare histograms then maybe the ImageEn undocumented function named IECompareHistograms (defined in hyieutils) could help. This function allows you to use three different comparing modes: RMSE (Root Mean Square error), Hamming (Hamming distance) and Covariance. All of them returns a single double value (0 = not equal up to 1 = maximum equality).
Hope this helps.
|
 |
|
jccruz
 
Brazil
30 Posts |
Posted - Jun 01 2012 : 13:03:28
|
Thanks Fabrizio!
Please give a help! When I compile, it gives the following error:
Undeclared Identifier: IECompareHistograms
Bellow you can see the code:
unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ieview, imageenview, imageenproc, hyieutils;
type TForm1 = class(TForm) ImageEnView1: TImageEnView; ImageEnView2: TImageEnView; Button1: TButton; Button2: TButton; Button3: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); begin with ImageEnView1.IO do LoadFromFile( ExecuteOpenDialog('','',false,1,'') ); end;
procedure TForm1.Button2Click(Sender: TObject); begin with ImageEnView2.IO do LoadFromFile( ExecuteOpenDialog('','',false,1,'') ); end;
procedure TForm1.Button3Click(Sender: TObject); var hist1, hist2: THistogram; er: double; begin ImageEnView1.Proc.GetHistogram( @hist1 ); ImageEnView2.Proc.GetHistogram( @hist2 );
er := IECompareHistograms(hist1,hist2,iecmpHamming,3);
end;
end.
Thanks
Jose
JCC |
 |
|
fab
   
1310 Posts |
Posted - Jun 02 2012 : 00:27:35
|
Ops, my error! IECompareHistograms isn't visible outside imageenproc. It will be starting from next minor release. In the mean time here is the code:
// channel: 0=R, 1=G, 2=B, 3=gray
function IECompareHistograms(h1,h2:THistogram; Mode:TIECmpMode; channel:integer):double;
var
i:integer;
v1,v2:PDWORD;
max,min:DWORD;
m1,m2,d1,d2:double;
begin
result:=0;
case Mode of
iecmpRMSE: // Root Mean Square error
begin
max:=0;
min:=$FFFFFFFF;
for i:=0 to 255 do
begin
v1:=PDWORD(@h1[i]); inc(v1,channel);
v2:=PDWORD(@h2[i]); inc(v2,channel);
result:=result + sqr(v1^-v2^);
if v1^>max then max:=v1^;
if v2^>max then max:=v2^;
if v1^<min then min:=v1^;
if v2^<min then min:=v2^;
end;
result:=sqrt(result/256) / (max-min);
end;
iecmpHamming: // Hamming distance
begin
for i:=0 to 255 do
begin
v1:=PDWORD(@h1[i]); inc(v1,channel);
v2:=PDWORD(@h2[i]); inc(v2,channel);
if v1^<>v2^ then
result:=result+1;
end;
result:=result/256;
end;
iecmpCovariance: // Covariance
begin
m1:=0; m2:=0;
for i:=0 to 255 do
begin
v1:=PDWORD(@h1[i]); inc(v1,channel);
v2:=PDWORD(@h2[i]); inc(v2,channel);
m1:=m1+v1^;
m2:=m2+v2^;
end;
m1:=m1/256;
m2:=m2/256;
for i:=0 to 255 do
begin
v1:=PDWORD(@h1[i]); inc(v1,channel);
v2:=PDWORD(@h2[i]); inc(v2,channel);
d1:=v1^-m1;
d2:=v2^-m2;
result:=result+(d1 * d2 - result) / (i + 1);
end;
end;
end;
end;
|
 |
|
|
Topic  |
|
|
|