Jeffrey Cross
Jeffrey Cross

コードボックス:魔法の杖を作成する

カラートラッキングは、ソフトウェアと対話するための楽しい新しい方法を作成するためのシンプルだが強力な技術です。センサーとしてウェブカメラを使用して、プログラムはある種の物理的なポインタの上で特定の色を見つけるために「訓練」されます。色付きポインタは、移動するにつれて(x、y)座標にマッピングされます。リアルタイムで行われると、これはマウスのようにポインタを使うことを可能にし、あらゆる種類の興味深い可能性を切り開きます。今回のCodeboxでは、ProcessingとコンピューターのWebカメラ(この例では、私のMacBookに内蔵されているiSightカメラを使用しました)の使い方を説明します。

例自体は簡単ですが、コードは、このシリーズの後半で説明するさまざまなプロジェクトの構成要素です。

セットアップ処理

このプロジェクトに入る前に、数分かけてProcessingについて少し見てみましょう。まず、プログラムにまったく慣れていないのであれば、Processing.orgで言語を学ぶか、Ben FryとCasey Reasによって共同作成された、Processing入門のコピーを入手してください。処理言語その過程で支援資料や参照を指摘しますが、システムに基本的な根拠がない限り、あなたは非常にイライラする可能性があります。そのため、まだ行っていない場合は、自分のプラットフォーム用のProcessingをダウンロードしてインストールします。

「ワンド」を作る

Processingが設定されてスケッチが実行されたら、「ワンド」を作成する必要があります(独特の色を持つオブジェクトを実際に使用できるため、ワンドを引用符で囲みます)。これは、「一枚の紙から素晴らしいハリーポッターの杖を作り、接着剤で接着剤で接着する」のようなものです。少なくとも処理の観点からすると、重要な要素は、ワンドの先端に独特の色があることです。早くて汚い解決策として、私はDay-GloオレンジのPost-it Noteを箸の先に巻きつけました。正確にはハリーポッターではありませんが、仕事は終わりです。

スケッチを始める

ワンドの準備ができたら、スケッチを試してみることができます。処理を開始してから、次のコードをメインウィンドウに貼り付けます。最初の行をハイライトし、一番下までスクロールしてからctrl-c(hard)を使用するか、このリンク(magic_wand.pde)をクリックしてCtrl + aを押してすべてのテキストを選択してからCtrlを使用することができます。コピーするには+ c(簡単)。

コードを貼り付けたら、次のように、処理ウィンドウの左上隅にあるスタートボタンを押します。

最後に、あなたのウェブカメラの前に出てください。カラートラッキングを使用する準備が整いました。

追跡色を取得する

最初のステップは、Processingが追跡する色を設定することです。これを行うには、棒の先端を左上隅の白いボックスに移動します。上のボックスが、杖の先のような色に変わるのがわかります。色について設定したら、任意のキーを押します。

舞台裏では、ProcessingはWebカメラから入ってくる各フレームを読み込み、Processingの第一人者Daniel Shiffmanによる素晴らしい小さなハックを使って、スケッチをより自然に相互作用させるために画像を水平方向に反転させます。それ以外の場合は、すべての動きが鏡像として表示されるため、ワンドを右に動かすと左に動かし、逆の場合も同様です。これはすべて次のコードスニペットで行われます。

