ノーマライズ(ヒストグラムの引き伸ばし)のサンプルコード
画像に「ノーマライズ(ヒストグラムの引き伸ばし)」の処理をするサンプルです。ソースコードは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.
[ノーマライズ(ヒストグラムの引き伸ばし)の関数]
//-----------------------------------------------------------------------------
//■関数 EffectHistogramNormalize
//■用途 ノーマライズ(ヒストグラムの引き伸ばし)
//■引数 hBMP ...転送元のビットマップのハンドル
//■戻り値
// 新しいビットマップのハンドル
//-----------------------------------------------------------------------------
function EffectHistogramNormalize(hBMP:HBitmap):HBitmap;
var
Row,Col : Integer;
DestRow,SrcRow : pRGBArray;
SrcBitmap,DestBitmap:TBitmap ;
aMin,aMax : TRGBTriple;
R_ratio,G_ratio,B_ratio :Single;
begin
//------------------------------------------------------------------------------
//
// ――線形濃度変換――
//
// 原画像のヒストグラムにおける濃度の最小値をmin、最大値をmaxとしたとき、
// 次の式により変換する。
//
// (新しい濃度値)=255/max-min*(現画像の濃度値)
//------------------------------------------------------------------------------
SrcBitmap := TBitmap.Create;
DestBitmap:= TBitmap.Create;
SrcBitmap.handle := hBMP;
Set24bit(SrcBitmap,DestBitmap);
FillChar(aMin,Sizeof(TRGBTriple),255);
FillChar(aMax,Sizeof(TRGBTriple),0);
try
for Row := 0 to SrcBitmap.Height - 1 do
begin
SrcRow := SrcBitmap.Scanline[Row];
for Col := 0 to SrcBitmap.Width - 1 do
begin
// 最小値の入れ替え
if (SrcRow[Col].rgbtRed < aMin.rgbtRed) then aMin.rgbtRed :=SrcRow[Col].rgbtRed;
if (SrcRow[Col].rgbtGreen < aMin.rgbtGreen) then aMin.rgbtGreen :=SrcRow[Col].rgbtGreen;
if (SrcRow[Col].rgbtBlue < aMin.rgbtBlue) then aMin.rgbtBlue :=SrcRow[Col].rgbtBlue;
// 最大値の入れ替え
if (SrcRow[Col].rgbtRed > aMax.rgbtRed) then aMax.rgbtRed :=SrcRow[Col].rgbtRed;
if (SrcRow[Col].rgbtGreen > aMax.rgbtGreen) then aMax.rgbtGreen :=SrcRow[Col].rgbtGreen;
if (SrcRow[Col].rgbtBlue > aMax.rgbtBlue) then aMax.rgbtBlue :=SrcRow[Col].rgbtBlue;
end;
end;
R_ratio := 255 / (aMax.rgbtRed - aMin.rgbtRed);
G_ratio := 255 / (aMax.rgbtGreen - aMin.rgbtGreen);
B_ratio := 255 / (aMax.rgbtBlue - aMin.rgbtBlue);
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
// maxはMath.pasにあるのでuses節にMathを追加する
DestRow[Col].rgbtRed := Set255( Round(R_ratio * max( (SrcRow[Col].rgbtRed - aMin.rgbtRed ),0)) );
DestRow[Col].rgbtGreen := Set255( Round(G_ratio * max( (SrcRow[Col].rgbtGreen - aMin.rgbtGreen),0)) );
DestRow[Col].rgbtBlue := Set255( Round(B_ratio * max( (SrcRow[Col].rgbtBlue - aMin.rgbtBlue ),0)) );
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 :=
EffectHistogramNormalize(Image1.Picture.Bitmap.ReleaseHandle);
end;
スポンサーリンク
関連記事
公開日:2015年02月24日
記事NO:00280
プチモンテ ※この記事を書いた人
![]() | |
![]() | 💻 ITスキル・経験 サーバー構築からWebアプリケーション開発。IoTをはじめとする電子工作、ロボット、人工知能やスマホ/OSアプリまで分野問わず経験。 画像処理/音声処理/アニメーション、3Dゲーム、会計ソフト、PDF作成/編集、逆アセンブラ、EXE/DLLファイルの書き換えなどのアプリを公開。詳しくは自己紹介へ |
| 🎵 音楽制作 BGMは楽器(音源)さえあれば、何でも制作可能。歌モノは主にロック、バラード、ポップスを制作。歌詞は抒情詩、抒情的な楽曲が多い。楽曲制作は🔰2023年12月中旬 ~ | |









