Bug 444394

Summary: Rejected face suggestions reappear for the same person the next time recognition is run
Product: [Applications] digikam Reporter: griffiths_andy
Component: Faces-RecognitionAssignee: Digikam Developers <digikam-bugs-null>
Status: RESOLVED FIXED    
Severity: normal CC: carlo.mj.m, caulier.gilles, chrisc.gigamail, frieder, iwannaberich, michael.zoehrer, michael_miller, sendchrissomejunk, sven.burmeister, thilo.grundmann
Priority: NOR    
Version First Reported In: 7.3.0   
Target Milestone: ---   
Platform: Arch Linux   
OS: Linux   
Latest Commit: Version Fixed/Implemented In: 8.7.0
Sentry Crash Report:

Description griffiths_andy 2021-10-25 23:16:25 UTC
SUMMARY
If a group of faces are rejected (not ignored) as not being a particular person, then the next time the recognition is run, they appear again as suggestions for that same particular person, and again have to be tediously rejected.

They are other people, who may in time get their own face tag, or may already have one, but the effort to chop and change the name would be too much while trying to concentrate on one particular person. Because of this it would be incorrect to 'ignore' the rejections.

I'm aware of the solution offered in #392023 but I feel it is not a good approach.If I were to ignore faces instead I would have to un-ignore them each time before hoping they get picked up as a different face once more training data has been processed.  It would be inevitable they would be categorised yet again as persons I have already rejected. 

I would expect the application to maintain a relationship between detected faces and the face tags which it has been confirmed it is NOT a match with. But this appears not to be implemented otherwise the same false positives would not reappear.

STEPS TO REPRODUCE
1. Run face recognition
2. Reject the false suggestions for a particular person
3. Rerun face detection, the same false suggestions reappear.

OBSERVED RESULT
On rerunning recognise faces. rejected faces reappear for the same person I have just rejected them from

EXPECTED RESULT
Rejected faces remain in the 'Unknown' category, unless a newer match has been made for them. This would be implemented by a database relationship indicating a negative match between person and detected face whenever a suggestion is rejected.


SOFTWARE/OS VERSIONS
Windows: 
macOS: 
Linux/KDE Plasma: 
(available in About System)
KDE Plasma Version:  
KDE Frameworks Version: 5.87.0
Qt Version: 5.15.2

ADDITIONAL INFORMATION
Comment 1 griffiths_andy 2021-10-25 23:22:44 UTC
Forgot to add. Of course, when a face is positively confirmed then all its negative confirmations can be removed.
Comment 2 Thilo 2021-10-30 06:44:39 UTC
Maybe an alternative solution to this problem could be to maintain information for a face tag on which persons it is definitivly not. Marking it as "unknown" could be seen as a rejection to all persons in the database at the time of marking (or only to the false recognition result itself).

When the recognition is rerun (unchanged database) the person would be identified falsely to the former person again, but now we have the information "not this person" - which results then in a result "unknown"

