擬似カラー

 疑似カラーは、山の高さ表示や、温度分布の表示など、本来は色の無いものに、色を付けて表示かる方法です。

 360°のカラーリングを用いると、最高の値と、最低の値が同じ色になってしまうので、青から赤までの色を使用するのが一般的です。
温度の場合は、 最低の値が純粋な青で、最大値が純粋な赤とします。
HLSカラーBluetoRed

画像の場合、一端モノクロームのグレイスケール画像にしてから、上図右の様な配分で色付けをします。
青が一番小さい値で、赤を大きくするのは、人の色に対する感覚を利用したものです。
もし、緑化を表す場合は、純赤を一番小さくして、純緑を一番大きな値にするのが良いと思われます。
必要に応じて、色の組み合わせを変えたほうが良いでしょう。

グレイスケールと色の関係を示すカラーバーです。
カラーバー

下の図は、上のカラーバーの条件で、グレイスケール画像に色付けをしたものです。

疑似カラー図

この方法は、一般的な写真には使用それませんが、測定器のデーターを二次元で表示する場合に、よく使用される方法です。

サンプルプログラム

unit PseudoColor;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.ExtDlgs;

type
  TForm1 = class(TForm)
    FileOpenBtn: TButton;
    Image1: TImage;
    GrayBtn: TButton;
    Image2: TImage;
    Image3: TImage;
    OpenPictureDialog1: TOpenPictureDialog;
    Pseudo_ColorBtn: TButton;
    SorceBtn: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FileOpenBtnClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure GrayBtnClick(Sender: TObject);
    procedure Pseudo_ColorBtnClick(Sender: TObject);
    procedure SorceBtnClick(Sender: TObject);
  private
    { Private 宣言 }
    procedure MakeTemp;                   // カラーテンプレート作成
    procedure MonoColorBar;               // モノクロカラーバー
    procedure ColorBar;                   // カラーバー
    procedure ConvertGray;                // グレースケール変換
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

// ファイル拡張子設定
const
  OpenFileFilter =
    '画像ファイル|*.png;*.jpg;*.gif;*.bmp;*.tif;*.ico;*.wdp'+
    '|*.png|*.png' +
    '|*.jpg|*.jpg' +
    '|*.gif|*.gif' +
    '|*.bmp|*.bmp' +
    '|*.tif|*.tif' +
    '|*.ico|*.ico' +
    '|*.wdp|*.wdp';

  kr  = 0.299;                     // R 輝度変換係数
  kg  = 0.587;                     // G 輝度変換係数
  kb  = 0.114;                     // B 輝度変換係数

var
  ColorTemp : array[0..255] of TColor;          // カラーテンプレート
  GrayScale : array of array of Byte;
  InBitmap        : TBitmap;                    // ビットマップ
  OutBitmap       : TBitmap;
  GHeight, GWidth : integer;                    // ソース画像サイズ
  VRect           : Trect;                      // 表示サイズ設定用

type
  TPrgbarry = array[0..0] of Trgbtriple;      // 24ビットカラーレコード 32ビット用はTRGBQuadArray
  Prgbarray  = ^TPrgbarry;                    // ポインター
                                              // 配列のポインターが必要なだけなので、長さは1 [0..0]で問題ありません。
//======================
// グレースケール変換
//======================
procedure TForm1.ConvertGray;
var
  PB    : Prgbarray;
  X, Y  : Integer;
begin
  for Y := 0 to GHeight - 1 do begin
    PB := InBitmap.ScanLine[Y];
    for X := 0 to GWidth -1 do
      GrayScale[Y, X] := Round(PB[X].rgbtBlue  * kb +
                               PB[X].rgbtGreen * kg +
                               PB[X].rgbtRed   * kr); // 輝度変換
  end;
end;

//==========================
// モノクロカラーバー 作成
//==========================
procedure TForm1.MonoColorBar;
var
  II: Integer;
  C : Integer;
begin
  for II := 0 to 255 do begin
    C := II * 256 * 256 + II * 256 + II;
    Image1.Canvas.Pen.Color := C;
    Image1.Canvas.MoveTo(II, 0);
    Image1.Canvas.LineTo(II, 30);
  end;
