Search code examples
javaopencvnullpointerexceptiontemplate-matching

Null Pointer Exception in MatchTemplate example using OpenCV and Java


This question is continued from this thread. I could download the com.larmor.opencv.MatchTemplate library from here (in case anyone needs the link in future.)

Now coming down to my question.

When I run the code I am getting null pointer exception. Attaching the error messages for reference. Also this is the exact same project downloaded from here So I am not mentioning the code in the question.

Can anyone help me with how do I get rid of these errors.

enter image description here

enter image description here

EDIT

I had provided a link to the code above. So I didn't paste the entire code here. Anyways, here's the code:

package templatematching;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Panel;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;

import javax.media.Buffer;
import javax.media.CaptureDeviceInfo;
import javax.media.CaptureDeviceManager;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.Player;
import javax.media.control.FrameGrabbingControl;
import javax.media.format.VideoFormat;
import javax.media.util.BufferToImage;
import javax.swing.JButton;
import javax.swing.JComponent;

import com.larmor.opencv.MatchTemplate;

/**
 * This example match WebCam Area.
 * <br>
 * The class uses <a href="http://java.sun.com/products/java-media/jmf/" target="_blank">Java Media Framework API (JMF)</a>, 
 * and <a href="http://java.sun.com/javase/6/docs/technotes/guides/imageio/index.html" target="_blank">JAI-Java Image I/O Technology</a>
 * and <a href="http://java.sun.com/products/java-media/jmf/">Java Media Framework API (JMF)</a>
 * (for dowload: <a href="https://jai.dev.java.net/" target="_blank">https://jai.dev.java.net/</a>,
 * <a href="https://jai-imageio.dev.java.net/" target="_blank">https://jai-imageio.dev.java.net/</a> and
 * <a href="http://java.sun.com/products/java-media/jmf/2.1.1/download.html" target="_blank">http://java.sun.com/products/java-media/jmf/2.1.1/download.html</a>).<br>
 * <br>
 * 
 * 1) press button "select area" for stop image
 * 2) using mouse select area to matching (red rectangle)
 * 3) press button "start matching" for play webcam and starting matching (green rectangle)
 *    
 * @author      Pier Paolo Ciarravano Larmor  
 * License:     GNU General Public License   
 * @version     Vers. 0.5 beta (April.2008) 
 */
