matiasdelellis / facerecognition

Nextcloud app that implement a basic facial recognition system.
GNU Affero General Public License v3.0
515 stars 46 forks source link

Crashes with TypeError: OCA\FaceRecognition\Helper\Euclidean::distance(): Argument #1 ($vector1) must be of type array, string given, called in #780

Open wojciechczyz opened 1 week ago

wojciechczyz commented 1 week ago

Hey, Thanks for reporting issues back to Nextcloud Face Recognition. Please, try to complete this report in detail so we can help you easier. :smile:

Make sure you read all the documentation, and the FAQ, and that the issue has not been reported before. :wink:

Expected behaviour

when running:

php occ face:background_job --cluster-mode

It starts clustering and then crashes: 1/3 - Executing task CheckRequirementsTask (Check all requirements) 2/3 - Executing task CheckCronTask (Check that service is started from either cron or from command) 3/3 - Executing task CreateClustersTask (Create new persons or update existing persons) Face clustering will be created for the first time. There are 47 faces for clustering An unhandled exception has been thrown:

Actual behaviour

Crashes with error: 42b5095134e3:/var/www/html$ php occ face:background_job --cluster-mode 1/3 - Executing task CheckRequirementsTask (Check all requirements) 2/3 - Executing task CheckCronTask (Check that service is started from either cron or from command) 3/3 - Executing task CreateClustersTask (Create new persons or update existing persons) Face clustering will be created for the first time. There are 47 faces for clustering An unhandled exception has been thrown: TypeError: OCA\FaceRecognition\Helper\Euclidean::distance(): Argument #1 ($vector1) must be of type array, string given, called in /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php on line 336 and defined in /var/www/html/custom_apps/facerecognition/lib/Helper/Euclidean.php:24 Stack trace:

0 /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php(336): OCA\FaceRecognition\Helper\Euclidean::distance('[-0.08935702592...', '[-0.08935702592...')

1 /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php(177): OCA\FaceRecognition\BackgroundJob\Tasks\CreateClustersTask->getNewClusters(Array)

2 /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php(90): OCA\FaceRecognition\BackgroundJob\Tasks\CreateClustersTask->createClusterIfNeeded('admin')

3 /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/BackgroundService.php(150): OCA\FaceRecognition\BackgroundJob\Tasks\CreateClustersTask->execute(Object(OCA\FaceRecognition\BackgroundJob\FaceRecognitionContext))

4 /var/www/html/custom_apps/facerecognition/lib/Command/BackgroundCommand.php(192): OCA\FaceRecognition\BackgroundJob\BackgroundService->execute(0, false, NULL, NULL, 'cluster-mode')

5 /var/www/html/3rdparty/symfony/console/Command/Command.php(298): OCA\FaceRecognition\Command\BackgroundCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

6 /var/www/html/3rdparty/symfony/console/Application.php(1040): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

