金子邦彦研究室プログラミングOctave の活用2次元の図形要素を2値画像データとして描画

2次元の図形要素を2値画像データとして描画

2次元の図形要素を2値画像データとして描画する Octave のプログラム例を示す.

前準備

Octave のインストールが済んでいること.

必見 Web ページ: http://www.csse.uwa.edu.au/~pk/Research/MatlabFns/

必見 Web ページ: http://www.eecs.berkeley.edu/Research/Projects/CS/vision/bsds/

※ プロンプトを変えたいときは,次のように操作する.

PS1('> ')

※ Octave のインストールによっては,Octave の起動時に毎回次の操作を行う必要があるかもしれない

pkg load image

プログラムのソースコード

function A = intersect_X ( px, vx, val )
# 点 (px,py) を通過するベクトル(xv,vy) が x = val と交わる交点について.
# px + A * vx = val となるような A を求める
  if ( abs( vx ) < 0.0001 )
    A = NaN;
  else
    A = (val - px) / vx;
  endif
endfunction

function A = intersect_Y ( py, vy, val )
# 点 (px,py) を通過するベクトル(xv,vy) が y = val と交わる交点について.
# py + A * vy = val となるような A を求める
  if ( abs( vy ) < 0.0001 )
    A = NaN;
  else
    A = (val - py) / vy ;
  endif
endfunction

function AA = intersect_rectangle ( px, py, vx, vy, width, height )
# 点 (px,py) を通過するベクトル(xv,vy) がなす軌跡 (px,py) + A * (xv,vy) と
# 左上 (1,1), 右下 (width, height) である長方形と交点(2つ)について,その交点における A の値を求める
  # 4 本の直線との交点
  a1 = intersect_X( px, vx, 1 );
  a2 = intersect_X( px, vx, width );
  a3 = intersect_Y( py, vy, 1 );
  a4 = intersect_Y( py, vy, height );
  A = [a1 a2 a3 a4];

  # a1, a2, a3, a4 の中で正であり、最小のもの
  e1 = min( A( find( A > 0 ) ) );

  # a1, a2, a3, a4 の中で負であり、最大のもの
  e2 = max( A( find( A < 0 ) ) );
 
  AA = [e1 e2];
endfunction

function mask = draw_linesegment ( x1, y1, x2, y2, width, height )
# 2端点を指定しての線分の描画
# 左上 (1,1), 右下 (width, height) である画像に,線分 (x1, y1) - (x2, y2) を描く
  mask = poly2mask([x1 x2 x1], [y1 y2 y1], height, width);
endfunction

function mask = draw_linesegment_vectorform ( px, py, vx, vy, width, height )
# 左上 (1,1), 右下 (width, height) である画像に,(px, py) を通過し,方向が (vx, vy) であるような線分を書く
  AA = intersect_rectangle( px, py, vx, vy, width, height );
  mask = draw_linesegment( px + (vx * AA(1)), py + (vy * AA(1)), px + (vx * AA(2)), py + (vy * AA(2)), width, height );
endfunction

function mask = draw_vector ( px, py, vx, vy, width, height )
# 左上 (1,1), 右下 (width, height) である画像に,線分 (x1, y1) - (x2, y2) を描く
  # (px, py) + (vx, vy) が画像からはみ出るか?
  AA = intersect_rectangle( px, py, vx, vy, width, height );
  if ( AA(1) > 1 )
    # はみ出ない
    mask = draw_linesegment( px, py, px + vx, py + vy, width, height );
  else
    mask = draw_linesegment( px, py, px + ( vx * AA(1) ), py + ( vy * AA(1) ), width, height );
  endif
endfunction

px = 140;
py = 250;
vx = 8;
vy = -12;

width = 512;
height = 512;

# 線分
mask = draw_linesegment_vectorform(px, py, vx, vy, width, height);
imshow( mask );
w = input("please press Enter to proceed");

# ベクトル
mask2 = draw_vector( px, py, vx, vy, width, height );
imshow( mask2 );
w = input("please press Enter to proceed");

実行方法と実行結果の例

  1. (オプション)Cygwin からリモートログインする場合
    startx
    xhost +
    ssh -X username@ipaddress
    
  2. ソースコードをファイルとして保存
  3. Octave を起動
  4. Octave の source コマンドを使って実行
    cd <ソースコードのファイルを置いたディレクトリ>
    source "<ソースコードのファイル名>"
    
  5. 実行が終わるまで数秒待つ
  6. 途中で何回か「please press Enter to proceed」と表示されるので,Enter キーを押す.

使用方法の説明

ここでのプログラムは,2値画像データ(2 次元の配列)に,2次元の図形要素を描画するもの.gnuplot と混同しないように.