Eric Love
Eric Love

Reputation: 35

Getting nullPointer in image recognition attempt

I am getting a nullPointerError on the CascadeClassifier in triDetect. I need to write a code to find the number of circles, triangles, rectangles, and lines. Please do not roast this code it is terrible but I really need help. If you have any suggestions or help please give whatever advice you can. I need this done in the next two days (today is june 15 2019) so if it is past that you don't need to spend time on this. Please offer any help in making this better and solving my issue. Thank you.

I have tried changing the cascadeclassifier to other things but i believe this is the best way. Please help.

public class main extends JComponent implements MouseInputListener {
    static int rects = 0;
    static int triangles = 0;
    static int circles = 0;
    static int lines = 0;

    public static void main(String[] args) throws AWTException, IOException {
        System.loadLibrary( Core.NATIVE_LIBRARY_NAME );

        Robot robot = new Robot();
        Rectangle screenSize = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
        BufferedImage image = robot.createScreenCapture(screenSize);    


            JFrame window = new JFrame("Image Recognition");
            main run = new main();
            window.add(run, BorderLayout.CENTER);
            window.pack();
            window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

            window.setVisible(true);
            window.setSize(300,500); //300,500

            window.addMouseListener(run);

            ImageIcon icon = new ImageIcon(image);
            JLabel lbl=new JLabel();
            lbl.setIcon(icon);
            window.add(lbl);

            window.repaint();


            File outputFile = new File("image.jpg");
            ImageIO.write(image, "jpg", outputFile);
            File input = new File("C:\\Users\\ericl\\eclipse-workspace\\ImageRecognition\\image.jpg");
            BufferedImage buffImage = ImageIO.read(input);
            BufferedImage imageCopy =
                    new BufferedImage(buffImage.getWidth(), buffImage.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
            imageCopy.getGraphics().drawImage(buffImage, 0, 0, null);

            byte[] data = ((DataBufferByte) imageCopy.getRaster().getDataBuffer()).getData();  


            Mat mat = new Mat(image.getHeight(),image.getWidth(), CvType.CV_8UC3);
            mat.put(0, 0, data);           
            Imgcodecs.imwrite("C:\\Users\\ericl\\eclipse-workspace\\ImageRecognition\\input.jpg", mat);



            new main().detectTris(mat);

            window.repaint();

        }

    public void detectTris(Mat mat) {
        System.out.println("\nRunning detection");

        CascadeClassifier shapeDetector = new CascadeClassifier(getClass().getResource("C:\\Users\\ericl\\eclipse-workspace\\OpenCVImageRecognition\\shapes\\triEx.jpg").getPath());

        MatOfRect triDetections = new MatOfRect();
        shapeDetector.detectMultiScale(mat, triDetections);

        System.out.println(String.format("Detected %s triangles", triDetections.toArray().length));
    }


    public void paint(Graphics g) {
        String strRect = String.valueOf(rects);
        String strTri = String.valueOf(triangles);
        String strCirc = String.valueOf(circles);
        String strLine = String.valueOf(lines);
        g.setColor(Color.white);
        g.fillRect(90,10,200,400);
        g.setColor(Color.red);
        g.setFont(new Font("Comic Sans", Font.PLAIN, 80));
        g.drawString(strRect, 100, 100);
        g.drawString(strTri, 100, 200);
        g.drawString(strCirc, 100, 300);
        g.drawString(strLine, 100, 400);
        g.fillRect(200, 40, 60, 60);
        int y[] = {200,150,200}; 
        int x[] = {200,230,260};
        g.fillPolygon(x,y, 3);
        g.fillOval(200, 240, 55, 55);
        g.fillRect(220, 340, 5, 60);
    }
}

Expecting output to be a window with the amount of each shape from the screenshot in red.

Upvotes: 0

Views: 58

Answers (1)

Stephen C
Stephen C

Reputation: 718946

You are getting an NPE because you are using getResource incorrectly.

    getClass().getResource(
        "C:\\Users\\ericl\\eclipse-workspace\\OpenCVImageRecognition\\shapes\\triEx.jpg")
        .getPath()

The getGetResource method requires a resource path. You have given it a full (absolute) file system path. The getGetResource is then attempting to look that up in the resource namespace and failing.

Solution:

  1. Read up on how resource search actually works. For example: Location-Independent Access to Resources
  2. Read the javadoc for CascadeClassifier
  3. Decide if you should be using resources in this context.
  4. If you decide to continue trying to use resources:
    1. Ensure that the resource you are trying to load actually is a JAR file (or directory tree) that is on the application's runtime classpath.
    2. Correct the resource path you are using.
    3. Work out how to deal with the case where the resource is not a file in the file system ... which is what CascadeClassifier requires.
  5. If you decide to use a regular file, change your code to something like the following:

CascadeClassifier shapeDetector = new CascadeClassifier(
    "C:\\Users\\ericl\\eclipse-workspace\\OpenCVImageRecognition\\shapes\\triEx.jpg");

Upvotes: 1

Related Questions