图像相似度算法

更新时间:2023-03-18 23:54:01 阅读量: 人文社科 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

一种图像相似度匹配的算法,

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;

本文来源:https://www.bwwdw.com/article/iofj.html

Top