11_4:ml5.js SketchRNN 最初の線を描画する ml5.js JavaScript

SketchRNNモデルのgenerate()メソッドに渡したコールバック関数には、第2引数としてモデルの線の情報を持つオブジェクト(strokes)が渡されます。そのオブジェクトをconsole.log()で出力すると、たとえば次の結果が得られます。本稿ではこの情報を使って、モデルの最初の線を描きます。

{dx: -3.407123509643178, dy: 11.261730799932574, pen: “down”}

11_1:ml5.js SketchRNN」で引用した「絵を「描く」プロセスの模倣 – A Neural Representation of Sketch Drawings」には、次のように書かれています(一部省略)。

私達がペンを持って絵を描くとき、それは様々な軌跡の線(ストローク)で表現されます。そして、書き上げられた絵は実際の写真とは異なるものの、非常によく対象の特徴(ネコのひげ、人の顔、車の形など・・・)を捉えています。このプロセスを、機械学習により再現できないかという試みが「A Neural Representation of Sketch Drawings」です。その手法の中核となるのは、ストロークを生んでいる「ペンの状態」に着目し、その状態遷移を学習させるというアイデアです。
論文では、ペンの状態を以下のようにモデル化しています。

「A Neural Representation of Sketch Drawings」で言う「ペンの状態」は、JavaScriptで作成する「お絵かきアプリ」と非常によく似ています。図の「X軸方向への移動幅」はstrokesオブジェクトのdxプロパティ値であり、「Y軸方向への移動幅」はstrokesオブジェクトのdyプロパティ値です。「ペンが紙に触れているか」はstrokesオブジェクトのpenプロパティが値’down’である状態であり、「ペンが紙から離れる(終点)」はstrokesオブジェクトのpenプロパティが値’up’である状態、「描画終了」はstrokesオブジェクトのpenプロパティが値’end’である状態です。

ペンが”down”状態の場合には、その位置から水平方向にdx分だけ、垂直方向にdy分だけ線を描きます。これが1ストローク(日本語で言うひと筆)です。ペンが”up”状態の場合は紙(キャンバス)から離れているので、線は描きません。

以上を踏まえて、sketch.jsに手を加えていきます。

複数の関数で使用できるように、変数xとyをグローバル変数として宣言します。

// 現在の描画位置 => ペンの位置
let x, y;

線はキャンバスのセンターから描くようにするので、補助として、始点が分かりやすいように小さな円を描画します。これはsetup()関数内に記述します。

// センターに小さな円を描く(ストロークパスの確認用)
  ellipse(320, 240, 1, 1);

startDrawing()関数で、グローバル変数のxとyに値を設定します。xとyはペンの現在位置を追跡する変数として使用します。

const startDrawing = () => {
        // 描画はキャンバスのセンターから開始する
        x = width / 2;
        y = height / 2;

gotStroke()関数に、線を引くコードを追加します。

line(x, y, x + strokes.dx, y + strokes.dy);

ここまでのコードを実行し、たとえば次のstrokesオブジェクトが得られた場合には、キャンバスのセンター(320, 240)から右に3.92…、下に16.23…進んだ位置まで線が描かれます。

{dx: 3.923058088681028, dy: 16.239803365250864, pen: “down”}

ml5.jsのSketchRNNではこのようにして、generate()メソッドを何度も呼び出して、その都度コールバック関数からstrokesオブジェクトを取り出し、ペンがdown状態のときには今の位置からdxとdy分だけ線を引いてペンを次の位置に移動させ、up状態のときには線は引かずにペンを移動させるという方法で、モデルの絵を描いていきます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA