I need to run Yolo v8 for object detection using OpenCV's DNN in Java. But as there are not examples, I cannot do this properly.
It provides some examples in C++ and Python:
- https://github.com/ultralytics/ultralytics/tree/main/examples/YOLOv8-CPP-Inference
- https://github.com/ultralytics/ultralytics/blob/main/examples/YOLOv8-OpenCV-ONNX-Python/main.py
I tried to convert the C++ version to the following Java version:
Mat img = Imgcodecs.imread(imgPath);
Mat blob = Dnn.blobFromImage(img, 1/255, new Size(640,640), mean, swapRB, crop);
//Sets the input to the network
net.setInput(blob);
//Runs the forward pass to get output of the output layers
List<Mat> outputs = new ArrayList<>();
net.forward(outputs);
int rows = (int) outputs.get(0).size().height;
int dimensions = (int) outputs.get(0).size().width;
if (dimensions > rows) {
rows = (int) outputs.get(0).size().width;
dimensions = (int) outputs.get(0).size().height;
outputs.set(0,outputs.get(0).reshape(1, dimensions));
Core.transpose(outputs.get(0), outputs.get(0));
}
float[] data = new float[rows * dimensions];
outputs.get(0).get(0, 0, data);
float x_factor = img.cols() / 640;
float y_factor = img.rows() / 640;
List<Float> confs = new ArrayList<>();
List<Rect2d> boxes = new ArrayList<>();
for (int i = 0; i < data.length/4; ++i) {
Mat scores = outputs.get(0).row(i);
Core.MinMaxLocResult mm = Core.minMaxLoc(scores);
float confidence = (float) (mm.maxVal/100);
confs.add(confidence);
float x = data[0+i*4];
float y = data[1+i*4];
float w = data[2+i*4];
float h = data[3+i*4];
int left = (int) ((x - 0.5 * w) * x_factor);
int top = (int) ((y - 0.5 * h) * y_factor);
int width = (int) (w * x_factor);
int height = (int) (h * y_factor);
Rect2d box = new Rect2d(left, top, width, height);
boxes.add(box);
}
Mat converted = Converters.vector_float_to_Mat(confs);
MatOfFloat confidences = new MatOfFloat(converted);
Rect2d[] boxesArray = boxes.toArray(new Rect2d[0]);
MatOfRect2d matBoxes = new MatOfRect2d(boxesArray);
//boxes.fromArray(boxesArray);
MatOfInt indices = new MatOfInt();
Dnn.NMSBoxes(matBoxes, confidences, confThreshold, nmsThresh, indices);
int [] ind = indices.toArray();
List<Rect2d> boxesAfterNMS = new ArrayList<>();
for (int i = 0; i < ind.length; ++i)
{
int idx = ind[i];
Rect2d box = boxesArray[idx];
int width = (int)box.width;
int height = (int)box.height;
int left = (int)box.x;
int top = (int)box.y;
boxesAfterNMS.add(new Rect2d(left,top,width,height));
}
But I cannot get the confidence correctly. Any help would be great.