Search code examples
javatensorflowopencvdeep-learningcaffe

OpenCV Vector Subscript out of range error in java


I'm trying to write a AgeGender Guessing program in Java with OpenCV. I'm having problems with the DNN running to recognise faces. I have started adding code to debug my program.

package AgeGenderCV;

import java.util.ArrayList;
import java.util.List;

import org.opencv.core.Core;
import org.opencv.core.Point;
import org.opencv.core.Mat;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.dnn.Dnn;
import org.opencv.dnn.Net;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.videoio.VideoCapture;

public class AgeGenderCV {
    private static final String[] GENDER_LIST = {"Male", "Female"};
    private static final String[] AGE_LIST = {"(0-2)", "(4-6)", "(8-12)", "(15-20)", "(25-32)", "(38-43)", "(48-53)", "(60-100)"};
    private static final double[] MODEL_MEAN_VALUES = {78.4263377603, 87.7689143744, 114.895847746};
    private static final double CONFIDENCE_THRESHOLD = 0.7;

    public void ProcessImage(){
        // Load networks
        Net faceNet = Dnn.readNetFromTensorflow("opencv_face_detector_uint8.pb", "opencv_face_detector.pbtxt");
        Net ageNet = Dnn.readNetFromCaffe("age_deploy.prototxt", "age_net.caffemodel");
        Net genderNet = Dnn.readNetFromCaffe("gender_deploy.prototxt", "gender_net.caffemodel");
        
        
        // Open a video file or an image file or a camera stream
        VideoCapture cap;
        //if (args.length > 0) {
        //    cap = new VideoCapture(args[0]);
        //} else {
            cap = new VideoCapture(0);
        //}

        while (true) {
            // Read frame
            Mat frame = new Mat();
            cap.read(frame);
            
            // Get face bounding boxes
            Mat frameFace = frame.clone();
            //Imgcodecs.imwrite("frame.jpg", frameFace);
            
            List<Rect> bboxes = new ArrayList<>();
            Size size = new Size(300,300);
            System.out.println("Size : "+size);
            
            Scalar scalar = new Scalar(104, 117, 123);
            System.out.println("Scalar : "+scalar);
            
            Mat blob = Dnn.blobFromImage(frameFace, 1.0, size, scalar, false, false);
            System.out.println("blob : "+blob);
            
            faceNet.setInput(blob);
            System.out.println("FaceNet : "+faceNet);
            
            Mat detections = faceNet.forward();
            System.out.println("detections : "+detections);
            
            for (int i = 0; i < detections.size().height; i++) {
                System.out.println("i : "+i);
                //double confidence = detections.get(0, 0, i, 2)[0];
                double confidence;
                confidence = detections.get(i, 2)[0];
                if (confidence > CONFIDENCE_THRESHOLD) {
                    int x1 = (int) (detections.get(i, 3)[0] * frame.cols());
                    int y1 = (int) (detections.get(i, 4)[0] * frame.rows());
                    int x2 = (int) (detections.get(i, 5)[0] * frame.cols());
                    int y2 = (int) (detections.get(i, 6)[0] * frame.rows());
                    bboxes.add(new Rect(x1, y1, x2 - x1, y2 - y1));
                    Imgproc.rectangle(frameFace, new org.opencv.core.Point(x1, y1), new org.opencv.core.Point(x2, y2), new org.opencv.core.Scalar(0, 255, 0), (int) Math.round(frame.rows() / 150), 8, 0);
                }
            }


        if (bboxes.isEmpty()) {
            System.out.println("No face Detected, Checking next frame");
            continue;
        }

        for (Rect bbox : bboxes) {
            Mat face = new Mat(frame, bbox);
            Size sizeb = new Size(227,227);
            Scalar scalarb = new Scalar(MODEL_MEAN_VALUES);
            blob = Dnn.blobFromImage(face, 1.0, sizeb, scalarb, false);
            genderNet.setInput(blob);
            Mat genderPreds = genderNet.forward();
            String gender = GENDER_LIST[(int) genderPreds.get(0, 0)[0]];
            //System.out.println("Gender Output : " + genderPreds);
            System.out.println("Gender : " + gender + ", conf = " + genderPreds.get(0, 0)[0]);

            ageNet.setInput(blob);
            Mat agePreds = ageNet.forward();
            agePreds = agePreds.reshape(1, 1); // reshape to 2D matrix with one row
            //Point maxLoc = new Point(); // !!! not assiged !!!
            //Core.minMaxLoc(agePreds);
            //int ageIdx = (int) maxLoc.x; // !!! uninitialized !!!
             Core.MinMaxLocResult mm = Core.minMaxLoc(agePreds);
             int ageIdx = (int) mm.maxLoc.x;  

            //Imgcodecs.imwrite("age-gender-out-"+args[0]+".jpg", frameFace);
            //Imgcodecs.imwrite("age-gender-out-.jpg", frameFace);
            System.out.println("Age : " + AGE_LIST[ageIdx] + ", conf = " + agePreds.get(0, ageIdx)[0]);
        }
        cap.release();
        }
    }
    
    public static void main(String args[])
    {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        System.loadLibrary("opencv_java470");
        
        AgeGenderCV example = new AgeGenderCV();
        example.ProcessImage();
    }
}

Output - AgeGenderCV (run) run: [ INFO:[email protected]] global tf_importer.cpp:3014 cv::dnn::dnn4_v20221220::anonymous-namespace'::TFImporter::populateNet DNN/TF: parsing model (N/A version info). Number of nodes = 570 [ INFO:[email protected]] global tf_importer.cpp:3021 cv::dnn::dnn4_v20221220::anonymous-namespace'::TFImporter::populateNet DNN/TF: parsing config (N/A version info). Number of nodes = 145 Attempting to upgrade input file specified using deprecated V1LayerParameter: age_deploy.prototxt Successfully upgraded file specified using deprecated V1LayerParameter Attempting to upgrade input file specified using deprecated V1LayerParameter: age_net.caffemodel Successfully upgraded file specified using deprecated V1LayerParameter Attempting to upgrade input file specified using deprecated V1LayerParameter: gender_deploy.prototxt Successfully upgraded file specified using deprecated V1LayerParameter Attempting to upgrade input file specified using deprecated V1LayerParameter: gender_net.caffemodel Successfully upgraded file specified using deprecated V1LayerParameter Size : 300x300 Scalar : [104.0, 117.0, 123.0, 0.0] blob : Mat [ 13300300CV_32FC1, isCont=true, isSubmat=false, nativeObj=0x1ef8ecf6270, dataAddr=0x1ef9a76c080 ] FaceNet : org.opencv.dnn.Net@b81eda8 C:\Users\cam30\AppData\Local\NetBeans\Cache\16\executor-snippets\run.xml:111: The following error occurred while executing this line: C:\Users\cam30\AppData\Local\NetBeans\Cache\16\executor-snippets\run.xml:68: Java returned: -2147483645 BUILD FAILED (total time: 7 seconds)

Vector subscript out of range Error Message


Solution

  • For what its worth: I ran into this with version 4.7.0-0. Going back to 4.5.5.-1 fixed it for me.