if at a later recognition run, more persons are known, and the classification result to a new person is displayed as recognition result and may be correct or wrong (when the procedure starts again)
Comment 3 griffiths_andy 2021-10-30 12:32:36 UTC
(In reply to Thilo from comment #2)
> Maybe an alternative solution to this problem could be to maintain
> information for a face tag on which persons it is definitivly not. Marking
> it as "unknown" could be seen as a rejection to all persons in the database
> at the time of marking (or only to the false recognition result itself).
> 
> When the recognition is rerun (unchanged database) the person would be
> identified falsely to the former person again, but now we have the
> information "not this person" - which results then in a result "unknown"
> 
> if at a later recognition run, more persons are known, and the
> classification result to a new person is displayed as recognition result and
> may be correct or wrong (when the procedure starts again)

Thanks for the support. You're effectively stating the same as me I feel though.

All that is needed is a one to many relationship between a face tag and an unknown face that carries the weight of it being a rejected match. Once a face becomes positively identified all rejected relationships are removed. In most cases this will only be one rejected relationship as the face was otherwise always being related wrongly to on tag.

But yes, if a recognition rerun finds an existing rejection then the face remains in 'unknown' (your 2nd para).
Comment 4 S. Burmeister 2022-07-28 14:24:52 UTC
Does rejecting educate the detection engine or does it only learn from confirmations? 

I have people with 400 confirmed faces and still digikam suggests the same wrong faces each time I re-run the detection. So it seems to me that the engine does not get any negative feedback and hence does not learn from rejections.
Comment 5 Maik Qualmann 2023-04-23 17:06:05 UTC
*** Bug 468867 has been marked as a duplicate of this bug. ***
Comment 6 Chris 2023-10-17 08:32:54 UTC
(In reply to S. Burmeister from comment #4)
> Does rejecting educate the detection engine or does it only learn from
> confirmations? 
> 
> I have people with 400 confirmed faces and still digikam suggests the same
> wrong faces each time I re-run the detection. So it seems to me that the
> engine does not get any negative feedback and hence does not learn from
> rejections.

I agree. I would also like this feature. 

Possibly it could be done with a model similar to the one that connects confirmed and unconfirmed face tags to face regions. There could be a rejected category as well. Rejections should of course be cancellable again (if you reject by mistake).

To make it even more useful, maybe a large rejection value could be applied to the face recognition, for every face tag, in order to make the recognition value make the a second best suggestion.
It won't really "educate" the face recognition, but it will be helpful to the end user when running recognition again.
Comment 7 CM 2024-05-31 04:46:37 UTC
I'd like this feature also.
Comment 8 Chris D 2024-09-16 05:06:51 UTC
I agree, I have this problem too.  I have stopped bothering to reject suggestions, since it is apparently a waste of time (the program doesn't do anything with the information that the suggestion is not a match, so there's no benefit to rejecting as far as I can tell).  I just leave them as unknown, because they will end up that way again anyway next time I rescan everything (which the instructions say you should do once in a while for better accuracy).

Same with ignoring, I tried ignoring false face IDs when rejecting didn't keep them from popping back up, but everything I've ignored resets on a new scan.  So every face ID I've tried to ignore always pops back up on a rescan.

So hopefully it's a bug (and not an oversight) that the program behaves this way...you would expect the information gained by ignoring and rejecting faces would not be temporary.  If it's not used to improve the face recognition, at the least it should be stored to keep duplicate work from being created.
Comment 9 caulier.gilles 2024-10-08 09:30:15 UTC
Hi Michael,

I'm not sure if this problem is fully relevant of the recognition DNN models...

Best

Gilles
Comment 10 Michael Miller 2024-10-10 23:19:53 UTC
Yes, this is a known issue.  The problem is digiKam doesn't save which suggestion has been rejected as a match for a tagged face.  It's something I'm researching for the next rewrite of the FaceDB.  The other challenge is how to undo an accidental rejection.

For now, I suggest you either tag the face if you know who it is, or ignore it.  Either option will keep the suggestion from appearing again.

Cheers,
Mike
Comment 11 caulier.gilles 2024-12-01 09:04:01 UTC
digiKam 8.5.0 is out with many improvements in face detection and recognition. Please update these entry accordingly with this version. Thanks in advance...

https://www.digikam.org/news/2024-11-16-8.5.0_release_announcement/
Comment 12 Chris D 2024-12-01 11:22:40 UTC
I have been using 8.5 for a couplea weeks, and it is MUCH improved, so thanks to everyone for the hard work.  Many more faces in my collection have been identified, although still odd non-face results and such.  Hopefully it's downhill from here!

But I wonder, has the subject of this thread been addressed yet?  Does this update make the rejection of wrong identifications helpful or meaningful?  Or should we just continue to ignore wrong suggestions?

Thanks!
Chris
Comment 13 Michael Miller 2024-12-13 18:36:52 UTC
(In reply to Chris D from comment #12)
> I have been using 8.5 for a couplea weeks, and it is MUCH improved, so
> thanks to everyone for the hard work.  Many more faces in my collection have
> been identified, although still odd non-face results and such.  Hopefully
> it's downhill from here!
> 
> But I wonder, has the subject of this thread been addressed yet?  Does this
> update make the rejection of wrong identifications helpful or meaningful? 
> Or should we just continue to ignore wrong suggestions?
> 
> Thanks!
> Chris

Hi Chris,
digiKam does not keep track of rejected face matches, and the same face will appear in the next recognition pass.  The best way to avoid this is to either "ignore" the face, or confirm the face with a new name.  Future recognition passes will either ignore the face, or match the face to the new confirmed name.
Comment 14 MarcP 2025-03-18 22:47:57 UTC
I'd would also love this feature.

My workflow is the following.
1) I detect faces
2) I manually tag a bunch of them
3) I select all faces, and ran the recognition again. I get many results
4) I confirm the good ones and reject the bad ones.
5) I re-run the recognition again. More faces are recognized correctly.
6) rinse and repeat. 