public class TestMatchWebCamArea extends Panel implements ActionListener,
        MouseListener, MouseMotionListener {

    static Player player = null;
    CaptureDeviceInfo di = null;
    MediaLocator ml = null;
    JButton matchCam = null;
    JButton selectArea = null;
    Component sourceComp = null;
    DoubleBufferPanel dbPanel = null;
    int areaX = 0;
    int areaY = 0;
    int areaWidth = 0;
    int areaHeight = 0;
    int stateButton;
    BufferedImage buffImgTemplate = null;

    public TestMatchWebCamArea() {

        stateButton = 0;

        setLayout(new BorderLayout());
        // setSize(320,240);

        selectArea = new JButton("Select Area");
        selectArea.addActionListener(this);

        matchCam = new JButton("Start Matching");
        matchCam.addActionListener(this);
        matchCam.setEnabled(false);

        // String str1 = "vfw:Logitech USB Video Camera:0";
        String str2 = "vfw:Microsoft WDM Image Capture (Win32):0";
        di = CaptureDeviceManager.getDevice(str2);
        ml = di.getLocator();

        try {
            Manager.setHint(Manager.LIGHTWEIGHT_RENDERER, Boolean.TRUE);
            player = Manager.createRealizedPlayer(ml);
            player.start();

            if ((sourceComp = player.getVisualComponent()) != null) {
                sourceComp.addMouseMotionListener(this);
                sourceComp.addMouseListener(this);
                // sourceComp.setBounds (0, 0,
                // sourceComp.getPreferredSize().width,
                // sourceComp.getPreferredSize().height);

                dbPanel = new DoubleBufferPanel();
                dbPanel.setLayout(new BorderLayout());
                dbPanel.add(sourceComp);
                // dbPanel.setBackground(Color.BLUE);
                // dbPanel.setBounds (0, 0, sourceComp.getPreferredSize().width,
                // sourceComp.getPreferredSize().height);

                add(dbPanel, BorderLayout.CENTER);
            }
            add(selectArea, BorderLayout.NORTH);
            add(matchCam, BorderLayout.SOUTH);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        Frame f = new Frame("Test Match WebCam - By Larmor");
        f.setResizable(false);
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                playerclose();
                System.exit(0);
            }
        });

        TestMatchWebCamArea cf = new TestMatchWebCamArea();
        f.add("Center", cf);
        f.pack();
        // f.setSize(new Dimension(320,240));
        f.setVisible(true);

    }

    public static void playerclose() {
        player.close();
        player.deallocate();
    }

    public BufferedImage getPlayerImage() {
        // Grab a frame
        FrameGrabbingControl fgc = (FrameGrabbingControl) player.getControl("javax.media.control.FrameGrabbingControl");
        Buffer buf = fgc.grabFrame();

        // Convert it to an image
        BufferToImage btoi = new BufferToImage((VideoFormat) buf.getFormat());
        Image img = btoi.createImage(buf);

        // Convert to BufferedImage
        BufferedImage bi = new BufferedImage(sourceComp.getPreferredSize().width, sourceComp.getPreferredSize().height, BufferedImage.TYPE_BYTE_GRAY);
        Graphics2D g = bi.createGraphics();
        g.drawImage(img, 0, 0, null);
        g.dispose();

        return bi;
    }

    public void actionPerformed(ActionEvent e) {
        JComponent c = (JComponent) e.getSource();

        if (c == selectArea) {
            stateButton = 1;
            player.stop();
            selectArea.setEnabled(false);

        } else if (c == matchCam) {

            // Validate Area
            if ((areaX >= 0) 
                    && (areaY > 0) 
                    && (areaWidth > 0)
                    && (areaHeight > 0)) {
                buffImgTemplate = getPlayerImage().getSubimage(areaX, areaY, areaWidth, areaHeight);
                MatchTemplate.displayBufferedImage(buffImgTemplate, "template");

                stateButton = 2;
                player.start();
                matchCam.setEnabled(false);
                selectArea.setEnabled(true);
            }
        }
    }

    // @Override
    public void mouseClicked(MouseEvent arg0) {
    }

    // @Override
    public void mouseEntered(MouseEvent arg0) {
    }

    // @Override
    public void mouseExited(MouseEvent arg0) {
    }

    // @Override
    public void mouseMoved(MouseEvent arg0) {
    }

    // @Override
    public void mousePressed(MouseEvent arg0) {
        arg0.consume();
        if (stateButton == 1) {
            areaX = arg0.getX();
            areaY = arg0.getY();
            dbPanel.repaint();
        }
    }

    // @Override
    public void mouseReleased(MouseEvent arg0) {
        arg0.consume();
        if (stateButton == 1) {
            areaWidth = arg0.getX() - areaX;
            areaHeight = arg0.getY() - areaY;
            dbPanel.repaint();
            matchCam.setEnabled(true);
        }
    }

    // @Override
    public void mouseDragged(MouseEvent arg0) {
        arg0.consume();
        if (stateButton == 1) {
            areaWidth = arg0.getX() - areaX;
            areaHeight = arg0.getY() - areaY;
            dbPanel.repaint();
        }
    }

    class DoubleBufferPanel extends Panel {
        Image offscreen;

        /**
         * null out the offscreen buffer as part of invalidation
         */
        public void invalidate() {
            super.invalidate();
            offscreen = null;
        }

        /**
         * override update to *not* erase the background before painting
         */
        public void update(Graphics g) {
            paint(g);
        }

        /**
         * paint children into an offscreen buffer, then blast entire image at once.
         */
        public void paint(Graphics g) {

            if (offscreen == null) {
                offscreen = createImage(getSize().width, getSize().height);
            }

            Graphics og = offscreen.getGraphics();
            og.setClip(0, 0, getSize().width, getSize().height);
            super.paint(og);

            if (stateButton == 1) {
                Graphics2D g2 = (Graphics2D) og;
                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g2.setPaint(Color.red);
                Rectangle2D e = new Rectangle2D.Float(areaX, areaY, areaWidth, areaHeight);
                g2.draw(e);
            } else if (stateButton == 2) {
                // match template
                BufferedImage buffImgSource = getPlayerImage();
                long startTime = System.currentTimeMillis();
                MatchTemplate matchObj = new MatchTemplate(buffImgSource, buffImgTemplate);
                Point matchPoint = matchObj.matchTemplateBestPoint(MatchTemplate.CV_TM_CCOEFF_NORMED);
                long totalTime = System.currentTimeMillis() - startTime;
                System.out.println("totalTime for matching:" + totalTime);

                Graphics2D g2 = (Graphics2D) og;
                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g2.setPaint(Color.green);
                Rectangle2D e = new Rectangle2D.Float(matchPoint.x, matchPoint.y, areaWidth, areaHeight);
                g2.draw(e);
            }

            g.drawImage(offscreen, 0, 0, null);
            og.dispose();
        }
    }

}

Solution

  • The null pointer is caused by the following lines in the constructor of TestMatchWebCamArea:

    String str2 = "vfw:Microsoft WDM Image Capture (Win32):0";
    di = CaptureDeviceManager.getDevice(str2);
    ml = di.getLocator(); //NullPointerException
    

    The only way you can get a NullPointerException on that line is if di == null, so we look at where di is set, and look at the relevant Javadoc:

    Returns: A CaptureDeviceInfo object that corresponds to the specified device name. Returns null if the specified device could not be found.

    It seems therefore that the method can't find a device with the name "vfw:Microsoft WDM Image Capture (Win32):0".

    I've never used the Java Media Framework, but the example given for the method you're calling doesn't look anything like the device name you've provided:

    Parameters: deviceName - A String that contains the name of the device for which you want to get a CaptureDeviceInfo object. For example: "SunVideo"