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

輪郭のトレースのサンプルコード(画像フィルター)

画像に「輪郭のトレース」の処理をするサンプルです。ソースコードはDelphi5で作成しましたがその他の言語でも流用できるかと思います。

画像処理の結果

輪郭のトレースをすると下図のようになります。

画像フィルターのマスク

このフィルターのマスクは下図になります。

※マスク以外にも各RGB値に240を加算しています。

ソースコード

[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.

[輪郭のトレースの関数]

//-----------------------------------------------------------------------------
//■関数     EffectEdge_Trace
//■用途     輪郭のトレース
//■引数     hBMP             ... 転送元のビットマップのハンドル
//-----------------------------------------------------------------------------
function EffectEdge_Trace(hBMP: HBitmap):HBitmap;
var
  SrcBitmap,DestBitmap : TBitmap;
  DestRow    : pRGBArray;
  SourceRows : PPBits;
  MaskBits : array [0..8] of SmallInt;
  Row,Col,yRow,xCol,x,y,R,G,B,iMask: Integer;
begin

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

  // 係数
  MaskBits[0] :=-4 ;    MaskBits[1] :=-2 ;  MaskBits[2] :=-4 ;
  MaskBits[3] :=-1 ;    MaskBits[4] :=24 ;  MaskBits[5] :=-1 ;
  MaskBits[6] :=-4 ;    MaskBits[7] :=-2 ;  MaskBits[8] :=-4 ;

  GetMem(SourceRows, SrcBitmap.Height * SizeOf(pRGBArray));
  try

    for Row:= 0 to SrcBitmap.Height - 1 do  SourceRows[Row] := SrcBitmap.Scanline[Row];

    for Row := 0 To SrcBitmap.Height-1   do
    begin
         DestRow:=DestBitmap.ScanLine[Row];
         for Col := 0 To SrcBitmap.Width-1 do
         begin
            //-------------
            // 0 - 1 - 2
            //-------------
            // 3 -   - 4
            //-------------
            // 5 - 6 - 7

            iMask:=0;
            R:=0;G:=0;B:=0;
            for y:= -1 to 1 do
            begin
              for x:= -1 to 1 do
              begin

                 //Y軸
                 if (Row+ y ) > SrcBitmap.Height-1 then yRow:=SrcBitmap.Height-1
                 else if Row+(y) < 0               then yRow:=0
                 else                                   yRow:=Row+(y);

                 //X軸
                 if      Col+(x) > SrcBitmap.Width-1  then  xCol:=SrcBitmap.Width-1
                 else if Col+(x) < 0                  then  xCol:=0
                 else    xCol:=Col+(x);

                  R := R + SourceRows[yRow][xCol].rgbtRed   * MaskBits[iMask];
                  G := G + SourceRows[yRow][xCol].rgbtGreen * MaskBits[iMask];
                  B := B + SourceRows[yRow][xCol].rgbtBlue  * MaskBits[iMask];
                  inc(iMask);
              end;
            end;

            DestRow[Col].rgbtRed   :=Set255(R+240) ;
            DestRow[Col].rgbtGreen :=Set255(G+240) ;
            DestRow[Col].rgbtBlue  :=Set255(B+240) ;
         end;
    end;

    FreeMem(SourceRows); SourceRows:=nil;
    Result :=DestBitmap.ReleaseHandle;

  except
     if Assigned(SourceRows) then FreeMem(SourceRows);
     Result :=SrcBitmap.ReleaseHandle;
  end;
  SrcBitmap.Free ;
  DestBitmap.Free;
end;

[関数の呼び出し]

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





関連記事



公開日:2015年02月25日
記事NO:00301