if(cam.available()){cam.read(); //これはProcessingの第一人者であるDaniel Shiffmanの// //ウェブカメラのあなたの動きに対する鏡像効果を明らかにするためのちょっとしたコツです。スケール(-1.0、1.0)。 image(cam、-cam.width、0); popMatrix();画像(カム、0、0)。 }

画像が読み込まれた後 カム 変数に searchForTargetColor() 関数(関数については、第8章に説明があります。 処理入門)この関数は、白のターゲット取得ボックス内のピクセルをスキャンし、赤、緑、青の各成分を平均してターゲット色を表す全体的な色を計算します。これはここで起こります:

color acquireTargetColor(){int r = 0; int g = 0。 int b = 0。 int cnt = 0。 for(int i = 0; i <targetSide; i ++){for(int j = 0; j <targetSide; j ++){cnt + = 1; int x = targetX + 1。 // xはターゲットボックスの内側を指すint y = targetY + j; //ターゲットボックス内のyポイント//現在のピクセルの色colorを引き出すc = cam.pixels [y * width + x]; r + =赤(c)。 g + =緑(c)。 b + =青(c)。 targetColor = color(r / cnt、g / cnt、b / cnt); targetColorを返します。 }

目標色を探す

キーを押すとターゲットの色が設定されます。 targetColor (可変)の場合、スケッチはターゲットカラーの取得からターゲットカラーの検索にモードを切り替えます。この仕事は searchForTargetColor() 画像内のすべてのピクセルをスキャンして targetColor。 2つの色の間の距離が50単位(あるいはあなたが設定したどんな値でも)より小さいならば colorDistその後、それは試合と見なされます。 (距離に関する簡単なメモ:これは、RGB色を赤、緑、青の軸を持つ「スペース」として扱うことを意味します。2色間の距離は、基本代数からの2点間の距離だけです。ピクセルがターゲットカラーと一致した場合は、一致するピクセルの合計に加算されます。すべてのピクセルがテストされたら、次にワンドの先端の全体的な位置を考え出すために、一致するすべての色の平均を求めます。これはすべてここで起こります:

void searchForTargetColor(){//ワンドをリセットwandX = 0; wandY = 0。 wandFound = false; //ここで、ターゲットカラーと一致するピクセルを検索します。int numPoints = 0; //見つかった点の数int sx = 0; //見つかったすべてのx座標の合計int sy = 0; //(int i = 0; i <width; i ++){for(int j = 0; j <height; j ++){color pix = cam.pixels [j * width + i]で見つかったすべてのy座標の合計; // i、jでピクセルを取得します。float dr = red(targetColor) - red(pix); float dg =緑(targetColor) - 緑(pix)。 float db = blue(targetColor) - blue(pix); float d = sqrt(pow(dr、2)+ pow(dg、2)+ pow(db、2))。 //もしそれが一致するならば、(d <colorDist){numPoints + = 1; sx + = i; sy + = j; //目的の色が見つかったら、次の場合にワンド座標を設定します。(numPoints> 0){wandX = sx / numPoints;} wandY = sy / numPoints; wandFound = true; }}

この平均的な位置の概念が、先端に異なる色を使用することが非常に重要な理由です。あなたが白のような共通の色を選ぶことになっていたならば、あなたの平均的な位置は杖だけではなく、ドアフレーム、あなたのシャツ、靴のペア、または視野内に偶然存在していたもの。

ターゲットの位置が計算されると、スケッチはワンドの先端から発する一連の光線を作成します。これは drawWand() それは光線がどれくらい速く現れるかを制御するためにタイマーを使う機能です。 (タイマーについては、入門書の例7-11で説明されています)。これがその抜粋です。

void drawWand(int N、int R){strokeWeight(6);ストローク(wandColor); smooth(); int経過時間= millis() - oldTime。 float r = map(経過時間、0、wandFrequency、0、R); (int i = 0; i <N; i ++){float step =ラジアン(360.0 / N); float dx = r * sin(i * step)+ wandX; float dy = r * cos(i * step)+ wandY。ライン(wandX + 10 * sin(i * step)、wandY + 10 * cos(i * step)、dx、dy)。 if(経過時間> wand頻度){oldTime = millis();} }}

アクションを実行する

最後のステップは、ワンドを使用してスケッチの動作を制御することです。この例では、画面の左上隅に、設定可能なタイマーに基づいて色が変わる小さな円を追加しました。ワンドの先端を円の中に移動すると、ワンドの光線は新しい色に切り替わります。これはGetting Startedの例5-16を少し修正したものです。

//カラーサークルを新しいランダムカラーに設定します。void setColorCircleColor(){int経過時間= millis() - colorCircleMillis;} if(経過時間> colorCircleFrequency){colorCircleMillis = millis(); colorCircleColor = color(int(ランダム(255))、int(ランダム(255))、int(ランダム(255)); void testControlBounds(){float d = dist(wandX、wandY、cX、cY); //ランダムな色}} if(d <c R){wandColor = colorCircleColor; }}

次回のCodeboxでは、この例に基づいて、複数の移動するターゲットを作成します。あなたがゲーム、パーティクルシステム、あるいは杖で制御されたArduinoを使った魔法のショー(今後の記事の題材ですが、そこにたどり着くには少し時間がかかります)を書いているかどうか、これらはあなたが何度も何度も使うツールですProcessingをさらに進めるにつれて。

もっと:
Codeboxの全記事を見る

メーカーの小屋で:


Processing入門Processing、コードを使用して図面、アニメーション、インタラクティブグラフィックを作成するための簡単な言語であるProcessingを使用して、コンピュータプログラミングを簡単に学ぶことができます。プログラミングコースは通常理論から始まりますが、この本では創造的で楽しいプロジェクトに飛び込むことができます。基本的なプログラミングを学びたい人には理想的で、プログラミングのスキルを持っている人のためのグラフィックスの簡単な紹介としても役立ちます。

シェア

コメントを残します