掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
ビットマップのデータで骨組みを取得するには (ID:24239)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
元ネタは、「C言語で学ぶ実践画像処理」 HPは http://www.silphix.com/kaiba/image/4/ にありました。最後の Hilditchの方法による二値画像の細線化例 のところです。 以下長いですがCからの移植コード。 ボタン1つとイメージ2つを貼って、細線化したいビットマップを用意します。 ---------------------- unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Math; type TRGBTripleArray = array[0..High(Integer) div 3 - 1] of RGBTRIPLE; PRGBTripleArray = ^TRGBTripleArray; //配列型のポインタ Tarray2d = array of array of Integer; TForm1 = class(TForm) Button1: TButton; Image1: TImage; Image2: TImage; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private 宣言 } public { Public 宣言 } procedure thinning( var image_in , image_out : Tarray2d); function cconc( inb : array of Integer ): Integer; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin Image1.Picture.LoadFromFile('gray002.bmp'); //適当にbmpのファイルをアサインすること end; function TForm1.cconc ( inb : array of Integer ) : Integer; var i, icn :Integer; begin icn := 0; i := 0; while( i < 8) do begin if (inb[i] = 0)then begin if (inb[i+1] = 255) or (inb[i+2] = 255)then begin Inc(icn); end; end; Inc(i,2); end; Result:= icn; end; procedure TForm1.thinning( var image_in , image_out : Tarray2d); var i, ix, iy, m, ir, iv, iw :Integer; ia ,ic : array[0..8] of Integer; X_SIZE, Y_SIZE :Integer; begin image_out := image_in; X_SIZE := High(image_in[0]) +1; Y_SIZE := High(image_in ) +1; m := 100; ir := 1 ; while (ir <> 0)do begin ir := 0; for iy := 1 to Y_SIZE-1 -1 do begin for ix := 1 to X_SIZE-1 -1 do begin if (image_out[iy][ix] <> 255)then continue; ia[0] := image_out[iy ][ix+1]; ia[1] := image_out[iy-1][ix+1]; ia[2] := image_out[iy-1][ix ]; ia[3] := image_out[iy-1][ix-1]; ia[4] := image_out[iy ][ix-1]; ia[5] := image_out[iy+1][ix-1]; ia[6] := image_out[iy+1][ix ]; ia[7] := image_out[iy+1][ix+1]; for i := 0 to 8 -1 do begin if (ia[i] = m)then begin ia[i] := 255; ic[i] := 0; end else begin if (ia[i] < 255)then ia[i] := 0; ic[i] := ia[i]; end; end; ia[8] := ia[0]; ic[8] := ic[0]; if (ia[0]+ia[2]+ia[4]+ia[6] = 255*4)then continue; iv := 0; iw := 0; for i := 0 to 8 -1 do begin if (ia[i] = 255)then Inc(iv); if (ic[i] = 255)then Inc(iw); end; if (iv <= 1)then continue; if (iw = 0 )then continue; if (cconc(ia) <> 1)then continue; if (image_out[iy-1][ix] = m)then begin ia[2] := 0; if (cconc(ia) <> 1)then continue; ia[2] := 255; end; if (image_out[iy][ix-1] = m)then begin ia[4] := 0; if (cconc(ia) <> 1)then continue; ia[4] := 255; end; image_out[iy][ix] := m; Inc(ir); end; end; Inc(m); end; for iy := 0 to Y_SIZE-1 do begin for ix := 0 to X_SIZE-1 do begin if (image_out[iy,ix] < 255)then image_out[iy,ix] := 0; end; end; end; procedure TForm1.Button1Click(Sender: TObject); var Ps0, Ps1: PRGBTripleArray; thBMP: TBitMap; x ,y,d:Integer; image_in : Tarray2d; image_out : Tarray2d; begin thBMP := TBitMap.Create; thBMP.PixelFormat := pf24bit; Image1.Picture.Bitmap.PixelFormat := pf24bit; thBMP.Width := Image1.Picture.Bitmap.Width; thBMP.Height := Image1.Picture.Bitmap.Height; Setlength( Image_in , thBMP.Height,thBMP.Width ); Setlength( Image_out , thBMP.Height,thBMP.Width ); //水平のみ処理 for y := 0 to Image1.Picture.Bitmap.Height - 1 do begin Ps0 := Image1.Picture.Bitmap.ScanLine[y]; for x:= 0 to Image1.Picture.Bitmap.Width -1 do // begin d := Ps0[x].rgbtGreen; //適当にGrennのデータ if d <128 then d:=0 else d:=255; image_in[y,x] := d; end; end; thinning(image_in, image_out); for y := 0 to thBMP.Height - 1 do begin Ps0 := thBMP.ScanLine[y]; for x:=0 to thBMP.Width -1 do begin Ps0[x].rgbtRed := image_out[y,x]; Ps0[x].rgbtGreen := image_out[y,x]; Ps0[x].rgbtBlue := image_out[y,x]; end; end; Image2.Picture.Bitmap.Assign(thBMP); thBMP.free; end; end.
←解決時は質問者本人がここをチェックしてください。
更新する
戻る
掲示板システム
Copyright 2021 Takeshi Okamoto All Rights Reserved.