6

私はユーザー主導のリアルタイムオブジェクト追跡システムと呼ばれるプロジェクトを行っています。これが私がプロジェクトでやりたいことです

1) Webカメラから連続ストリームを取得します。

2)マウスを使用して、ユーザーは関心のあるオブジェクトの周りに正方形を描くことができます。

3)次に、そこから、正方形は対象のオブジェクトに沿って移動します。これにより、オブジェクトが移動するすべての場所を追跡するため、オブジェクト追跡という用語が使用されます。


現在の進行


dshownet(DirectShowの.NETラッパー)を使用して、Webカメラから入力を取得しました。そして、私はビデオをフレームに分割する過程にあります。私はプロジェクトを行うために4つの方法を考えています:


テクニック1


  • 保存されたビデオがあります
  • ロードします。
  • ビデオが実行されているとき、私は特定のシーンでビデオを一時停止し(一時停止ボタンを使用して)、オブジェクトに正方形を描きます。
  • そして、再生ボタンを押すと、正方形は5秒の処理時間なしでオブジェクトと一緒に移動します[または]アプリケーションに処理時間(たとえば3分)を与え、その時点から追跡を取りながら再生します場所。

テクニック2


  • 保存されたビデオがあります
  • ロードします。
  • ビデオが実行されているとき、私はそれを一時停止しませんが、オブジェクトにすぐに正方形を描きます(オブジェクトがまだある時点にあるとき)。
  • その後、オブジェクトは処理時間なしで追跡されます。[または]処理時間(10秒の遅延)があり、ファイルの再生時間が少し長くなります。

テクニック3


  • Webカメラから1分間入力します。
  • そのビデオをファイルに保存します
  • そして、ウェイ1またはウェイ2を実行します

テクニック4-(どうやらこれはかなり難しいようです)


  • Webカメラから継続的に入力を取得します
  • オブジェクトに動きがない場合(たとえば、人が椅子に座っている場合)、一時停止せずにオブジェクトの周りに正方形を描きます。
  • 次に、処理時間なし[または] 2秒のわずかな処理時間でオブジェクトと一緒に正方形を移動して追跡を示し、遅延があまり目立たないようにします。

追跡するオブジェクト:-


マウスを使って描くので、基本的には何でも追跡できます

  • 全身を使う予定です(でもこれが面倒なら次のオプション)
  • 私は個人の顔を追跡しようとします(明らかにマウスでその領域を描くことによって)。

コーディングまでの時間: 1か月半


進行状況:分割でまだエラーが発生しています。(誰かが最初に保存されたビデオの分割を開始することを提案しました、そして私は今それを試みているところです)


私の質問


1)1か月半の時間枠で(4つのうち)どの手法を実装できるでしょうか?

2)コーディングするには、java +いくつかのJavaフレームワークはこれに適していますか、それともemgucv / AForge.net / Dshownetを使用したC#.netですか[ちなみに、Javaに関する私の知識優れますが、C#.netにはあまり適していません] ??


前もって感謝します

4

3 に答える 3

2

テクニック1、2、3は、JavaMediaFrameworkおよびImageJライブラリを使用してJavaに実装できます。テクニック4の場合、時間の制約があるため、C++またはその他の非解釈言語で実装することをお勧めします。

于 2010-05-26T09:31:04.360 に答える
1

この例は基本的に、テクニック4として言及したものを実装します。ユーザーは、追跡するパターンまたはオブジェクトの周囲に長方形を描画します。この場合、追跡された要素は、ポンゲームのパドルを制御するために使用されます。したがって、ユーザーはオブジェクトを使用してカメラの前でゲームをプレイできます。

私はそれがあなたの問題のほとんどの部分を解決すると思います。

スクリーンショット: ここに画像の説明を入力してください

ソースコード:

package video.trackingPong; 

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Container; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 

import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JSlider; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 

import marvin.gui.MarvinImagePanel; 
import marvin.image.MarvinImage; 
import marvin.image.MarvinImageMask; 
import marvin.io.MarvinImageIO; 
import marvin.plugin.MarvinImagePlugin; 
import marvin.util.MarvinAttributes; 
import marvin.util.MarvinPluginLoader; 
import marvin.video.MarvinJavaCVAdapter; 
import marvin.video.MarvinVideoInterface; 
import marvin.video.MarvinVideoInterfaceException; 

public class TrackingPong extends JFrame implements Runnable{

    private final static int         BALL_INITIAL_PX=100; 
    private final static int         BALL_INITIAL_PY=100; 
    private final static int         BALL_INITIAL_SPEED=3; 

