7

こんにちは、画像処理をしようとしています。Microsoft Kinect を使用して、部屋にいる人間を検出します。深度データを取得し、バックグラウンド減算作業を行い、人がシーンに入って歩き回ると、次のようなビデオ シーケンスになります。

http://www.screenr.com/h7f8

動画でノイズの挙動が分かるように動画を載せておきます。異なる色は、異なる深さのレベルを表します。白は空を表します。ご覧のとおり、かなりうるさいです。特に赤いノイズです。

人間以外はできるだけ排除したい。(非常に大きなウィンドウ サイズを使用して) 侵食/膨張を行うと、多くのノイズを取り除くことができますが、使用できる他の方法があるかどうか疑問に思いました。特に、ビデオの赤いノイズは、浸食/膨張を使用して除去するのが困難です。

いくつかのメモ:

1) シーンに人間がいないことを知っていれば、より良い背景の減算を行うことができますが、私たちが行う背景の減算は完全に自動であり、シーンに人間がいる場合やカメラが動いている場合でも機能します。これは、現在取得できる最高のバックグラウンド減算です。

2) アルゴリズムは組み込みシステムでリアルタイムに動作します。したがって、アルゴリズムがより効率的で簡単であるほど、優れたものになります。そして、それは完璧である必要はありません。複雑な信号処理技術も大歓迎ですが (組み込みのリアルタイム処理を必要としない別のプロジェクトでそれらを使用するかもしれません)。

3) 実際のコードは必要ありません。ただのアイデア。

4

4 に答える 4

2

ちょうど私の2セント:

そのためにSDKを使用してもかまわない場合は、Outlaw Lemurが示すように、PlayerIndexBitmaskを使用して人物のピクセルのみを非常に簡単に保持できます。

今、あなたはそのためのドライバーに頼りたくなくて、画像処理レベルでそれをしたいと思うかもしれません。私たちがプロジェクトで試し、かなりうまくいったアプローチは、輪郭ベースでした。背景の減算から始めて、これが人物であると仮定して画像内で最大の輪郭を検出し(通常、残っているノイズは非常に小さなブロブであったため)、その輪郭を塗りつぶして維持しました。また、最初のパスとして、ある種のメディアンフィルタリングを使用することもできます。

もちろん、これはすべての場合に完全でも適切でもありません。おそらくもっと良い方法があります。しかし、それがあなたが何かアイデアを思いつくのを助ける場合に備えて、私はただそれをそこに投げています。

于 2012-08-28T19:52:04.273 に答える
1

eyeswebを見てください。

kinectデバイスに対応した設計プラットフォームで、出力にノイズフィルタをかけることができます。multimodalこれは、システム設計のための非常に便利でシンプルなツールです。

于 2012-08-28T21:38:19.333 に答える
0

Kinect SDKを使用していると仮定すると、これは非常に簡単です。深さの基本についてはこのビデオをフォローし、次のようなことを行います。

    private byte[] GenerateColoredBytes(DepthImageFrame depthFrame)
    {

        //get the raw data from kinect with the depth for every pixel
        short[] rawDepthData = new short[depthFrame.PixelDataLength];
        depthFrame.CopyPixelDataTo(rawDepthData); 

        //use depthFrame to create the image to display on-screen
        //depthFrame contains color information for all pixels in image
        //Height x Width x 4 (Red, Green, Blue, empty byte)
        Byte[] pixels = new byte[depthFrame.Height * depthFrame.Width * 4];

        //Bgr32  - Blue, Green, Red, empty byte
        //Bgra32 - Blue, Green, Red, transparency 
        //You must set transparency for Bgra as .NET defaults a byte to 0 = fully transparent

        //hardcoded locations to Blue, Green, Red (BGR) index positions       
        const int BlueIndex = 0;
        const int GreenIndex = 1;
        const int RedIndex = 2;


        //loop through all distances
        //pick a RGB color based on distance
        for (int depthIndex = 0, colorIndex = 0; 
            depthIndex < rawDepthData.Length && colorIndex < pixels.Length; 
            depthIndex++, colorIndex += 4)
        {
            //get the player (requires skeleton tracking enabled for values)
            int player = rawDepthData[depthIndex] & DepthImageFrame.PlayerIndexBitmask;

            //gets the depth value
            int depth = rawDepthData[depthIndex] >> DepthImageFrame.PlayerIndexBitmaskWidth;

            //.9M or 2.95'
            if (depth <= 900)
            {
                //we are very close
                pixels[colorIndex + BlueIndex] = Colors.White.B;
                pixels[colorIndex + GreenIndex] = Colors.White.G;
                pixels[colorIndex + RedIndex] = Colors.White.R;
            }
            // .9M - 2M or 2.95' - 6.56'
            else if (depth > 900 && depth < 2000)
            {
                //we are a bit further away
                pixels[colorIndex + BlueIndex] = Colors.White.B;
                pixels[colorIndex + GreenIndex] = Colors.White.G;
                pixels[colorIndex + RedIndex] = Colors.White.R;
            }
            // 2M+ or 6.56'+
            else if (depth > 2000)
            {
                //we are the farthest
                pixels[colorIndex + BlueIndex] = Colors.White.B;
                pixels[colorIndex + GreenIndex] = Colors.White.G;
                pixels[colorIndex + RedIndex] = Colors.White.R;
            }


            ////equal coloring for monochromatic histogram
            //byte intensity = CalculateIntensityFromDepth(depth);
            //pixels[colorIndex + BlueIndex] = intensity;
            //pixels[colorIndex + GreenIndex] = intensity;
            //pixels[colorIndex + RedIndex] = intensity;


            //Color all players "gold"
            if (player > 0)
            {
                pixels[colorIndex + BlueIndex] = Colors.Gold.B;
                pixels[colorIndex + GreenIndex] = Colors.Gold.G;
                pixels[colorIndex + RedIndex] = Colors.Gold.R;
            }

        }


        return pixels;
    }

これにより、人間以外はすべて白くなり、人間は金色になります。お役に立てれば!

編集

必ずしもアイデアだけのコードが必要なわけではないことを知っているので、深さを見つけるアルゴリズムと、人間の量を見つけるアルゴリズムを見つけて、人間以外のすべてを白に着色すると思います。私はこれらすべてを提供しましたが、あなたが何が起こっているのか知っているかどうかはわかりませんでした。また、最終的なプログラムのイメージもあります。

image1

注:遠近法のために2番目の深度フレームを追加しました

于 2012-08-28T13:08:37.153 に答える
0

私は間違っているかもしれません (そのための処理なしでビデオが必要です) が、私はあなたが照明の変化を取り除こうとしていると言う傾向があります.

これが、「実際の」環境での人物の検出を非常に困難にしている理由です。

いくつかのリンクについては、この他のSOの質問をチェックしてください。

私はあなたと同じ構成で人間をリアルタイムで検出していましたが、単眼視でした。私の場合、本当に良い記述子はLBPsで、主にテクスチャ分類に使用されます。これを実践するのは非常に簡単です (Web のいたるところに実装があります)。

LBP は基本的に、動きが検出される対象領域を定義するために使用されるため、画像の一部のみを処理してノイズをすべて取り除くことができます。

たとえば、この論文では、画像のグレースケール補正に LBP を使用しています。

それがいくつかの新しいアイデアをもたらすことを願っています。

于 2012-08-28T13:24:04.297 に答える