11_2:ml5.js SketchRNNの基本サンプル ml5.js JavaScript

本稿は「ml5-examples/p5js/SketchRNN/SketchRNN_basic」のサンプルを元に、適用するモデルをメニューから変更できるようにしたものです。

次のリンクをクリックすると、サンプルの動作を確認することができます。「ml5.js SketchRNNの基本サンプル」まずはml5.jsのSketchRNNを体験してみてください。ドロップダウンメニューをクリックして開き、描きたい項目を選択すると、そのモデルが読み込まれ、SketchRNNが線画を描きます。

以下はこのサンプルで使用しているHTMLとJavaScriptの全コードです。

HTML


<html>

<head>
  <meta charset="UTF-8" />
  <title>SketchRNN</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.0/p5.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.0/addons/p5.dom.min.js"></script>
  <script src="https://unpkg.com/ml5@0.1.2/dist/ml5.min.js" type="text/javascript"></script>
  <!-- サンプルでは新しいml5.jsを使うようになっているが、新しいml5.jsでは
      nextTensorId is not a function というエラーが発生する。サンプルで使われているml5.jsがどのバージョンが分からない
      上のml5@0.1.2ではエラーは発生しない-->
  <!---<script src="ml5.min.js" type="text/javascript"></script>-->
</head>

<body>
  <h1>SketchRNN</h1>
  <p id="status">モデルの読み込み中...</p>
  <div>
    <label for="model">モデルを選択:</label>
    <select id="model"></select>
  </div>
  <script src="sketch.js"></script>
</body>

</html>

sketch.js


// SketchRNNが描ける絵の種類
const models = [
    'alarm_clock',
    'ambulance',
    'angel',
    'ant',
    'antyoga',
    'backpack',
    'barn',
    'basket',
    'bear',
    'bee',
    'beeflower',
    'bicycle',
    'bird',
    'book',
    'brain',
    'bridge',
    'bulldozer',
    'bus',
    'butterfly',
    'cactus',
    'calendar',
    'castle',
    'cat',
    'catbus',
    'catpig',
    'chair',
    'couch',
    'crab',
    'crabchair',
    'crabrabbitfacepig',
    'cruise_ship',
    'diving_board',
    'dog',
    'dogbunny',
    'dolphin',
    'duck',
    'elephant',
    'elephantpig',
    'eye',
    'face',
    'fan',
    'fire_hydrant',
    'firetruck',
    'flamingo',
    'flower',
    'floweryoga',
    'frog',
    'frogsofa',
    'garden',
    'hand',
    'hedgeberry',
    'hedgehog',
    'helicopter',
    'kangaroo',
    'key',
    'lantern',
    'lighthouse',
    'lion',
    'lionsheep',
    'lobster',
    'map',
    'mermaid',
    'monapassport',
    'monkey',
    'mosquito',
    'octopus',
    'owl',
    'paintbrush',
    'palm_tree',
    'parrot',
    'passport',
    'peas',
    'penguin',
    'pig',
    'pigsheep',
    'pineapple',
    'pool',
    'postcard',
    'power_outlet',
    'rabbit',
    'rabbitturtle',
    'radio',
    'radioface',
    'rain',
    'rhinoceros',
    'rifle',
    'roller_coaster',
    'sandwich',
    'scorpion',
    'sea_turtle',
    'sheep',
    'skull',
    'snail',
    'snowflake',
    'speedboat',
    'spider',
    'squirrel',
    'steak',
    'stove',
    'strawberry',
    'swan',
    'swing_set',
    'the_mona_lisa',
    'tiger',
    'toothbrush',
    'toothpaste',
    'tractor',
    'trombone',
    'truck',
    'whale',
    'windmill',
    'yoga',
    'yogabicycle',
    'everything',
];

// 最初に描画するのは目覚まし時計
let selectedModel = 'alarm_clock';
// SketchRNNモデル
let model = null;
// 現在のストロークパス
let strokePath = null;

// ペンの状態
let previous_pen = 'down';
// 現在の描画位置
let x, y;

function setup() {
    // <select>要素の選択肢を設定
    const selectE = select('#model');
    models.forEach((elm, index) => {
        let op = document.createElement("option");
        op.value = models[index]; //value値
        op.text = models[index]; //テキスト値
        selectE.child(op);
    });
    // キャンバスを作成し、背景色を設定
    createCanvas(640, 480);
    background(220);
    // 線を太くする
    strokeWeight(3.0);

    // <select>メニューの選択で、モデルを決める
    selectE.elt.addEventListener('change', (e) => {
        model = null;
        selectedModel = e.target.value;
        // 選択されたモデルを読み込む
        model = ml5.SketchRNN(selectedModel, modelReady);
        select('#status').html('モデルの読み込み中...');

    }, false);
    // 初期設定の'alarm_clock'モデルを読み込む
    model = ml5.SketchRNN(selectedModel, modelReady);
}

function modelReady() {
    select('#status').html('モデルの準備ができたので描画する');
    startDrawing();
}

const startDrawing = () => {
    // キャンバスをクリアし、背景色を設定
    clear();
    background(220);
    // 線の色をランダムに決める
    const r = random(255);
    const g = random(255);
    const b = random(255);
    stroke(r, g, b);

    // 描画の開始位置をキャンバスの中央にする
    x = width / 2;
    y = height / 2;
    // モデルをリセット
    model.reset();
    // ストロークパスを生成
    // async generate(optionsOrSeedOrCallback, seedOrCallback, cb)
    model.generate(gotStroke);
}

const gotStroke = (err, s) => {
    //console.log(s);
    strokePath = s;
}

// 毎フレーム呼び出される
function draw() {
    // ストロークパスがあれば
    if (strokePath) {
        console.log(strokePath.pen);
        // ペンが'down'状態なら線を描く
        if (previous_pen == 'down') {
            line(x, y, x + strokePath.dx, y + strokePath.dy);
        }
        // ペンを移動
        x += strokePath.dx;
        y += strokePath.dy;
        // ペンの状態は次のストロークのpenプロパティ
        previous_pen = strokePath.pen;

        // 1回の線描が終わったら
        if (strokePath.pen !== 'end') {
            // strokePath変数をnullにして、再度ストロークパスを生成し、次の線描に移る
            strokePath = null;
            model.generate(gotStroke);
        }
    }
}

コメントを残す

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

CAPTCHA