📄 uncrossentropy.pas.~4~
字号:
unit unCrossEntropy;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, ExtDlgs, Spin;
type
TfmCrossEntropy = class(TForm)
btnCal: TButton;
lblP: TLabel;
ImageI: TImage;
lblQ: TLabel;
lblI: TLabel;
btnLoadP: TButton;
btnLoadQ: TButton;
OpenPicDlgP: TOpenPictureDialog;
ScrollBoxP: TScrollBox;
ImageP: TImage;
ScrollBoxQ: TScrollBox;
ImageQ: TImage;
Image1: TImage;
lblE: TLabel;
editIpq: TEdit;
editErms: TEdit;
OpenPicDlgQ: TOpenPictureDialog;
SpinEdit1: TSpinEdit;
BakLbl: TLabel;
MarkLbl: TLabel;
procedure btnLoadPClick(Sender: TObject);
procedure btnLoadQClick(Sender: TObject);
procedure btnCalClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
fmCrossEntropy: TfmCrossEntropy;
implementation
{$R *.dfm}
procedure TfmCrossEntropy.btnLoadPClick(Sender: TObject);
begin
if OpenPicDlgP.Execute then
ImageP.Picture.LoadFromFile(OpenPicDlgP.Files[0]);
end;
procedure TfmCrossEntropy.btnLoadQClick(Sender: TObject);
begin
if OpenPicDlgQ.Execute then
ImageQ.Picture.LoadFromFile(OpenPicDlgQ.Files[0]);
end;
procedure TfmCrossEntropy.btnCalClick(Sender: TObject);
var
Y, X: Integer; // 循环变量
xi: array[0..255] of Integer; // 数组xi的下标表示图像的灰度可能取的值,即:0-255;
// 每个元素是图像中出现此灰度值的像素的个数
pi, qi: array[0..255] of Single; // 数组pi和qi中的每一个元素是图像各灰度值对应的概率,下标表示灰度值
Row, RowQ: PByteArray; // A line of pixels.
Gray: Integer; // 像素点的灰度值
Ipq: Single; // 交叉熵
Erms: Single; // 灰度均方根误差
Pij, Qij: Single; // 点(i, j)处的灰度值
ImgHeight, ImgFormat: bool;
oldImg, tImg: TBitmap;
right: Integer;
i: Integer;
Dir, data: string;
f: TextFile;
begin
Dir := ExtractFileDir(OpenPicDlgP.Files[0]);
//f:=Dir+'\data.txt';
AssignFile(f, Dir + '\data.txt');
if FileExists(Dir + '\data.txt') then
Append(f)
else
Rewrite(f);
for i := 0 to OpenPicDlgP.Files.Count - 1 do
begin
ImageP.Picture.LoadFromFile(OpenPicDlgP.Files[i]);
//判断打开的图像是否符合要求
ImgHeight := (ImageP.Height = 600) and (ImageQ.Height = 600);
ImgFormat := (ImageP.Picture.Bitmap.PixelFormat = pf24bit)
and (ImageQ.Picture.Bitmap.PixelFormat = pf24bit);
if ImgHeight and ImgFormat then
begin
oldImg := TBitmap.Create;
oldImg.Assign(ImageQ.Picture.Bitmap);
if ImageP.Width < ImageQ.Width then
begin
right := ImageQ.Width - ImageP.Width;
tImg := TBitmap.Create;
tImg.Width := ImageP.Width;
tImg.Height := ImageP.Height;
tImg.PixelFormat := ImageP.Picture.Bitmap.PixelFormat;
tImg.Canvas.CopyRect(Rect(0, 0, tImg.Width, tImg.Height), ImageQ.Picture.Bitmap.Canvas, Rect(right, 0, ImageQ.Width, ImageQ.Height));
ImageQ.Picture.Bitmap.Width := tImg.Width;
ImageQ.Picture.Bitmap.Assign(tImg);
tImg.Free;
end;
{ 计算交叉熵 }
{ 对图像P各灰度值的像素的个数进行统计 }
for Y := 0 to 255 do
xi[Y] := 0; // 初始化
with ImageP.Picture.Bitmap do
for Y := 0 to Height - 1 do
begin
Row := ScanLine[Y]; // 扫描一行
for X := 0 to Width - 1 do
begin
// values must be less than 256, so "Round" is used.
Gray := Round(Row[X * 3 + 2] * 0.3 + Row[X * 3 + 1] * 0.59 + Row[X * 3] * 0.11);
Inc(xi[Gray]);
// 变为灰度图
Row[X * 3 + 2] := Gray;
Row[X * 3 + 1] := Gray;
Row[X * 3] := Gray;
end;
end;
// 求图像P各灰度值对应的概率
for Y := 0 to 255 do
pi[Y] := xi[Y] / 480000;
// 重画图像P
ImageP.Repaint;
{ 对图像Q各灰度值的像素的个数进行统计 }
for Y := 0 to 255 do
xi[Y] := 0; // 初始化
with ImageQ.Picture.Bitmap do
for Y := 0 to Height - 1 do
begin
Row := ScanLine[Y]; // 扫描一行
for X := 0 to Width - 1 do
begin
// values must be less than 256, so "Round" is used.
Gray := Round(Row[X * 3 + 2] * 0.3 + Row[X * 3 + 1] * 0.59 + Row[X * 3] * 0.11);
Inc(xi[Gray]);
// 变为灰度图
Row[X * 3 + 2] := Gray;
Row[X * 3 + 1] := Gray;
Row[X * 3] := Gray;
end;
end;
// 求图像Q各灰度值对应的概率
for Y := 0 to 255 do
qi[Y] := xi[Y] / 480000;
// 重画图像Q
ImageQ.Repaint;
// 按公式计算交叉熵
Ipq := 0;
for Y := 0 to 255 do
if (pi[Y] <> 0) and (qi[Y] <> 0) then
Ipq := Ipq + pi[Y] * Ln(pi[Y] / qi[Y]);
{ 显示交叉熵 }
editIpq.Text := FloatToStr(Ipq);
{ 计算灰度均方根误差 }
Erms := 0; // 初始化
for Y := 0 to ImageP.Picture.Bitmap.Height - 1 do
begin
Row := ImageP.Picture.Bitmap.ScanLine[Y]; // 扫描一行
RowQ := ImageQ.Picture.Bitmap.ScanLine[Y];
for X := 0 to ImageP.Picture.Bitmap.Width - 1 do
begin
// 计算灰度值P(i,j)
Pij := Row[X * 3];
// 计算灰度值Q(i,j)
Qij := RowQ[X * 3];
Erms := Erms + Sqr(Pij - Qij);
end;
end;
Erms := Sqrt(Erms / (ImageP.Picture.Bitmap.Height * ImageP.Picture.Bitmap.Width));
{ 显示灰度均方根误差 }
editErms.Text := FloatToStr(Erms);
//data:=ExtractFileName(openPicDlgP.Files[i])+' '+ExtractFileName(openPicDlgQ.FileName)+': '+ FloatToStr(Ipq)+' '+ FloatToStr(Erms);
data := FloatToStr(Ipq) + ' ' + FloatToStr(Erms);
Writeln(f, data);
ImageQ.Width := oldImg.Width;
ImageQ.Picture.Bitmap.Assign(oldImg);
oldImg.Free;
end
else if (not ImgHeight) then
MessageDlg('Both Image P and Q must be 800*600!', mtError, [mbOk], 0)
else if (not ImgFormat) then
MessageDlg('Both Image P and Q must be 24bit!', mtError, [mbOk], 0)
end;
Flush(f);
CloseFile(f);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -