⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uncrossentropy.pas.~2~

📁 这是我用Delphi和Matlab写的一个程序
💻 ~2~
字号:
unit unCrossEntropy;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, ExtDlgs;

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;
    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 + -