end;

//===============================
// グレイスケール表示
//===============================
procedure TForm1.GrayBtnClick(Sender: TObject);
var
  PB    : Prgbarray;
  X, Y  : Integer;
begin
  for Y := 0 to GHeight - 1 do begin
    PB := OutBitmap.ScanLine[Y];
    for X := 0 to GWidth -1 do begin
      PB[X].rgbtBlue  := GrayScale[Y, X];
      PB[X].rgbtGreen := GrayScale[Y, X];
      PB[X].rgbtRed   := GrayScale[Y, X];
    end;
  end;
  Image3.Canvas.StretchDraw(VRect, OutBitmap);              // 出力枠に変倍出力
end;

//================================
// 擬似カラー表示
//================================
procedure TForm1.Pseudo_ColorBtnClick(Sender: TObject);
var
  PB    : Prgbarray;
  X, Y  : Integer;
  TC    : TColor;
begin
  for Y := 0 to GHeight - 1 do begin
    PB := OutBitmap.ScanLine[Y];
    for X := 0 to GWidth -1 do begin
      TC := ColorTemp[GrayScale[Y, X]];
      PB[X].rgbtBlue  := GetBValue(TC);
      PB[X].rgbtGreen := GetGValue(TC);
      PB[X].rgbtRed   := GetRValue(TC);
    end;
  end;
  Image3.Canvas.StretchDraw(VRect, OutBitmap);              // 出力枠に変倍出力
end;

//============================
// 元画像表示
//============================
procedure TForm1.SorceBtnClick(Sender: TObject);
begin
  Image3.Canvas.StretchDraw(VRect, InBitmap);              // 出力枠に変倍出力
end;

//=========================
// カラーバー  作成
//=========================
procedure TForm1.ColorBar;
var
  II : Integer;
begin
  for II := 0 to 255 do begin
    Image2.Canvas.Pen.Color := ColorTemp[II];
    Image2.Canvas.MoveTo(II, 0);
    Image2.Canvas.LineTo(II, 30);
  end;
end;

//============================
// カラーテンプレート作成
//============================
procedure TForm1.MakeTemp;
var
  II      : Integer;
  R, B, G : Integer;
begin
  for II := 0 to 255 do begin
    B := 0;                                     // RGB初期化
    G := 0;
    R := 0;
    if II <= 63 then begin                      // II 0~63
      B := 255;
      G := II * 4;
    end;
    if (II >= 64) and (II <= 127) then begin    // II 64~127
      B := (255 - (II - 64) * 4);
      G := 255;
    end;
    if (II >= 128) and (II <= 191) then begin   // II 128~191
      G := 255;
      R := (II - 128) * 4;
    end;
    if (II >= 192) then begin                   // II 192~255
      G := (255 - (II - 192) * 4);
      R := 255;
    end;
    B := B shl 16;                              // 左シフト16bit
    G := G shl  8;                              // 左シフト 8bit
    ColorTemp[II] := B + G + R;                 // 三色加算
  end;
end;

//====================================
// 画像ファイルのオープン
//====================================
procedure TForm1.FileOpenBtnClick(Sender: TObject);
var
  WIC         : TWICImage;
  InFilename  : String;
  IHeight     : Integer;
  IWidth      : Integer;
begin
  OpenPictureDialog1.Filter := OpenFileFilter;              // ファイルオープンフィルターの設定
  if OpenPictureDialog1.Execute then                        // ファイルが指定されたら
    begin
      WIC := TWICImage.Create;                              // TWICImageの生成
      try
        InFilename := OpenPictureDialog1.FileName;          // ファイル名の取得
        WIC.LoadFromFile(InFilename);                       // 画像の読み込み
        GHeight := WIC.Height;                              // 画像高さ取得
        GWidth  := WIC.Width;                               // 画像幅
        IWidth  := Image3.Width;                            // 出力先イメージ1の幅
        IHeight := Image3.Height;                           // 出力先イメージ1の高さ
        if GHeight <= GWidth then begin                     // 縦横比により出力サイズ設定
          IHeight := Round(IWidth * GHeight / GWidth);
        end
        else
        begin
          IWidth := Round(IHeight * GWidth / GHeight);
        end;
        VRect := Rect(0, 0, IWidth, IHeight);               // 出力枠設定
        InBitmap.Assign(WIC);
      finally
        WIC.Free;                                           // TWICImage 解放
      end;
      InBitmap.PixelFormat  := pf24bit;
      Image3.Canvas.StretchDraw(VRect, InBitmap);           // 出力枠に変倍出力
      setlength(GrayScale, GHeight, GWidth);
      OutBitmap.PixelFormat := pf24bit;
      OutBitmap.Height := GHeight;
      OutBitmap.Width  := GWidth;
    end
    else Exit;
  ConvertGray;                                              // グレースケール変換
  GrayBtn.Enabled := True;
  Pseudo_ColorBtn.Enabled := True;
  SorceBtn.Enabled := True;