    private MarvinVideoInterface    videoInterface; 
    private MarvinImagePanel         videoPanel; 

    private Thread                     thread; 

    private MarvinImage             imageIn,  
                                    imageOut; 

    private JPanel                    panelSlider; 

    private JSlider                    sliderSensibility; 

    private JLabel                    labelSlider; 

    private int                        regionPx,
                                    regionPy, 
                                    regionWidth, 
                                    regionHeight; 

    private boolean                    regionSelected=false; 
    private int[]                    arrInitialRegion; 

    private int                        sensibility=30; 



    // Pong Game Attributes 
    private double                    ballPx=BALL_INITIAL_PX,
                                    ballPy=BALL_INITIAL_PY; 

    private int                        ballSide=15; 


    double                            ballIncX=5; 
    private double                    ballIncY=5;     

    private int                        imageWidth,
                                    imageHeight; 

    private Paddle                    paddlePlayer, 
                                    paddleComputer; 

    private int                        playerPoints=0, 
                                    computerPoints=0; 

    private MarvinImagePlugin         findColorPattern, 
                                    flip, 
                                    text; 

    private MarvinImage                imageBall, 
                                    imagePaddlePlayer, 
                                    imagePaddleComputer; 

    private MarvinAttributes        attributesOut; 

    public TrackingPong(){ 
        videoPanel = new MarvinImagePanel(); 

        try{ 
            // 1. Connect to the camera device. 
            videoInterface = new MarvinJavaCVAdapter(); 
            videoInterface.connect(0); 

            imageWidth = videoInterface.getImageWidth(); 
            imageHeight = videoInterface.getImageHeight(); 

            imageOut = new MarvinImage(imageWidth, imageHeight);

            // 2. Load Graphical Interface. 
            loadGUI(); 

            // 3. Load and set up Marvin plug-ins. 
            findColorPattern     = MarvinPluginLoader.loadImagePlugin("org.marvinproject.image.pattern.findColorPattern"); 
            flip                = MarvinPluginLoader.loadImagePlugin("org.marvinproject.image.transform.flip"); 
            text                = MarvinPluginLoader.loadImagePlugin("org.marvinproject.image.render.text"); 
            text.setAttribute("fontFile", MarvinImageIO.loadImage("./res/font.png")); 
            text.setAttribute("color", 0xFFFFFFFF); 

            // 3. Load game images 
            imageBall = MarvinImageIO.loadImage("./res/ball.png"); 
            imagePaddlePlayer = MarvinImageIO.loadImage("./res/paddleA.png"); 
            imagePaddleComputer = MarvinImageIO.loadImage("./res/paddleB.png"); 

            attributesOut = new MarvinAttributes(null);

            // Set up plater and computer paddle properties. 
            paddlePlayer = new Paddle(); 
            paddlePlayer.px=100; 
            paddlePlayer.py=420; 
            paddlePlayer.width=100; 
            paddlePlayer.height=30; 

            paddleComputer = new Paddle(); 
            paddleComputer.px=100; 
            paddleComputer.py=30; 
            paddleComputer.width=100; 
            paddleComputer.height=30; 

            thread = new Thread(this);
            thread.start(); 
        } 
        catch(MarvinVideoInterfaceException e){ 
            e.printStackTrace(); 
        } 
    } 

    private void loadGUI(){     
        setTitle("Video Sample - Tracking Pong"); 

        videoPanel.addMouseListener(new MouseHandler()); 

        sliderSensibility = new JSlider(JSlider.HORIZONTAL, 0, 60, 30);
        sliderSensibility.setMinorTickSpacing(2); 
        sliderSensibility.setPaintTicks(true); 
        sliderSensibility.addChangeListener(new SliderHandler());

        labelSlider = new JLabel("Sensibility"); 

        panelSlider = new JPanel(); 
        panelSlider.add(labelSlider); 
        panelSlider.add(sliderSensibility); 

        Container container = getContentPane(); 
        container.setLayout(new BorderLayout()); 
        container.add(videoPanel, BorderLayout.NORTH); 
        container.add(panelSlider, BorderLayout.SOUTH); 

        setSize(videoInterface.getImageWidth()+20,videoInterface.getImageHeight()+100); 
        setVisible(true); 
    } 