7 /var/www/html/3rdparty/symfony/console/Application.php(301): Symfony\Component\Console\Application->doRunCommand(Object(OCA\FaceRecognition\Command\BackgroundCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

8 /var/www/html/3rdparty/symfony/console/Application.php(171): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

9 /var/www/html/lib/private/Console/Application.php(213): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

10 /var/www/html/console.php(102): OC\Console\Application->run()

11 /var/www/html/occ(11): require_once('/var/www/html/c...')

12 {main}42b5095134e3:/var/www/html$

Server configuration

docker setup with external container

docker setup with external container

29.0.8

Client configuration

Chrome

Docker under Proxmox

Logs

Background task log with debug.

sudo -u apache php occ -vvv face:background_job ``` 1/8 - Executing task CheckRequirementsTask (Check all requirements) System: Linux System memory: 33227206656 PHP Memory Limit: 2147483648 Clustering backend: PHP (Not recommended.) Image Backend: Imaginary Imaginary version: dev 2/8 - Executing task CheckCronTask (Check that service is started from either cron or from command) 3/8 - Executing task DisabledUserRemovalTask (Purge all the information of a user when disable the analysis.) yielding yielding 4/8 - Executing task StaleImagesRemovalTask (Crawl for stale images (either missing in filesystem or under .nomedia) and remove them from DB) Skipping stale images removal for user admin as there is no need for it Skipping stale images removal for user wojtek as there is no need for it 5/8 - Executing task CreateClustersTask (Create new persons or update existing persons) Face clustering will be created for the first time. There are 47 faces for clustering We will cluster with 1 batch(es) of 47 faces An unhandled exception has been thrown: TypeError: OCA\FaceRecognition\Helper\Euclidean::distance(): Argument #1 ($vector1) must be of type array, string given, called in /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php on line 336 and defined in /var/www/html/custom_apps/facerecognition/lib/Helper/Euclidean.php:24 Stack trace: #0 /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php(336): OCA\FaceRecognition\Helper\Euclidean::distance('[-0.08935702592...', '[-0.08935702592...') #1 /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php(177): OCA\FaceRecognition\BackgroundJob\Tasks\CreateClustersTask->getNewClusters(Array) #2 /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php(90): OCA\FaceRecognition\BackgroundJob\Tasks\CreateClustersTask->createClusterIfNeeded('admin') #3 /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/BackgroundService.php(150): OCA\FaceRecognition\BackgroundJob\Tasks\CreateClustersTask->execute(Object(OCA\FaceRecognition\BackgroundJob\FaceRecognitionContext)) #4 /var/www/html/custom_apps/facerecognition/lib/Command/BackgroundCommand.php(192): OCA\FaceRecognition\BackgroundJob\BackgroundService->execute(0, true, NULL, NULL, 'default-mode') #5 /var/www/html/3rdparty/symfony/console/Command/Command.php(298): OCA\FaceRecognition\Command\BackgroundCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #6 /var/www/html/3rdparty/symfony/console/Application.php(1040): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #7 /var/www/html/3rdparty/symfony/console/Application.php(301): Symfony\Component\Console\Application->doRunCommand(Object(OCA\FaceRecognition\Command\BackgroundCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #8 /var/www/html/3rdparty/symfony/console/Application.php(171): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #9 /var/www/html/lib/private/Console/Application.php(213): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #10 /var/www/html/console.php(102): OC\Console\Application->run() #11 /var/www/html/occ(11): require_once('/var/www/html/c...') 42b ```

Web server error log

Web server error log ``` Insert your webserver log here ```

Nextcloud log (data/nextcloud.log)

Nextcloud log ``` Insert your Nextcloud log here ```

Browser log

Browser log ``` Insert your browser log here, this could for example include: a) The javascript console log b) The network log c) ... ```
ewok2 commented 1 week ago

Hello, I get the same behaviour Face recognation 0.9.51 NC 29.0.8 Pdlib tested Ok

When launching : sudo -u www-data php /var/www/nextcloud/occ face:background_job after a sudo -u www-data php /var/www/nextcloud/occ face:reset --all it start analyse the picture and stop after all picture has been analysed With the stat command :

sudo -u www-data php /var/www/nextcloud/occ face:stats
+----------------+--------+-----------+-------+----------+---------+
| User           | Images | Processed | Faces | Clusters | Persons |
+----------------+--------+-----------+-------+----------+---------+
| user1           | 224    | 224       | 263   | 0        | 0       |
+----------------+--------+-----------+-------+----------+---------+

but when launching again sudo -u www-data php /var/www/nextcloud/occ face:background_job I get

1/8 - Executing task CheckRequirementsTask (Check all requirements)
2/8 - Executing task CheckCronTask (Check that service is started from either cron or from command)
3/8 - Executing task DisabledUserRemovalTask (Purge all the information of a user when disable the analysis.)
4/8 - Executing task StaleImagesRemovalTask (Crawl for stale images (either missing in filesystem or under .nomedia) and remove them from DB)
5/8 - Executing task CreateClustersTask (Create new persons or update existing persons)
    Skipping cluster creation, not enough data (yet) collected. For cluster creation, you need either one of the following:
    * have 1000 faces already processed
    * or you need to have 95% of you images processed
    Use stats command to track progress
    Skipping cluster creation, not enough data (yet) collected. For cluster creation, you need either one of the following:
    * have 1000 faces already processed
    * or you need to have 95% of you images processed
    Use stats command to track progress
    Skipping cluster creation, not enough data (yet) collected. For cluster creation, you need either one of the following:
    * have 1000 faces already processed
    * or you need to have 95% of you images processed
    Use stats command to track progress
    Skipping cluster creation, not enough data (yet) collected. For cluster creation, you need either one of the following:
    * have 1000 faces already processed
    * or you need to have 95% of you images processed
    Use stats command to track progress
    Face clustering will be created for the first time.
    There are 263 faces for clustering
An unhandled exception has been thrown:
TypeError: dlib_vector_length(): Argument #1 ($x_arg) must be of type array, string given in /var/www/nextcloud/apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php:311
Stack trace:
#0 /var/www/nextcloud/apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php(311): dlib_vector_length()
#1 /var/www/nextcloud/apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php(177): OCA\FaceRecognition\BackgroundJob\Tasks\CreateClustersTask->getNewClusters()
#2 /var/www/nextcloud/apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php(90): OCA\FaceRecognition\BackgroundJob\Tasks\CreateClustersTask->createClusterIfNeeded()
#3 /var/www/nextcloud/apps/facerecognition/lib/BackgroundJob/BackgroundService.php(150): OCA\FaceRecognition\BackgroundJob\Tasks\CreateClustersTask->execute()
#4 /var/www/nextcloud/apps/facerecognition/lib/Command/BackgroundCommand.php(192): OCA\FaceRecognition\BackgroundJob\BackgroundService->execute()
#5 /var/www/nextcloud/3rdparty/symfony/console/Command/Command.php(298): OCA\FaceRecognition\Command\BackgroundCommand->execute()
#6 /var/www/nextcloud/3rdparty/symfony/console/Application.php(1040): Symfony\Component\Console\Command\Command->run()
#7 /var/www/nextcloud/3rdparty/symfony/console/Application.php(301): Symfony\Component\Console\Application->doRunCommand()
#8 /var/www/nextcloud/3rdparty/symfony/console/Application.php(171): Symfony\Component\Console\Application->doRun()
#9 /var/www/nextcloud/lib/private/Console/Application.php(213): Symfony\Component\Console\Application->run()
#10 /var/www/nextcloud/console.php(102): OC\Console\Application->run()
#11 /var/www/nextcloud/occ(11): require_once('...')

The first time I had installed Face recognation it has worked, but after changing the setting on the face detection in NC interface and perform a reset it does not works anymore?

Any idea why?

ewok2 commented 1 week ago

PS : I initialy test it with a higher number of picture (more than 20 000 picture) but for the last test I perform it on a small number :-)

nordscan commented 6 days ago

hi, the same (i tried it maybe a year ago and it was working)

tried external model installed on wsl2 and through Nextcloud AIO (Computing container for facerecognition container) too.

Nextcloud AIO v9.7.0 Nextcloud Hub 8 (29.0.8) Face recognation 0.9.51

1/8 - Executing task CheckRequirementsTask (Check all requirements)
2/8 - Executing task CheckCronTask (Check that service is started from either cron or from command)
3/8 - Executing task DisabledUserRemovalTask (Purge all the information of a user when disable the analysis.)
4/8 - Executing task StaleImagesRemovalTask (Crawl for stale images (either missing in filesystem or under .nomedia) and remove them from DB)
5/8 - Executing task CreateClustersTask (Create new persons or update existing persons)
        Face clustering will be recreated with new information or changes
        There are 7635 faces for clustering
An unhandled exception has been thrown:
TypeError: OCA\FaceRecognition\Helper\Euclidean::distance(): Argument #1 ($vector1) must be of type array, string given, called in /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php on line 336 and defined in /var/www/html/custom_apps/facerecognition/lib/Helper/Euclidean.php:24
Stack trace:
#0 /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php(336): OCA\FaceRecognition\Helper\Euclidean::distance('[-0.10269370675...', '[-0.10269370675...')
#1 /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php(177): OCA\FaceRecognition\BackgroundJob\Tasks\CreateClustersTask->getNewClusters(Array)
#2 /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php(90): OCA\FaceRecognition\BackgroundJob\Tasks\CreateClustersTask->createClusterIfNeeded('nordscan')
#3 /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/BackgroundService.php(150): OCA\FaceRecognition\BackgroundJob\Tasks\CreateClustersTask->execute(Object(OCA\FaceRecognition\BackgroundJob\FaceRecognitionContext))
#4 /var/www/html/custom_apps/facerecognition/lib/Command/BackgroundCommand.php(192): OCA\FaceRecognition\BackgroundJob\BackgroundService->execute(0, false, Object(OC\User\User), NULL, 'default-mode')
#5 /var/www/html/3rdparty/symfony/console/Command/Command.php(298): OCA\FaceRecognition\Command\BackgroundCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#6 /var/www/html/3rdparty/symfony/console/Application.php(1040): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#7 /var/www/html/3rdparty/symfony/console/Application.php(301): Symfony\Component\Console\Application->doRunCommand(Object(OCA\FaceRecognition\Command\BackgroundCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#8 /var/www/html/3rdparty/symfony/console/Application.php(171): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#9 /var/www/html/lib/private/Console/Application.php(213): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#10 /var/www/html/console.php(102): OC\Console\Application->run()
#11 /var/www/html/occ(11): require_once('/var/www/html/c...')
Oski19831 commented 5 days ago

I can confirm this Bug also. It is a WorkArround to manuel convert the json_string to an array.

I don´t know if this is a Problem with PHP. I use PHP8.2 and run it on a RPI4 with ARM64-CPU.

for me it work to edit the CreateClusterTaks.php on Line 311

$distance = dlib_vector_length($face1->descriptor, $face2->descriptor); to

if(!is_array($face1->descriptor)) { $face1->descriptor = json_decode($face1->descriptor, true); } if(!is_array($face2->descriptor)) { $face2->descriptor = json_decode($face2->descriptor, true); } $distance = dlib_vector_length($face1->descriptor, $face2->descriptor);

I hope this help temporaly...

ewok2 commented 5 days ago

If related to php I am using php8.3

ewok2 commented 5 days ago

@Oski19831 thanks your workaroud seem's to works for me !

vwbusguy commented 5 days ago

I can confirm this Bug also. It is a WorkArround to manuel convert the json_string to an array.

I don´t know if this is a Problem with PHP. I use PHP8.2 and run it on a RPI4 with ARM64-CPU.

for me it work to edit the CreateClusterTaks.php on Line 311

$distance = dlib_vector_length($face1->descriptor, $face2->descriptor); to

if(!is_array($face1->descriptor)) { $face1->descriptor = json_decode($face1->descriptor, true); } if(!is_array($face2->descriptor)) { $face2->descriptor = json_decode($face2->descriptor, true); } $distance = dlib_vector_length($face1->descriptor, $face2->descriptor);

I hope this help temporaly...

Heck yes! Maybe submit a Pull Request for this?

Oski19831 commented 5 days ago

I never wrote Code for NC. So i think it is better Solution to change Code in DB-Object. But i don´t know the relation between NC and Entity - Class in NC. I think this Code is better in /lib/Db/Face.php. Or a function there... and call the function in CreateClusterTask.php ... But if it is helfull for you i will change the code...

warriorcookie commented 5 days ago

Same issue here.

Noticed Face Recognition was hung at Analyzing images - 31779 images detected - 339 images in queue - Ends approximately in 26 minutes.

went to CLI and executed the following:

:~$ sudo docker exec --user www-data -it nextcloud-aio-nextcloud php occ face:background_job
1/8 - Executing task CheckRequirementsTask (Check all requirements)
2/8 - Executing task CheckCronTask (Check that service is started from either cron or from command)
3/8 - Executing task DisabledUserRemovalTask (Purge all the information of a user when disable the analysis.)
4/8 - Executing task StaleImagesRemovalTask (Crawl for stale images (either missing in filesystem or under .nomedia) and remove them from DB)
5/8 - Executing task CreateClustersTask (Create new persons or update existing persons)
    Face clustering will be created for the first time.
    There are 2 faces for clustering
An unhandled exception has been thrown:
TypeError: OCA\FaceRecognition\Helper\Euclidean::distance(): Argument #1 ($vector1) must be of type array, string given, called in /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php on line 336 and defined in /var/www/html/custom_apps/facerecognition/lib/Helper/Euclidean.php:24
Stack trace:
#0 /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php(336): OCA\FaceRecognition\Helper\Euclidean::distance('[-0.04276097938...', '[-0.04276097938...')
#1 /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php(177): OCA\FaceRecognition\BackgroundJob\Tasks\CreateClustersTask->getNewClusters(Array)
#2 /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php(90): OCA\FaceRecognition\BackgroundJob\Tasks\CreateClustersTask->createClusterIfNeeded('admin')
#3 /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/BackgroundService.php(150): OCA\FaceRecognition\BackgroundJob\Tasks\CreateClustersTask->execute(Object(OCA\FaceRecognition\BackgroundJob\FaceRecognitionContext))
#4 /var/www/html/custom_apps/facerecognition/lib/Command/BackgroundCommand.php(192): OCA\FaceRecognition\BackgroundJob\BackgroundService->execute(0, false, NULL, NULL, 'default-mode')
#5 /var/www/html/3rdparty/symfony/console/Command/Command.php(298): OCA\FaceRecognition\Command\BackgroundCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#6 /var/www/html/3rdparty/symfony/console/Application.php(1040): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#7 /var/www/html/3rdparty/symfony/console/Application.php(301): Symfony\Component\Console\Application->doRunCommand(Object(OCA\FaceRecognition\Command\BackgroundCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#8 /var/www/html/3rdparty/symfony/console/Application.php(171): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#9 /var/www/html/lib/private/Console/Application.php(183): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#10 /var/www/html/console.php(87): OC\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput))
#11 /var/www/html/occ(11): require_once('/var/www/html/c...')
#12 {main}
Oski19831 commented 5 days ago

Same here. $faces returns a String instead of an array.

So for WorkArround add a function in /lib/Db/Face.php function getDescriptorArray(): array { if(is_array($this->descriptor)) { return $this->descriptor; } else { return jsond_decode($this->descriptor, true); } }

and change each $face1['descriptor'] and $face2['descriptor'] to $face1->getDescriptorArray() and $face2->getDescriptorArray() in /lib/BackgroundJob/Tasks/CreateClusterTask.php

Or change my Solution above to your Code in CreateClusterTask.php

This is my Solutiion for this Issue.

This schould work as WorkArround or Wait until the Issue is fixed... I hope i could help you.

tuxArg commented 4 days ago

Probably related I've got this error:

An unhandled exception has been thrown:
Error: Call to a member function getTimestamp() on string in /var/www/nextcloud/apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php:232
nordscan commented 4 days ago

781

mrmipo commented 3 days ago

Same here. $faces returns a String instead of an array.

So for WorkArround add a function in /lib/Db/Face.php function getDescriptorArray(): array { if(is_array($this->descriptor)) { return $this->descriptor; } else { return jsond_decode($this->descriptor, true); } }

and change each $face1['descriptor'] and $face2['descriptor'] to $face1->getDescriptorArray() and $face2->getDescriptorArray() in /lib/BackgroundJob/Tasks/CreateClusterTask.php

Or change my Solution above to your Code in CreateClusterTask.php

This is my Solutiion for this Issue.

This schould work as WorkArround or Wait until the Issue is fixed... I hope i could help you.

Hi

sorry but I not know what to do ...

I add function to lib/Db/Face.php

        public function setCreationTime($creationTime): void {
                if (is_a($creationTime, 'DateTime')) {
                        $this->creationTime = $creationTime;
                } else {
                        $this->creationTime = new \DateTime($creationTime);
                }
                $this->markFieldUpdated('creationTime');
        }
        public function getDescriptorArray(): array {
                if (is_array($this->descriptor)) {
                        return $this->descriptor;
                } else {
                        return jsond_decode($this->descriptor, true);
                }
        }

But not know what do you mean change each $face1['descriptor'] and $face2['descriptor'] to $face1->getDescriptorArray() as I don't see $face1['descriptor'] in file:

$grep "face1" /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/Tasks/CreateClustersTask.php
                                $face1 = $faces[$i];
                                if (!isset($face1->descriptor)) {
                                        if (!is_array($face1->descriptor)) {
                                                $face1->descriptor = json_decode($face1->descriptor, true);
                                        $distance = dlib_vector_length($face1->descriptor, $face2->descriptor);
                                $face1 = $faces[$i];
                                if (!isset($face1->descriptor)) {
                                        $distance = Euclidean::distance($face1->descriptor, $face2->descriptor);

Can you attach corrected files ?

Oski19831 commented 3 days ago

hello @mrmipo .

change $face1->descriptor to $face1->getDescriptorArray(). that should call the function in Class Face.php and returned an array and not the String from the DB. Try it.

EDIT:

And you don´t proof again in CreateTaskCluster.php if $facex->descriptor is an array. you proof it also in the function getDescriptorArray() in Face.php.

@tuxArg

For you the WorkArround ist like the Same. You get the TimeString instead a DateTime-Object. So it must be converted before call getTimestamp().

tuxArg commented 3 days ago

For you the WorkArround ist like the Same. You get the TimeString instead a DateTime-Object. So it must be converted before call getTimestamp().

I did it this way: https://github.com/matiasdelellis/facerecognition/issues/781#issuecomment-2429163804

mrmipo commented 3 days ago

hello @mrmipo .

change $face1->descriptor to $face1->getDescriptorArray(). that should call the function in Class Face.php and returned an array and not the String from the DB. Try it.

EDIT:

And you don´t proof again in CreateTaskCluster.php if $facex->descriptor is an array. you proof it also in the function getDescriptorArray() in Face.php.

@tuxArg

For you the WorkArround ist like the Same. You get the TimeString instead a DateTime-Object. So it must be converted before call getTimestamp().

Hi Oski19831

Ok I finally fix this issue and it's look like no it's working fine (manage new image/face and creating clustering) but without getDescriptorArray() as I was not able to understand how it's should be done. But I use your solution from beginning and from issue that I create. So I only modify one file CreateClustersTask.php . Output from diff:

$ diff CreateClustersTask.php_org CreateClustersTask.php
--- CreateClustersTask.php_org
+++ CreateClustersTask.php
@@ -229,10 +229,16 @@

                // We have some faces, but not that many, let's see when oldest one is generated.
                $oldestFace = $this->faceMapper->getOldestCreatedFaceWithoutPerson($userId, $modelId);
-               $oldestFaceTimestamp = $oldestFace->creationTime->getTimestamp();
+               if (is_string($oldestFace->creationTime)) {
+                       $oldestFaceTimestamp = strtotime($oldestFace->creationTime);
+                       $oldestFaceFormat=$oldestFace->creationTime;
+               } else {
+                       $oldestFaceTimestamp = $oldestFace->creationTime->getTimestamp();
+                       $oldestFaceFormat=$oldestFace->creationTime->format('Y-m-d H:i:s');
+               }
                $currentTimestamp = (new \DateTime())->getTimestamp();
                $this->logDebug(sprintf('Oldest face without persons for user %s and model %d is from %s',
-                               $userId, $modelId, $oldestFace->creationTime->format('Y-m-d H:i:s')));
+                               $userId, $modelId, $oldestFaceFormat));

                // todo: get rid of magic numbers (move to config)
                if ($currentTimestamp - $oldestFaceTimestamp > 2 * 60 * 60)
@@ -308,6 +314,12 @@
                                        if (!isset($face2->descriptor)) {
                                                continue;
                                        }
+                                       if (!is_array($face1->descriptor)) {
+                                               $face1->descriptor = json_decode($face1->descriptor, true);
+                                       }
+                                       if (!is_array($face2->descriptor)) {
+                                               $face2->descriptor = json_decode($face2->descriptor, true);
+                                       }
                                        $distance = dlib_vector_length($face1->descriptor, $face2->descriptor);
                                        if ($distance < $sensitivity) {
                                                $edges[] = array($i, $j);
@@ -333,6 +345,12 @@
                                        if (!isset($face2->descriptor)) {
                                                continue;
                                        }
+                                       if (!is_array($face1->descriptor)) {
+                                                $face1->descriptor = json_decode($face1->descriptor, true);
+                                        }
+                                        if (!is_array($face2->descriptor)) {
+                                                $face2->descriptor = json_decode($face2->descriptor, true);
+                                        }
                                        $distance = Euclidean::distance($face1->descriptor, $face2->descriptor);
                                        if ($distance < $sensitivity) {
                                                $edges[] = array($i, $j);

Really thanks for your help

Oski19831 commented 3 days ago

Top no thanks. I test a modification which is easyer... i post an update if it pass the test....

Oski19831 commented 3 days ago

it is also enough to change /lib/Db/face.php and add two Lines in function __construct()


public function __construct() {
          $this->addType('id', 'integer');
          $this->addType('image', 'integer');
          $this->addType('person', 'integer');
          $this->addType('isGroupable', 'bool');

          //This Lines fix the Isue
          $this->addType('descriptor', 'json');
          $this->addType('creationTime', 'datetime');
}

Then nothing else is to do.

Testet on NC HUB 8 (29.0.8)