I'd love a way for digikam to keep track of which faces I already rejected from each person, so it doesn't reassign it to the same one. Maybe try with the next best match instead. (I believe this is similar to request #432207)
Comment 15 Michael Miller 2025-03-18 23:37:25 UTC
Hi Marc,
If the faces you are rejecting are faces that will never have tags, then the correct action is to Ignore the face instead of rejecting the face.  If the suggested face match is incorrect and should be applied to someone else, then you should change the name and confirm the new name.

This will prevent the faces from being presented again, and help train the AI by providing the correct name for an incorrect match.

Cheers,
Mike
Comment 16 MarcP 2025-03-18 23:42:43 UTC
(In reply to Michael Miller from comment #15)
> Hi Marc,
> If the faces you are rejecting are faces that will never have tags, then the
> correct action is to Ignore the face instead of rejecting the face.  If the
> suggested face match is incorrect and should be applied to someone else,
> then you should change the name and confirm the new name.
> 
> This will prevent the faces from being presented again, and help train the
> AI by providing the correct name for an incorrect match.
> 
> Cheers,
> Mike

By rejection, I mean that the suggested face is not correct and I click the "-" sign to reject it. The thing is, I may not know who that person is (I've got thousands of shared pictures with my family), this is in part why I use face recognition, so I want digikam to try again once it has more information about faces. 

This is essentially how Picasa worked in its day, it continuously reassigned detected faces to people based on the most likely face, without needing to manually run face recognition.

I'm not asking for that, but just that it would be useful that digikam remembers that a particular face does not belong to a specific person, so it can try again with a different suggestion.
Comment 17 Michael Miller 2025-04-02 17:45:58 UTC
Git commit 7cd0b91e4e18e7d513e941f80007bffb66bb08b8 by Michael Miller.
Committed on 02/04/2025 at 17:45.
Pushed by michmill into branch 'master'.

Work/michmill/facebackgroundprocess

- A new recognize only face scan is started whenever the face training data is modified.
- Added logic to ensure incompatible face scan types do not run at the same time
Related: bug 501690

M  +6    -4    core/app/items/views/digikamitemview.cpp
M  +7    -2    core/app/main/digikamapp.cpp
M  +13   -2    core/app/main/digikamapp_tools.cpp
M  +23   -16   core/app/views/sidebar/peoplesidebarwidget.cpp
M  +26   -42   core/app/views/stack/itemiconview_search.cpp
M  +10   -2    core/libs/album/treeview/albumselectiontreeview.cpp
M  +6    -15   core/libs/facesengine/recognition/faceclassifier.cpp
M  +7    -2    core/libs/facesengine/recognition/faceclassifier.h
M  +5    -1    core/libs/facesengine/widgets/facescansettings.cpp
M  +28   -1    core/libs/facesengine/widgets/facescansettings.h
M  +9    -8    core/libs/mlfoundation/mlpipelinefoundation.cpp
M  +1    -0    core/libs/mlfoundation/mlpipelinefoundation.h
M  +2    -2    core/libs/mlfoundation/mlpipelinemacros.h
M  +1    -1    core/libs/tags/autoassignment/pipelines/object/autotagspipelineobject.cpp
M  +3    -0    core/utilities/facemanagement/CMakeLists.txt
A  +221  -0    core/utilities/facemanagement/backgroundprocesses/facebackgroundrecognition.cpp     [License: GPL(v2.0+)]
A  +61   -0    core/utilities/facemanagement/backgroundprocesses/facebackgroundrecognition.h     [License: GPL(v2.0+)]
M  +1    -1    core/utilities/facemanagement/pipelines/detectrecognize/facepipelinedetectrecognize.cpp
M  +5    -5    core/utilities/facemanagement/pipelines/recognize/facepipelinerecognize.cpp
M  +1    -1    core/utilities/facemanagement/pipelines/reset/facepipelinereset.cpp
M  +1    -1    core/utilities/facemanagement/pipelines/retrain/facepipelineretrain.cpp
M  +1    -0    core/utilities/maintenance/main/maintenancedlg_settings.cpp
M  +13   -3    core/utilities/maintenance/manager/maintenancemngr.cpp
M  +161  -18   core/utilities/maintenance/tools/facesmanagement/facesengine.cpp
M  +4    -4    core/utilities/maintenance/tools/facesmanagement/facesengine.h
M  +1    -1    project/bundles/homebrew/config.sh

https://invent.kde.org/graphics/digikam/-/commit/7cd0b91e4e18e7d513e941f80007bffb66bb08b8
Comment 18 Michael Miller 2025-04-18 10:55:13 UTC
Git commit 499d41cee5f7422e9951ed9c097d898568f7046d by Michael Miller.
Committed on 18/04/2025 at 10:55.
Pushed by michmill into branch 'master'.

Save rejected face data

Save rejected face tags and exclude the tags from being used during face classification (matching).

This MR does not include code to write the rejected face tags to the item metadata.  That will be a different MR in the next several days.

This MR does not include the ability to clear the reject face data. That will be a different MR in the next several days.
Related: bug 502219, bug 432207, bug 415783, bug 502924

M  +5    -0    core/libs/database/coredb/coredbconstants.cpp
M  +1    -0    core/libs/database/coredb/coredbconstants.h
M  +137  -13   core/libs/database/tags/facetagseditor.cpp
M  +15   -3    core/libs/database/tags/facetagseditor.h
M  +135  -28   core/libs/database/tags/facetagsiface.cpp
M  +52   -6    core/libs/database/tags/facetagsiface.h
M  +29   -28   core/libs/facesengine/recognition/faceclassifier.cpp
M  +17   -11   core/libs/facesengine/recognition/faceclassifier.h
M  +2    -0    core/libs/facesengine/recognition/faceclassifierbase.cpp
M  +2    -0    core/libs/facesengine/recognition/faceclassifierbase.h
M  +35   -36   core/libs/facesengine/recognition/identityprovider.cpp
M  +4    -1    core/libs/facesengine/widgets/facescansettings.cpp
M  +8    -6    core/libs/mlfoundation/mlclassifierfoundation.h
M  +4    -3    core/libs/tags/autoassignment/classifiers/minmax/autotagsclassifierminmax.cpp
M  +10   -8    core/libs/tags/autoassignment/classifiers/minmax/autotagsclassifierminmax.h
M  +9    -5    core/libs/tags/autoassignment/classifiers/multiclassyolo/autotagsclassifiermultiyolo.h
M  +5    -3    core/libs/tags/autoassignment/classifiers/softmax/autotagsclassifiersoftmax.cpp
M  +10   -8    core/libs/tags/autoassignment/classifiers/softmax/autotagsclassifiersoftmax.h
M  +25   -0    core/utilities/facemanagement/database/faceutils.cpp
M  +10   -1    core/utilities/facemanagement/database/faceutils.h
M  +44   -20   core/utilities/facemanagement/pipelines/detectrecognize/facepipelinedetectrecognize.cpp
M  +73   -39   core/utilities/facemanagement/pipelines/edit/facepipelineedit.cpp
M  +7    -0    core/utilities/facemanagement/pipelines/edit/facepipelineedit.h
M  +15   -0    core/utilities/facemanagement/pipelines/facepipelinebase.cpp
M  +1    -0    core/utilities/facemanagement/pipelines/facepipelinepackagebase.h
M  +27   -29   core/utilities/facemanagement/pipelines/recognize/facepipelinerecognize.cpp
M  +1    -0    project/bundles/homebrew/02-build-extralibs.sh
M  +2    -0    project/bundles/homebrew/03-build-digikam.sh
M  +11   -8    project/bundles/homebrew/config.sh

https://invent.kde.org/graphics/digikam/-/commit/499d41cee5f7422e9951ed9c097d898568f7046d