2011年8月21日日曜日

たまには画像処理

久しぶりの更新です。
いろんな事情により画像処理の練習をしようと思ってSIFTを組んでみたのですが、
プログラムにマッチングさせるまでもなくいろいろとおかしいです。
いろいろと調べて間違ってるところを直さないと・・・





2011年7月22日金曜日

Kinect.Toolkit にジェスチャのテンプレートを追加する

Eternal CodingCode PlexでKinectでジェスチャの認識をするためのライブラリが公開されてます。

記事を読むのが一番早いと思いますが、ライブラリでは点の軌跡をそのまま解析する方法と、テンプレートを予め用意しておいてそれと比較する二種類の方法があるようです。

今回はそのテンプレートを自作してみようと思います。
どういうことかというと、公開されているサンプルの

この部分に表示されるものを自分で作ってみます。
(circleKB.saveに当たるものを作る。)

自作するジェスチャは次のような感じ。


今回はこのジェスチャの軌跡をテキストファイルに手打ちして、それを読み込んで.saveファイルを作成してみました。
大体の手順はTemplateGestureDetectorのAddメソッドに座標を追加していって、それをSaveStateメソッドでファイルに保存します。
以下が正確ではないですがコードにしたものです。

TemplateGestureDetector gd = new TemplateGestureDetector(null);
gd.StartRecordTemplate()
for (i = 0 ; i < n ; i++) {
gd.add(position , kinect.SkeletonEngine);
}
gd.EndRecordTemplate()
gd.SaveState(stream)


作成した結果がこちら


公開されているサンプルはほとんどいじっていないので、自作したテンプレートの認識結果を載せようとすると自分が写ってしまうので載せませんが、このとおりの動きをしたらきちんとジェスチャが認識されました。
最初に予定していたのに比べると傾いてしまいましたが、これは説明文をもっときちんと読むことで解消できるかと思います。

プロジェクトはこちらDownLoad

2011年7月9日土曜日

Kinect + OpenCVSharp フィルタ処理

Kinectから取ってきた深度画像とOpenCVを組み合わせて何かできないかと考えてます。
一応Kinectから取ってこれる画像は生の実画像に近いと思うのでOpenCVSharpに慣れるのもかねてフィルタ処理をしてみました。

画像中左上がKinectから取得してそのままの画像。
右上がガウシアンフィルタ。左下がブラー処理、右下がメディアンフィルタです。
これを見る限りだとフィルタ処理しても全然変わらないですね・・・
それでも若干ですがメディアンフィルタがエッジを保ちつつノイズを除去できているようには感じます。
そもそもフィルタ処理が必要かどうかという部分もありますが、使うならメディアンフィルタになるのかな・・・?

2011年7月2日土曜日

Kinect SDK + ARっぽいもの

前に、カメラからの距離の変化を利用してARっぽいことができないかと考えたので、その第一段階のようなものです。

Kinectから得られた最初のDepthFrameを基準とし、それと比べて距離が一定以上遠くなった領域の大体の重心に球体を描画しています。
もうちょっとちゃんと位置合わせしたりしないといけないですね。
まだまだ付け足さないといけない部分も多いですがこれをもとにいろいろいじろうと思います。

2011年6月26日日曜日

KinectSDK + Formアプリケーション ちょっとお遊び

現在本当は全身マウスっぽいものをやろうとしているのですが、XNA特有の問題を知らなかったりして時間を食って、現在Formアプリで作ってます。
大体は出来上がったのですが、精度面がまだかなり粗いのでその辺を改善したいと思ってます。
そんな中適当にやってたら残像?っぽいものが出てきて楽しかったので載せておきます。
適当にα値いじるだけですね。
画像は僕の腕ですw




using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Research.Kinect.Nui;

namespace Kinect_Residualimage
{
public partial class Form1 : Form
{
//画面表示用
Bitmap Texture;

//Kinectの変数
Runtime nui;

const int ALPHA_IDX = 3;
const int RED_IDX = 0;
const int GREEN_IDX = 1;
const int BLUE_IDX = 2;
byte[] colorFrame32 = new byte[640 * 480 * 4];

Graphics Graphi;

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
Texture = new Bitmap(640, 480, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

//Kinectの初期化
nui = new Runtime();
try
{
nui.Initialize(RuntimeOptions.UseColor);
}
catch (InvalidOperationException)
{
Console.WriteLine("Runtime initialization failed. Please make sure Kinect device is plugged in.");
return;
}

//video streamのOpenをする
try
{
nui.VideoStream.Open(ImageStreamType.Video, 2, ImageResolution.Resolution640x480, ImageType.Color);
}
catch (InvalidOperationException)
{
Console.WriteLine("Failed to open stream. Please make sure to specify a supported image type and resolution.");
return;
}
nui.VideoFrameReady += new EventHandler<ImageFrameReadyEventArgs>(nui_VideoFrameReady);

pictureBox1.Image = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphi = Graphics.FromImage(pictureBox1.Image);
}

void nui_VideoFrameReady(object sender, ImageFrameReadyEventArgs e)
{
PlanarImage Image = e.ImageFrame.Image;
byte[] converted = convertColorFrame(Image.Bits, (byte)50);
//画像の作成

unsafe {
fixed (byte* ptr = &converted[0]) {
Texture = new Bitmap(Image.Width , Image.Height , Image.Width * 4 , System.Drawing.Imaging.PixelFormat.Format32bppArgb , (IntPtr)ptr);
}
}

Graphi.DrawImage(Texture, 0, 0);

pictureBox1.Refresh();
}

//kinectから取り込んだColorFrameのフォーマットを直す
byte[] convertColorFrame(byte[] colorFrame , byte alpha)
{
for (int i = 0; i < colorFrame32.Length; i += 4)
{
colorFrame32[i + ALPHA_IDX] = alpha;
colorFrame32[i + RED_IDX] = colorFrame[i + 0];
colorFrame32[i + GREEN_IDX] = colorFrame[i + 1];
colorFrame32[i + BLUE_IDX] = colorFrame[i + 2];
}
return colorFrame32;
}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
nui.Uninitialize();
Environment.Exit(0);
}
}
}


2011年6月21日火曜日

Kinect SDK + XNA Jointを3次元座標で表示する


今までは2次元内での描画だったので今度は3次元座標を使って描画してみました。
もともと取得してこられるデータは3次元座標なので、XNAから使う分には3次元の方が楽でした。
ちゃんと3次元座標がとれたところで、マウスポインタを手で動かせるようにしてみようかと思います。そのうち。
今回のプロジェクトファイルですダウンロード

2011年6月20日月曜日

Kinect SDK + XNA スケルトンの表示

やっとKinectから取得してきたデータでスケルトンを描画できました。
早くXNAでもAPIとして2次元の直線とか基本的な図形をサポートしてもらいたいです。
さすがにソースコードは長いのでプロジェクトファイルを置いておきます。
ダウンロード