    public void run(){ 
        long time = System.currentTimeMillis(); 
        int ticks=0; 

        // The game loop. 
        try{ 
            while(true){ 

                ticks++; 
                if(System.currentTimeMillis() - time > 1000){ 
                    System.out.println("FPS: "+ticks+"       "); 
                    ticks=0; 
                    time = System.currentTimeMillis();                     
                } 

                // 1. Get the current video frame. 
                imageIn = videoInterface.getFrame(); 
                MarvinImage.copyColorArray(imageIn, imageOut); 

                // 2. Flip the frame horizontally so the player will see him on the screen like looking at the mirror. 
                flip.process(imageOut, imageOut); 

                if(regionSelected){ 

                    // 3. Find the player paddle position. 
                    findColorPattern.setAttribute("differenceColorRange", sensibility); 
                    findColorPattern.process(imageOut, imageOut, attributesOut, MarvinImageMask.NULL_MASK, false);
                    regionPx         = (Integer)attributesOut.get("regionPx"); 
                    regionPy         = (Integer)attributesOut.get("regionPy"); 
                    regionWidth     = (Integer)attributesOut.get("regionWidth"); 
                    regionHeight    = (Integer)attributesOut.get("regionHeight"); 

                    // 4. Invoke the game logic 
                    pongGame(); 

                    // 5. Draw the detected region 
                    imageOut.drawRect(regionPx, regionPy, regionWidth, regionHeight, Color.red); 

                    // 6. Draw the player and computer points. 
                    text.setAttribute("x", 105); 
                    text.setAttribute("y", 3); 
                    text.setAttribute("text", "PLAYER:"+playerPoints); 
                    text.process(imageOut, imageOut); 

                    text.setAttribute("x", 105); 
                    text.setAttribute("y", 460); 
                    text.setAttribute("text", "COMPUTER:"+computerPoints); 
                    text.process(imageOut, imageOut); 
                } 


                videoPanel.setImage(imageOut); 
            } 
        } 
        catch(MarvinVideoInterfaceException e){ 
            e.printStackTrace(); 
        } 
    } 

    private void pongGame(){ 
        // 1. Move the ball 
        ballIncX*=1.001; 
        ballIncY*=1.001; 
        ballPx+=ballIncX; 
        ballPy+=ballIncY; 

        // 2. Set the player paddle position to the the coordinates of the detected region. 
        paddlePlayer.px = regionPx+((regionWidth-paddlePlayer.width)/2); 

        // 3. Invoke simple computer AI 
        computerAI(); 

        // 4. Check object positions and collisions. 
        checkPaddlePosition(paddlePlayer); 
        checkPaddlePosition(paddleComputer); 
        collisionScreen(); 
        collisionTap(); 

        // 5. Draw the game elements. 
        imageOut.fillRect(horizontalMargin, 0, 5, imageHeight, Color.black);
        imageOut.fillRect(imageWidth-horizontalMargin, 0, 5, imageHeight, Color.black);

        combineImage(imagePaddlePlayer, paddlePlayer.px, paddlePlayer.py); 
        combineImage(imagePaddleComputer, paddleComputer.px, paddleComputer.py); 
        combineImage(imageBall,(int)ballPx, (int)ballPy); 
    } 

    private void checkPaddlePosition(Paddle a_paddle){ 
        if(a_paddle.px < horizontalMargin){ 
            a_paddle.px = horizontalMargin; 
        } 
        if(a_paddle.px+a_paddle.width > imageWidth-horizontalMargin){ 
            a_paddle.px = imageWidth-horizontalMargin-a_paddle.width; 
        }         
    } 

    private void computerAI(){ 
        if(ballPx < paddleComputer.px+(paddleComputer.width/2)-10){ 
            paddleComputer.px-=4; 
        } 
        if(ballPx > paddleComputer.px+(paddleComputer.width/2)+10){ 
            paddleComputer.px+=4; 
        } 
    } 

    private int horizontalMargin = 100;
    private void collisionScreen(){ 

        if(ballPx < horizontalMargin){ 
            ballPx = horizontalMargin; 
            ballIncX*=-1; 
        } 
        if(ballPx+ballSide >= imageWidth-horizontalMargin){
            ballPx=(imageWidth-horizontalMargin)-ballSide; 
            ballIncX*=-1; 
        } 
        if(ballPy < 0){ 
            playerPoints++; 
            ballPx = BALL_INITIAL_PX; 
            ballPy = BALL_INITIAL_PY; 
            ballIncY=BALL_INITIAL_SPEED; 
            ballIncX=BALL_INITIAL_SPEED; 
        } else if(ballPy+ballSide >= imageHeight){ 
            computerPoints++; 
            ballPx = BALL_INITIAL_PX; 
            ballPy = BALL_INITIAL_PY; 
            ballIncY=BALL_INITIAL_SPEED; 
            ballIncX=BALL_INITIAL_SPEED; 
        } 
    } 

