Vector Subscript out of range error in Java

Hi I’m getting a Vector Subscript out of range error and the error messages aren’t pointing me in the right direction, Help!

run

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 ageNet = Dnn.readNetFromCaffe("age_deploy.prototxt", "age_net.caffemodel");
        Net genderNet = Dnn.readNetFromCaffe("gender_deploy.prototxt", "gender_net.caffemodel");
        Net faceNet = Dnn.readNetFromTensorflow("opencv_face_detector_uint8.pb", "opencv_face_detector.pbtxt");
        
        // 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();
            List<Rect> bboxes = new ArrayList<>();
            Size size = new Size(300,300);
            Scalar scalar = new Scalar(104, 117, 123);
            Mat blob = Dnn.blobFromImage(frameFace, 1.0, size, scalar, false, false);
            faceNet.setInput(blob);
            Mat detections = faceNet.forward();
            for (int i = 0; i < detections.size().height; 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();
            Core.minMaxLoc(agePreds);
            int ageIdx = (int) 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();
    }
}

hmm, that’s neither a java nor an opencv exception, but deep down from the ms c++ runtime …

are you able to debug it in java (at least to find which line it happens) ?

only problem, i can spot w/o trying actual code (cant, sorry)
is here:

        Point maxLoc = new Point(); // !!! not assiged !!!
        Core.minMaxLoc(agePreds);
        int ageIdx = (int) maxLoc.x;   // !!! uninitialized !!!

imo, you need something like:

 Core.MinMaxLocResult mm = Core.minMaxLoc(agePreds);
 int ageIdx = (int) mm.maxLoc.x;  

see docs

I still had the error even though this might have fixed another issue later down the line.

I added lots of debugging println for various parts of the code and it appears that line Mat detections = faceNet.forward(); dosen’t run properly?

how would I know ? and what do you mean there ?
so you dont even get to the uninitialized ageidx ?

So I added some lines of code!

            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);
run:
[ INFO:0@0.116] 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
Attempting to upgrade input file specified using deprecated V1LayerParameter: age_deploy.prototxt
[ INFO:0@0.116] 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
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 [ 1*3*300*300*CV_32FC1, isCont=true, isSubmat=false, nativeObj=0x180e7be7f50, dataAddr=0x180f10ce080 ]
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: 6 seconds)
1 Like

related:

Any sugestions, as i don’t know how to further debug my code?

This might been a wierd one.

I ran the same models in python and they worked. There appears to be a problem with the faceNet TensorFlow model in opencv 4.7.0 in java jdk 18.

I then replaced the model with another 8bit onnx one and it ran, but I’m having a diffrent problem with my code, that I’m now debugging.

Hi there,
I’m trying to set up a pose estimation application with java as well. I am also getting the Vector Subscript out of range error with OpenCV 4.7.0-dev.

As the example above, the code fails when calling the net.forward() function.

Another thing that came to my attention is that the file path from the Debug Assertion Fail, C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\include\vector, is an invalid path on my device. I only have MS VS Professional edition installed thus the Community directory doesn’t exist.

What type (tensorflow/caffe/onnx) and name of the model are you using?

1 Like

it’s from the machine, the library code was built upon (somewhere in the cloud), not your box

1 Like

I installed OpenPose which contains multiple models for hand, face, and pose estimation. They are all Caffe-model types. I have tried iter_584000 and iter_440000 for pose estimation so far.

I remember reading that some models dont work in java, but i cant find the github issue.

Try the model in python, so we can pin it down to being a java, rather than a bad model problem?

I am not too familiar with Python, but I can try and take a look at it. The OpenPose dir has instructions for both Python and C++. I believe OpenPose would be compatible with those languages. I’ve also seen the iter_440000 model used in older java projects like this one: openpose java sample · GitHub

Rather than the models being bad, I think it’s more likely a compatibility error with the newest version of OpenCV since some of the models seemed to work previously.

Update:

I found a potential solution. Running OpenCV 3.4.16 instead of 4.7.0 fixed the error for me. All the code I use is compatible with this version. It seems that the error is within the 4.7.0 library.

I managed to run the iter 440000 Caffe model in the older version. My result images are inaccurate, but I believe this is optimisable through the code. I tried running iter 584000 as well in this configuration, but that model failed to work.

I don’t know if the age-, gender- and face-net are compatible with this version, but I’d say it is worth the try.