【问题标题】:Real time object tracking in java(some java API) or C#(emgucv,dshownet,Aforge.NET)java(一些java API)或C#(emgucv,dshownet,Aforge.NET)中的实时对象跟踪
【发布时间】:2010-05-26 09:12:26
【问题描述】:

我正在做一个名为用户启动的实时对象跟踪系统项目。以下是我希望在项目发生

1) 从网络摄像头获取连续流。

2) 使用鼠标,用户可以在感兴趣的对象周围画一个正方形。

3) 然后从那里开始,方块随着感兴趣的对象移动。因此,跟踪对象移动的每个位置,因此称为对象跟踪。


当前进度


我使用 dshownet(DirectShow 的 .NET 包装器)从网络摄像头获取输入。我正在将视频拆分为帧。我有 4 种方法来做这个项目:


技巧1


  • 有一个保存的视频
  • 我加载它。
  • 当视频播放时,我会在特定场景暂停(使用暂停按钮)它并在对象上绘制一个正方形。
  • 当我按下播放按钮时,方块将与对象一起移动,没有/5 秒的处理时间 [或] 我会给应用程序一些处理时间(例如 3 分钟),然后它会从那时开始播放正在发生的跟踪。

技巧2


  • 有一个保存的视频
  • 我加载它。
  • 当视频运行时,我不会暂停它,而是快速在对象上绘制一个正方形(当对象仍然在某个点时)。
  • 之后将跟踪对象,无需处理时间。 [或] 有一些处理时间(10 秒延迟),使文件播放时间更长。

技巧3


  • 我从网络摄像头获取输入 1 分钟。
  • 将该视频保存到文件中
  • 并执行方式 1 或方式 2

技术 4 - (显然这看起来更难


  • 连续从网络摄像头获取输入
  • 当对象没有移动时(例如,当一个人坐在椅子上时),在对象周围画一个正方形,不要暂停
  • 然后通过将正方形与对象一起移动来显示跟踪,没有处理时间 [或] 2 秒的轻微处理时间,这样延迟不会很明显。

要跟踪的对象:-


基本上我可以跟踪任何东西,因为我使用鼠标来绘制

  • 我打算使用整个身体(但如果这很麻烦..下一个选项)
  • 我会尝试跟踪一个人的面部(显然是通过用鼠标绘制该区域。)

编码时间: 1 和 1/2 个月


进度:拆分仍然出错。 (有人建议先开始分割保存的视频,我现在正在尝试)


我的问题


1) 我可以在 1 个月和 1/2 个月的时间范围内实施(四项中的)哪种技术?

2) 要编码,java + 一些 java 框架 是否适合此或 C#.netemgucv/AForge。 net/Dshownet [顺便说一下,我在 java 中的 knowledgegood 而不是那么 good C#.net]??


提前致谢

【问题讨论】:

    标签: c# java real-time tracking emgucv


    【解决方案1】:

    您可以使用 Java Media Framework 和 ImageJ 库在 Java 中实现技术 1、2、3。考虑到时间限制,对于技术 4,您最好使用 C++ 或其他非解释性语言来实现。

    【讨论】:

    • 欢迎您,有点含糊。非常有趣的项目,祝你好运。
    【解决方案2】:

    This example 基本上实现了你提到的技术4。用户在要跟踪的图案或对象周围绘制一个矩形。在这种情况下,tracked 元素用于控制 Pong Game 中的球拍。因此用户可以使用物体在镜头前玩游戏。

    我认为它可以解决您的大部分问题。

    截图:

    源代码:

    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;
        } 
    } 
    

    【讨论】:

      【解决方案3】:

      This article fully explains 与您想要的算法非常相似,the accompanying source code is here。你可以see it in action in this video。您需要添加的部分是,当用户绘制一个框时,识别框周围的对象(算法已经找到),然后在整个帧中简单地跟随具有该 int ID 的对象(算法关联对象逐帧知道它是整个视频中的同一个对象)。

      免责声明:我是作者;但我确实认为这非常有用,并且我自己也成功地使用了很多算法。)

      在商业计算机视觉应用方面,OpenCVPoint Cloud Library aka PCL 是您最好的朋友。类似链接的文章解释了如何使用 OpenCV 等工具来完成全栈运动跟踪。 (纯 Java 实现显示了它是如何工作到单个像素的。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-04
        • 1970-01-01
        • 2010-09-24
        相关资源
        最近更新 更多