图像相似度算法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1、图片大小规格化

为了比较两个图像,应该使其大小完全一致,这里可以设置为两个图片中较大的那个大小,长宽。

function Resize(const Source: TBitmap; var Dest: TBitmap): Boolean;

begin

if not Assigned(Dest) then

Dest := TBitmap.Create;

Dest.pixelformat := pf24bit;

Dest.Width := BMPWIDTH;

Dest.Height := BMPHEIGHT;

Dest.Canvas.CopyRect(Rect(0, 0, Dest.Width - 1, Dest.Height - 1), Source.Canvas, Rect(0, 0, Source.Width - 1, Source.Height - 1));

end;

2、图像灰度化

图像灰度化的方法有多种,这里介绍两种。一种是绝对平均值,一种是加权平均值。其实质就是将RGB三原色的色值相加,平均后赋予新值。不同的只是RGB三原色的权重不同。

绝对平均值

function Gray1(const Source: TBitmap): Boolean;

var

p : PByteArray;

w : Integer;

i, j : Integer;

begin

for i := 0 to Source.Height - 1 do

begin

p := Source.ScanLine[i];

for j := 0 to (Source.Width - 1) do

begin

w := p[3 * j] + p[3 * j + 1] + p[3 * j + 2];

w := w div 3;

w := byte(w);

p[3 * j] := w;

p[3 * j + 1] := w;

p[3 * j + 2] := w;

end;

end;

end;

加权平均值

function TForm1.Gray2(const Source: TBitmap): Boolean;

var

p : PByteArray;

w : Integer;

i, j : Integer;

begin

for i := 0 to Source.Height - 1 do

begin

p := Source.ScanLine[i];

for j := 0 to (Source.Width - 1) do

begin

w := (p[3 * j] * 28 + p[3 * j + 1] * 151 + p[3 * j + 2] * 77);

w := w div 3;

w := byte(w);

p[3 * j] := w;

p[3 * j + 1] := w;

p[3 * j + 2] := w;

end;

end;

end;

3、抽取直方图

由于是灰度图,所以只会有256种灰度值,计算直方图

function GetHisogram(const Source: TBitmap; var His: TSamp): Boolean; var

i, j, c : Integer;

p : PByteArray;

begin

try

//取样

for i := 0 to 255 do

His[i] := 0;

for i := 0 to Source.Height - 1 do

begin

p := Source.ScanLine[i];

for j := 0 to Source.Width - 1 do

begin

c := p^[j * 3];

Inc(His[c]);

end;

end;

finally

tb.Free;

end;

end;

4、判断相似度

这里采用的是一个公式,,g,s分别为两附图片的直方图,N为直方图抽样个数。

function GetSimilar(const HisA, HisB: TSamp): Double;

var

i, j : Integer;

function DivideAbs(const NumA, NumB: Integer): Double;

var

Tabs : Integer;

begin

Tabs := Abs(NumA - NumB);

if NumA >= NumB then

Result := NumA

else

Result := NumB;

if Result <> 0 then

Result := Tabs / Result;

end;

begin

Result := 0.0;

if Length(HisA) <> Length(HisB) then

Exit;

for i := 0 to Length(HisA) do

begin

Result := Result + 1 - DivideAbs(HisA[i], HisB[i]); end;

Result := Result / Length(HisA);

end;

相关文档
最新文档