delphi图像灰度化处理

时间:2022-10-14 04:55:54

一、图像的灰度化处理的基本原理

将彩色图像转化成为灰度图像的过程称为图像的灰度化处理。彩色图像中的每个像素的颜色有R、G、B三个分量决定,而每个分量有255个中值可取,这样一个像素点可以有1600多万(255*255*255)的颜色的变化范围。而灰度图像是R、G、B三个分量相同的一种特殊的彩色图像,其一个像素点的变化范围为255种,所以在数字图像处理中一般先将各种格式的图像转变成灰度图像以使后续的图像的计算量变得少一些。灰度图像的描述与彩色图像一样仍然反映了整幅图像的整体和局部的色度和亮度等级的分布和特征。图像的灰度化处理可用两种方法来实现。

第一种方法是求出每个像素点的R、G、B三个分量的平均值,然后将这个平均值赋予给这个像素的三个分量。

第二种方法是根据YUV的颜色空间中,Y的分量的物理意义是点的亮度,由该值反映亮度等级,根据RGB和YUV颜色空间的变化关系可建立亮度Y与R、G、B三个颜色分量的对应:Y=0.3R+0.59G+0.11B,以这个亮度值表达图像的灰度值。
下面是我的代码:

主窗体的代码:
unit u_main;

interface

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

type
  TF_Main = class(TForm)
    img1: TImage;
    btnSelect: TButton;
    dlgOpen1: TOpenDialog;
    btnConvertYUV: TButton;
    btnConvertRGB: TButton;
    procedure btnSelectClick(Sender: TObject);
    procedure btnConvertYUVClick(Sender: TObject);
    procedure btnConvertRGBClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  F_Main: TF_Main;
  displayFrm:TF_Convert;

implementation

{$R *.dfm}

procedure TF_Main.btnConvertRGBClick(Sender: TObject);
begin
  btnConvertYUVClick(Sender);
end;

procedure TF_Main.btnConvertYUVClick(Sender: TObject);
begin
  with TF_Convert.Create(Self) do
  begin
    if TButton(Sender).Name='btnConvertYUV' then
    begin
      showType:=true;
      ShowMessage('采用这样转换方式:计算方式'+#13+
                  'YUV=0.3R+0.59G+0.11B,新像素点的颜色值:'+#13+
                  'newR=newG=newB=byte(YUV)');
    end
    else
    if TButton(Sender).Name='btnConvertRGB' then
    begin
      showType:=False;
      ShowMessage('采用这样转换方式:计算方式'+#13+
                  'tmp=(R+G+B)/3,新像素点的颜色值:'+#13+
                  'newColor=RGB(tmp,tmp,tmp)');
    end;
    Caption:=TButton(Sender).Name;
    Show;
  end;
end;

procedure TF_Main.btnSelectClick(Sender: TObject);
var
  img:TImage;
begin
  if dlgOpen1.Execute then
  begin
    img1.Picture.LoadFromFile(dlgOpen1.FileName);
    if SameText(ExtractFileExt(dlgOpen1.FileName),'.jpg') then //转换jpg成bmp
    begin
      try
        img:=TImage.Create(Self);
        img.Picture.Bitmap.Assign(img1.Picture.Graphic);
        img1.Picture.Assign(img.Picture);
        img1.Refresh;
      finally
        img.Free;
      end;
    end; 
  end;
   
end;

procedure TF_Main.FormShow(Sender: TObject);
begin
  img1.Picture.Bitmap.LoadFromResourceName(0,'Jay');
end;

end.

显示转换图像的窗体:
unit U_Convert;

interface

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

type
  PByteArray = ^TByteArray;
  TByteArray = array[0..32767] of Byte;


  TF_Convert = class(TForm)
    img1: TImage;
    procedure FormShow(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
    changeBmp,testBmp:TBitmap;

  public
    showType:Boolean;
    { Public declarations }
  end;

var
  F_Convert: TF_Convert;

implementation
uses
  u_main;

{$R *.dfm}

procedure TF_Convert.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action:=caFree;
end;

procedure TF_Convert.FormCreate(Sender: TObject);
begin
  if not Boolean(changeBmp) then
    changeBmp:=TBitmap.Create;
  if not Boolean(testBmp) then
    testBmp:=TBitmap.Create;
end;

procedure TF_Convert.FormDestroy(Sender: TObject);
begin
  if Boolean(changeBmp) then
    FreeAndNil(changeBmp );
  if Boolean(testBmp) then
    FreeAndNil(testbmp);
end;

procedure TF_Convert.FormShow(Sender: TObject);
var
  p:PByteArray;
  gray,x,y:Integer;
begin
  try
    testBmp.Assign(F_Main.img1.Picture);//对象赋值
    if showType then
    begin
      for y := 0 to testBmp.Height - 1 do
      begin
        p:=testBmp.ScanLine[y];
        for x := 0 to testBmp.Width - 1 do
        begin
          gray:=Round(0.3* p[3*x+2]+ 0.59* p[3*x+1]+ 0.11*p[3*x]);//y=0.3R+0.59G+0.11B
          //设置新点的颜色值
          p[3*x+2]:=Byte(gray);
          p[3*x+1]:=Byte(gray);
          p[3*x  ]:=Byte(gray);
        end;
      end;
    end
    else
    begin
      for y := 0 to testBmp.Height - 1 do
      begin
        p:=testBmp.ScanLine[y];
        for x := 0 to testBmp.Width - 1 do
        begin
          gray:=Round((p[3*x+2]+p[3*x+1]+p[3*x])/3);//(r+g+b)/3
          p[3*x+2]:=gray;
          p[3*x+1]:=gray;
          p[3*x  ]:=gray;
        end; 
      end; 
    end; 
 
    changeBmp.Assign(testBmp);
    //显示
    img1.Picture.Assign(changeBmp);
    img1.Refresh;
  except
    ShowMessage('格式转换错误');
  end; 
end;

end.
2个窗体的窗体文件:

object F_Main: TF_Main
  Left = 0
  Top = 0
  Caption = 'MainForm'
  ClientHeight = 458
  ClientWidth = 426
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnShow = FormShow
  PixelsPerInch = 96
  TextHeight = 13
  object img1: TImage
    Left = 0
    Top = 0
    Width = 425
    Height = 417
  end
  object btnSelect: TButton
    Left = 343
    Top = 425
    Width = 75
    Height = 25
    Caption = #36873#25321#22270#29255
    TabOrder = 0
    OnClick = btnSelectClick
  end
  object btnConvertYUV: TButton
    Left = 0
    Top = 425
    Width = 75
    Height = 25
    Caption = #36716#25442'YUV'
    TabOrder = 1
    OnClick = btnConvertYUVClick
  end
  object btnConvertRGB: TButton
    Left = 81
    Top = 425
    Width = 75
    Height = 25
    Caption = #36716#25442'RGB'
    TabOrder = 2
    OnClick = btnConvertRGBClick
  end
  object dlgOpen1: TOpenDialog
    Filter = 'bmp|*.bmp|jpeg|*.jpg'
    Left = 256
    Top = 424
  end
end
-------------------------------------------------------------------------------------------------------
object F_Convert: TF_Convert
  Left = 0
  Top = 0
  AutoSize = True
  Caption = 'F_Convert'
  ClientHeight = 500
  ClientWidth = 400
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnClose = FormClose
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  OnShow = FormShow
  PixelsPerInch = 96
  TextHeight = 13
  object img1: TImage
    Left = 0
    Top = 0
    Width = 400
    Height = 500
    Align = alCustom
    AutoSize = True
    Stretch = True
  end
end