    private void collisionTap(){ 
        if(ballCollisionTap(paddlePlayer)){ 
            ballIncY*=-1; 
            ballPy = paddlePlayer.py-ballSide; 
        } 
        if(ballCollisionTap(paddleComputer)){ 
            ballIncY*=-1; 
            ballPy = paddleComputer.py+paddleComputer.height; 
        } 
    } 

    private boolean ballCollisionTap(Paddle a_tap){ 
        if 
        ( 
            ( 
                ballPx >= a_tap.px && ballPx <= a_tap.px+a_tap.width || 
                ballPx <= a_tap.px && ballPx+ballSide >= a_tap.px 
            ) 
            && 
            ( 
                ballPy >= a_tap.py && ballPy <= a_tap.py+a_tap.height || 
                ballPy <= a_tap.py && ballPy+ballSide >= a_tap.py 
            ) 
        ) 
        { 
            return true; 
        } 
        return false; 
    } 

    private void combineImage(MarvinImage img, int x, int y){ 
        int rgb; 
        int width = img.getWidth(); 
        int height = img.getHeight(); 

        for(int iy=0; iy<height; iy++){ 
            for(int ix=0; ix<width; ix++){ 
                if 
                ( 
                    ix+x > 0 && ix+x < imageWidth &&
                    iy+y > 0 && iy+y < imageHeight
                ) 
                { 
                    rgb=img.getIntColor(ix, iy);                 
                    if(rgb != 0xFFFFFFFF){ 
                        imageOut.setIntColor(ix+x, iy+y, rgb); 
                    } 
                } 
            } 
        }         
    } 

    public static void main(String args[]){ 
        TrackingPong trackingPong = new TrackingPong(); 
        trackingPong.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

    private class SliderHandler implements ChangeListener{
        public void stateChanged(ChangeEvent a_event){ 
            sensibility = (60-sliderSensibility.getValue());
        } 
    } 

    private class MouseHandler implements MouseListener{
        public void mouseEntered(MouseEvent a_event){} 
        public void mouseExited(MouseEvent a_event){} 
        public void mousePressed(MouseEvent a_event){} 
        public void mouseClicked(MouseEvent a_event){} 

        public void mouseReleased(MouseEvent event){ 
            if(!regionSelected){ 
                if(arrInitialRegion == null){ 
                    arrInitialRegion = new int[]{event.getX(), event.getY(),0,0}; 
                } 
                else{ 
                    arrInitialRegion[2] = event.getX()-arrInitialRegion[0]; 
                    arrInitialRegion[3] = event.getY()-arrInitialRegion[1]; 

                    findColorPattern.setAttribute("regionPx", arrInitialRegion[0]); 
                    findColorPattern.setAttribute("regionPy", arrInitialRegion[1]); 
                    findColorPattern.setAttribute("regionWidth", arrInitialRegion[2]); 
                    findColorPattern.setAttribute("regionHeight", arrInitialRegion[3]); 

                    regionSelected = true; 
                }     
            } 
        }         
    } 

    private class Paddle{ 
        public int px,py,width,height;
    } 
} 
于 2016-11-24T18:27:48.270 に答える
0

この記事では、必要なものと非常によく似たアルゴリズムについて詳しく説明しています。付属のソースコードはこちらです。あなたはこのビデオでそれが実際に動いているのを見ることができます。追加する必要があるのは、ユーザーがボックスを描画するときに、ボックスが周囲にあるオブジェクト(アルゴリズムによって既に検出されている)を識別し、フレーム全体でそのint IDを持つオブジェクトを追跡することです(アルゴリズムは相関します)オブジェクトはフレームごとに表示され、ビデオ全体で同じオブジェクトであることを認識します)。

免責事項:私は著者です。しかし、これは非常に便利であり、自分でアルゴリズムをうまく使用できたと思います。)

商用コンピュータビジョンアプリケーションに関しては、OpenCVポイントクラウドライブラリ(別名PCL)が親友です。また、リンクされているような記事では、OpenCVなどのツールを使用してフルスタックモーショントラッキングを実行する方法について説明しています。(純粋なJava実装は、個々のピクセルまでどのように機能するかを示しています。)

于 2016-02-20T15:20:03.417 に答える