OpenCV face recognition training model return unrealistic label index and confidence value

I wrote the following codes in Java using OpenCV 4.8.0 and try to train the faces lies in subdirectory within a specified directory, then perform a “predict” to test the confidence values.

It seems the results are always return predictedLabel = 0 and confidence values do not realistic. My test cases expect to return false (e.g. predictedLabel should equal -1 for not found), and why the confidence level > 100? Any hints for this?

import java.io.File;
import java.util.LinkedList;
import java.util.List;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.face.LBPHFaceRecognizer;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import com.jos.cv.detect.ModelExecutionResult;

public class FaceScanner {

static {
	System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}

private final CascadeClassifier classifier;

private final LBPHFaceRecognizer model;

public FaceScanner(FaceScannerParam param) {
	classifier = new CascadeClassifier(param.cascadeClassifierFile);
	model = LBPHFaceRecognizer.create();
	trainDataSet(param.trainDataPath);
}

private Mat extractfaces(Mat src) {
	MatOfRect features = new MatOfRect();
	classifier.detectMultiScale(src, features);

	if (features.total() > 0) {
		Mat img_gray = src.clone();
		Imgproc.cvtColor(src, img_gray, Imgproc.COLOR_RGB2GRAY);
		return img_gray.submat(features.toArray()[0]);
	}
	return null;
}

public void execute(Mat mat) {
	Mat face = extractfaces(mat);
	if (face != null) {
		int[] predictedLabel = { -1 };
		double[] confidence = { 0 };
		model.predict(face, predictedLabel, confidence);
		System.out.println("predictedLabel: " + predictedLabel[0] + ", confidence: " + confidence[0]);
	} else {
		System.out.println("no face detected from the test image");
	}		
}

private void trainDataSet(String trainingDataPath) {
	File directory = new File(trainingDataPath);
	File[] files = directory.listFiles();
	List<Mat> faceSamples = new LinkedList<>();
	List<Integer> faceIds = new LinkedList<>();

	Mat labelsMat;

	int faceId = 0;
	for (File file : files) {
		if (file.isDirectory()) {
			System.out.println("Images in directory: " + file.getAbsolutePath());
			File[] imageFiles = file.listFiles();
			for (File imageFile : imageFiles) {
				Mat src = Imgcodecs.imread(imageFile.getAbsolutePath());
				Mat face = extractfaces(src);
				if (face != null) {
					faceSamples.add(face);
					faceIds.add(faceId);
					System.out.println("Train data " + faceId + " (" + imageFile.getAbsolutePath() + ") added");
				} else {
					System.out.println("Train data " + faceId + " (" + imageFile.getAbsolutePath() + ") not added");
				}
			}
			faceId++;
		}
	}

	labelsMat = new Mat(faceIds.size(), 1, CvType.CV_32SC1);
	model.train(faceSamples, labelsMat);
}

public static void main(String[] args) {
	FaceScannerParam faceScannerParam = new FaceScannerParam();
	faceScannerParam.cascadeClassifierFile = "..\\lbpcascade_frontalface.xml";
	faceScannerParam.trainDataPath = "E:\\Test\\faces\\train";
	String testImagePath = "E:\\Test\\faces\\";

	FaceScanner faceScanner = new FaceScanner(faceScannerParam);

	File directory = new File(testImagePath);
	File[] files = directory.listFiles();
	for (File file : files) {
		if (file.isFile()) {
			Mat mat = Imgcodecs.imread(file.getAbsolutePath());
			System.out.println("#############################################");
			System.out.println("Testing file " + file.getAbsolutePath());
			faceScanner.execute(mat);
			System.out.println("#############################################");
		}
	}		
}

}

Execution Result:

Images in directory: E:\Test\faces\train\chan

Train data 0 (E:\Test\faces\train\chan\1.png) added

libpng warning: iCCP: known incorrect sRGB profile

libpng warning: iCCP: cHRM chunk does not match sRGB

Train data 0 (E:\Test\faces\train\chan\2.png) added

Train data 0 (E:\Test\faces\train\chan\3.png) added

Train data 0 (E:\Test\faces\train\chan\4.png) added

Train data 0 (E:\Test\faces\train\chan\5.png) not added

Train data 0 (E:\Test\faces\train\chan\6.png) added

Train data 0 (E:\Test\faces\train\chan\7.jpg) added

Train data 0 (E:\Test\faces\train\chan\8.jpg) added

Images in directory: E:\Test\faces\train\chow

Train data 1 (E:\Test\faces\train\chow\a1.png) added

Train data 1 (E:\Test\faces\train\chow\a2.png) not added

Train data 1 (E:\Test\faces\train\chow\a3.png) added

Train data 1 (E:\Test\faces\train\chow\a4.png) added

Train data 1 (E:\Test\faces\train\chow\a5.jpg) added

Train data 1 (E:\Test\faces\train\chow\a6.png) added

#############################################

Testing file E:\Test\faces\a4.png

predictedLabel: 0, confidence: 0.0

#############################################

#############################################

Testing file E:\Test\faces\t1.png

predictedLabel: 0, confidence: 0.0

#############################################

#############################################

Testing file E:\Test\faces\t2.png

predictedLabel: 0, confidence: 80.45719377729274

#############################################

#############################################

Testing file E:\Test\faces\t3.png

predictedLabel: 0, confidence: 50.761764630916694

#############################################

#############################################

Testing file E:\Test\faces\t4.jpg

predictedLabel: 0, confidence: 151.99212260963574

#############################################

your ‘confidence’ is somehow a misnomer,
it’s actually the (chi-sqr) distance , so, smaller== better !

a ‘perfect’ 0.0 distance means: identity, so you must be testing with your train images again (bad idea)