Issues (12)

src/Detectors/Face.php (6 issues)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AhmadMayahi\Vision\Detectors;
6
7
use AhmadMayahi\Vision\Contracts\Detectable;
8
use AhmadMayahi\Vision\Contracts\File;
9
use AhmadMayahi\Vision\Data\Face as FaceData;
10
use AhmadMayahi\Vision\Data\Vertex as VertexData;
11
use AhmadMayahi\Vision\Detectors\Face\DrawBoxAroundFaces;
12
use AhmadMayahi\Vision\Enums\Color;
13
use AhmadMayahi\Vision\Enums\Likelihood;
14
use AhmadMayahi\Vision\Support\AbstractDetector;
15
use AhmadMayahi\Vision\Support\Image;
16
use AhmadMayahi\Vision\Traits\Arrayable;
17
use AhmadMayahi\Vision\Traits\Jsonable;
18
use Generator;
19
use Google\Cloud\Vision\V1\FaceAnnotation;
20
use Google\Cloud\Vision\V1\ImageAnnotatorClient;
21
use Google\Cloud\Vision\V1\Vertex;
22
use Google\Protobuf\Internal\RepeatedField;
23
24
/**
25
 * Face Detection detects multiple faces within an image along with the associated key facial attributes
26
 * such as emotional state or wearing headwear.
27
 *
28
 * @see https://cloud.google.com/vision/docs/detecting-faces
29
 */
30
class Face extends AbstractDetector implements Detectable
31
{
32
    use Arrayable;
33
    use Jsonable;
34
35
    public function __construct(protected ImageAnnotatorClient $imageAnnotatorClient, protected File $file, protected Image $image)
36
    {
37
    }
38
39
    public function getOriginalResponse(): RepeatedField
40
    {
41
        $response = $this
42
            ->imageAnnotatorClient
43
            ->faceDetection($this->file->toVisionFile());
44
45
        return $response->getFaceAnnotations();
46
    }
47
48
    /**
49
     * @return Generator|null
50
     */
51
    public function detect(): ?Generator
52
    {
53
        $faces = $this->getOriginalResponse();
54
55
        if (0 === $faces->count()) {
56
            return null;
57
        }
58
59
        /** @var FaceAnnotation $face */
60
        foreach ($faces as $face) {
61
            $vertices = $face->getBoundingPoly()->getVertices();
62
63
            $bounds = array_map(function (Vertex $vertex) {
64
                return new VertexData($vertex->getX(), $vertex->getY());
65
            }, iterator_to_array($vertices));
66
67
            yield new FaceData(
68
                anger: Likelihood::fromKey($face->getAngerLikelihood()),
0 ignored issues
show
It seems like AhmadMayahi\Vision\Enums...->getAngerLikelihood()) can also be of type null; however, parameter $anger of AhmadMayahi\Vision\Data\Face::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

68
                /** @scrutinizer ignore-type */ anger: Likelihood::fromKey($face->getAngerLikelihood()),
Loading history...
69
                joy: Likelihood::fromKey($face->getJoyLikelihood()),
0 ignored issues
show
It seems like AhmadMayahi\Vision\Enums...ce->getJoyLikelihood()) can also be of type null; however, parameter $joy of AhmadMayahi\Vision\Data\Face::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

69
                /** @scrutinizer ignore-type */ joy: Likelihood::fromKey($face->getJoyLikelihood()),
Loading history...
70
                surprise: Likelihood::fromKey($face->getSurpriseLikelihood()),
0 ignored issues
show
It seems like AhmadMayahi\Vision\Enums...etSurpriseLikelihood()) can also be of type null; however, parameter $surprise of AhmadMayahi\Vision\Data\Face::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

70
                /** @scrutinizer ignore-type */ surprise: Likelihood::fromKey($face->getSurpriseLikelihood()),
Loading history...
71
                blurred: Likelihood::fromKey($face->getBlurredLikelihood()),
0 ignored issues
show
It seems like AhmadMayahi\Vision\Enums...getBlurredLikelihood()) can also be of type null; however, parameter $blurred of AhmadMayahi\Vision\Data\Face::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

71
                /** @scrutinizer ignore-type */ blurred: Likelihood::fromKey($face->getBlurredLikelihood()),
Loading history...
72
                headwear: Likelihood::fromKey($face->getHeadwearLikelihood()),
0 ignored issues
show
It seems like AhmadMayahi\Vision\Enums...etHeadwearLikelihood()) can also be of type null; however, parameter $headwear of AhmadMayahi\Vision\Data\Face::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

72
                /** @scrutinizer ignore-type */ headwear: Likelihood::fromKey($face->getHeadwearLikelihood()),
Loading history...
73
                underExposed: Likelihood::fromKey($face->getUnderExposedLikelihood()),
0 ignored issues
show
It seems like AhmadMayahi\Vision\Enums...derExposedLikelihood()) can also be of type null; however, parameter $underExposed of AhmadMayahi\Vision\Data\Face::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

73
                /** @scrutinizer ignore-type */ underExposed: Likelihood::fromKey($face->getUnderExposedLikelihood()),
Loading history...
74
                bounds: $bounds,
75
                detectionConfidence: $face->getDetectionConfidence(),
76
                landmarking: $face->getLandmarkingConfidence(),
77
            );
78
        }
79
    }
80
81
    public function drawBoxAroundFaces(int $borderColor = Color::GREEN): Image
82
    {
83
        return (new DrawBoxAroundFaces($this, $this->image))
84
            ->borderColor($borderColor)
85
            ->draw();
86
    }
87
}
88