end;

//=================
// 初期設定
//=================
procedure TForm1.FormCreate(Sender: TObject);
var
  Bitmap : Tbitmap;
begin
  top := (Screen.Height - Height) div 2;
  left := (Screen.Width - Width) div 2;
  Image1.Width := 256;
  Image1.Height := 30;
  Image2.Width := Image1.Width;
  Image2.Height := Image1.Height;
  Image3.Width := 256;
  Image3.Height := 256;
  Bitmap := Tbitmap.Create;                       // 初期化用ビットマップ生成
  Bitmap.Width := Image1.Width;
  Bitmap.Height := Image1.Height;
  Image1.Picture.Bitmap := Bitmap;
  Image2.Picture.Bitmap := Bitmap;
  Bitmap.Free;                                    // 初期化用ビットマップの破棄
  Image1.Picture.Bitmap.PixelFormat := pf24bit;
  Image2.Picture.Bitmap.PixelFormat := pf24bit;
  MakeTemp;                                       // カラーテンプレート作成
  MonoColorBar;                                   // モノクロカラーバー
  ColorBar;                                       // カラーバー
  InBitmap  := TBitmap.Create;                    // ビットマップ生成
  OutBitmap := TBitmap.Create;
  GrayBtn.Enabled := False;                       // ボタンの設定
  Pseudo_ColorBtn.Enabled := False;
  SorceBtn.Enabled := False;
end;

//==================================
// 終了処理 作業用ビットマップの開放
//==================================
procedure TForm1.FormDestroy(Sender: TObject);
begin
  InBitmap.Free;
  OutBitmap.Free;
end;

end.

 カラーテンプレートの作成の簡素化
 Delphi Xe3 以降には、HSLtoRGB の変換メソッドが用意されているので、それを利用すれば簡単に擬似カラーパターンを作成することが出来ます。
変換テンプレートを使用せず、直接変換しても良いのですが、配列のサイズは4バイトデーターを256個用意するだけなのと、高速に擬似カラー化する為にテンプレートを使用するのが一番です。
前記サンプルプログラムの、MakeTemp ルーチンを下記の様に修正すれば、擬似カラーパターンの作成が簡単になります。
Uses節に System.UITypes, System.UIConsts の追加が必要です。
 下記のHsは、値 255 を 色相の240°に変換する為の係数です。
240の値を変更すれば、値 255に対する色相角度を変更することが出来ます。
HSLtoRGB(色相, 彩度, 明度) で、色相の0~360°は 0~1 彩度は 0~1 明度は0~1 で 0.5 が純色となります。
TAlphaColor,HSLToRGBは、FireMonkey 用に追加された物のようですが、VCLでも使用できます。

//==============================================================
// カラーテンプレート作成
// Hs は HSLtoRGB 変換時 値255 を 240度赤純色にするための補正値
// TAlphaColorはUsesにSystem.UITypesが
// HSLToRGB()にはUsesにSystem.UIConstsが必要です
//==============================================================
procedure TForm1.MakeTemp;
const
  Hs = 240 / 360 / 255;
var
  II      : Integer;
  C       : TAlphaColor;
begin
  for II := 0 to 255 do begin
    C := HSLToRGB(II * Hs, 1, 0.5);
    ColorTemp[II] := C and $00FFFFFF;
  end;
end;


    download Pseudo.zip

画像処理一覧へ戻る

      最初に戻る