TOP > カテゴリ > 画像処理工学 >

イコライズ(ヒストグラムの平均化)のサンプルコード

画像に「イコライズ(ヒストグラムの平均化)」の処理をするサンプルです。ソースコードはDelphi5で作成しましたがその他の言語でも流用できるかと思います。

画像処理の結果

イコライズ(ヒストグラムの平均化)をすると下図のようになります。

ヒストグラムの結果

イコライズの処理前と処理後のヒストグラムです。

ソースコード

[EffectBass.pas - 汎用モジュール]

//Bass Unit
unit EffectBass;

interface
uses
 Windows,SysUtils, Classes, Graphics;

type
 //24bitアクセス用ポインタ
 pRGBarray  = ^TRGBarray;
 TRGBarray  = array[0..0] of TRGBTriple; //None リテラル

type
 //24bitアクセス用ダブルポインタ
 PPBits = ^TPBits;
 TPBits = array[0..0] of pRGBarray; //None リテラル

//汎用プロシージャ
procedure Set24bit(Src,Dest :TBitmap);
function  Set255(Value : integer) : BYTE;

implementation


/////////
procedure Set24bit(Src,Dest :Tbitmap);
begin
  Src.PixelFormat :=pf24bit;
  Dest.PixelFormat:=pf24bit;
  Dest.Width:=Src.Width;
  Dest.Height:=Src.Height;
end;

/////////
function Set255(Value:Integer):Byte;
begin
 if Value>=255 then
  Result:=255
 else if Value<=0 then
 Result:=0
 else Result:=Value;
end;
end.

[イコライズ(ヒストグラムの平均化)の関数]

//-----------------------------------------------------------------------------
//■関数     EffectHistogramEqualize
//■用途     イコライズ(ヒストグラムの平均化)
//■引数     hBMP             ...転送元のビットマップのハンドル
//■戻り値
//            新しいビットマップのハンドル
//-----------------------------------------------------------------------------
function  EffectHistogramEqualize(hBMP:HBitmap):HBitmap;
var
  i,Row,Col      : Integer;
  DestRow,SrcRow : pRGBArray;
  SrcBitmap,DestBitmap : TBitmap  ;
  RGB_Count : array [0..255] of Dword;
  R_Table : array[0..255] of Byte;
  G_Table : array[0..255] of Byte;
  B_Table : array[0..255] of Byte;
  j, HistTotal : Dword;
  n : Dword;
begin

  // RGBの輝度ではなくHSVなどの明度でも良いかも

  SrcBitmap := TBitmap.Create;
  DestBitmap:= TBitmap.Create;
  SrcBitmap.handle := hBMP;
  Set24bit(SrcBitmap,DestBitmap);

  ZeroMemory(@RGB_count,4*256);

  // 一定値を求める
  n := ((SrcBitmap.Width * SrcBitmap.Height) div 256) + 1;

  try

    // 全ての濃度をヒストグラムにする
    for Row := 0 to SrcBitmap.Height - 1 do
    begin
      SrcRow  := SrcBitmap.Scanline[Row];
      for Col := 0 to SrcBitmap.Width - 1 do
          Inc(RGB_count[( SrcRow[Col].rgbtRed  +
                          SrcRow[Col].rgbtgreen+
                          SrcRow[Col].rgbtBlue  ) div 3]);
    end;

    // 平均化のための変換テーブルの作成

    // 赤
    HistTotal :=0; j :=0;

    for i := 0 to 255 do
    begin
         // 1
         HistTotal  := HistTotal + RGB_count[i];
         j  := j+(HistTotal div n);
         HistTotal  := HistTotal mod n ;
         R_Table[i] := j;
    end;

    // 緑
    HistTotal :=0;  j:=0;

    for i := 0 to 255 do
    begin
         HistTotal  := HistTotal +RGB_count[i];
         j          := j+(HistTotal div n);
         HistTotal  := HistTotal mod n;
         G_Table[i] := j;
    end;

    // 青
    HistTotal :=0; j :=0;

    for i := 0 to 255 do
    begin
         HistTotal  := HistTotal +RGB_count[i];
         j          := j+(HistTotal div n);
         HistTotal  := HistTotal mod n;
         B_Table[i] := j;
    end;

    // 値の再割り当て
    for Row := 0 to SrcBitmap.Height - 1 do
    begin
      SrcRow  := SrcBitmap.Scanline[Row];
      DestRow := DestBitmap.Scanline[Row];
      for Col := 0 to SrcBitmap.Width - 1 do
      begin
         DestRow[Col].rgbtRed   := R_Table[SrcRow[Col].rgbtRed];
         DestRow[Col].rgbtGreen := G_Table[SrcRow[Col].rgbtGreen];
         DestRow[Col].rgbtBlue  := B_Table[SrcRow[Col].rgbtBlue];
      end;
    end;

  Result :=DestBitmap.ReleaseHandle;

  except
     Result :=SrcBitmap.ReleaseHandle;
  end;
  
  SrcBitmap.Free ;
  DestBitmap.Free;
end;

[関数の呼び出し]

procedure TForm1.Button1Click(Sender: TObject);
begin
    Image1.Picture.Bitmap.Handle :=
      EffectHistogramEqualize(Image1.Picture.Bitmap.ReleaseHandle);
end;





掲示板

ソフトウェア、ハードウェアのプログラミング用の掲示板を作成しました。質問やわからない事は@掲示板でユーザー同士で情報を共有して下さい。

関連記事



公開日:2015年02月24日
記事NO:00279