Why the function match of FaceRecognizerSF alterates the feature?

As I known, sorry if I misunderstood, the method match from the class FaceRecognizerSF pass the features as references by using the &. My first question is why?

And then came another doubt crossed my mind the usage of match in this example is correct? Because when we call match by the second time, feature 1 and feature 2 are not the same as in the beggining.
Reference code

feature1, feature2;

faceRecognizer->feature(aligned_face1, feature1);

feature1 = feature1.clone()

faceRecognizer->feature(aligned_face2, feature2);

feature2 = feature2.clone()

double cos_score = faceRecognizer->match(feature1, feature2, FaceRecognizerSF::DisType::FR_COSINE);

double L2_score = faceRecognizer->match(feature1, feature2, FaceRecognizerSF::DisType::FR_NORM_L2);
1 Like

the answer is here:

and i think, you’ve found a bug ! :]
(const things should not be altered)

1 Like

i’d even move the normalize() into the feature() function
as of now, if you match 1 feature against 5 others,
there are 10 normalize() where only 6 are needed

Hey, Berak thanks for answering! I totally agree about the normalize() suggestion. I just reproduced the possible inconsistency, using the example from the OpenCV documentation and some print’s. Take a look about the changing of the features after passing by the match method:

could you do this somehow as TEXT instead of a screenshot ? ty.

First I took this example to my C++ environment and pass an image as input1 and another image as input2, creating 2 templates. After passing by:

// Run feature extraction with given aligned_face

Mat feature1, feature2;

faceRecognizer->feature(aligned_face1, feature1);

feature1 = feature1.clone()

faceRecognizer->feature(aligned_face2, feature2);

feature2 = feature2.clone()

Despite that, my templates are changed after passing by the method match, even with the type const in the declaration of match method in face_recognize.cpp.

double match(InputArray _face_feature1, InputArray _face_feature2, int dis_type) const override
    {
        Mat face_feature1 = _face_feature1.getMat(), face_feature2 = _face_feature2.getMat();
        normalize(face_feature1, face_feature1);
        normalize(face_feature2, face_feature2);

        if(dis_type == DisType::FR_COSINE){
            return sum(face_feature1.mul(face_feature2))[0];
        }else if(dis_type == DisType::FR_NORM_L2){
            return norm(face_feature1, face_feature2);
        }else{
            throw std::invalid_argument("invalid parameter " + std::to_string(dis_type));
        }

    };

The main idea is the features generated along the code aren’t supposed to be imuttable? This doubt came because I’m testing deploying a facial server with Yunet and SFace, which I have to compare each template from different user for enroll. But after passing to many comparsions in match, my templates are changing their original value. The path I followed to work around this problem is creating clones, even between cos_score and l2_score but this sounds weird and maybe there’s a real bug as you said.