Issues (125)

lib/Model/DlibCnnModel/DlibCnnModel.php (3 issues)

Labels
Severity
1
<?php
2
/**
3
 * @copyright Copyright (c) 2021-2023, Matias De lellis <[email protected]>
4
 * @copyright Copyright (c) 2018, Branko Kokanovic <[email protected]>
5
 *
6
 * @author Branko Kokanovic <[email protected]>
7
 *
8
 * @license GNU AGPL version 3 or any later version
9
 *
10
 * This program is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU Affero General Public License as
12
 * published by the Free Software Foundation, either version 3 of the
13
 * License, or (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU Affero General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Affero General Public License
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
 *
23
 */
24
25
namespace OCA\FaceRecognition\Model\DlibCnnModel;
26
27
use OCA\FaceRecognition\Service\CompressionService;
28
use OCA\FaceRecognition\Service\DownloadService;
29
use OCA\FaceRecognition\Service\ModelService;
30
use OCA\FaceRecognition\Service\SettingsService;
31
32
use OCA\FaceRecognition\Model\IModel;
33
34
class DlibCnnModel implements IModel {
35
36
	/*
37
	 * Model files.
38
	 */
39
	const FACE_MODEL_ID = -1;
40
	const FACE_MODEL_NAME = "";
41
	const FACE_MODEL_DESC = "";
42
	const FACE_MODEL_DOC = "";
43
44
	/** Relationship between image size and memory consumed */
45
	const MEMORY_AREA_RELATIONSHIP = -1;
46
	const MINIMUM_MEMORY_REQUIREMENTS = -1;
47
48
	const FACE_MODEL_FILES = array();
49
50
	const PREFERRED_MIMETYPE = 'image/png';
51
52
	/** @var \CnnFaceDetection */
0 ignored issues
show
The type CnnFaceDetection was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
53
	private $cfd;
54
55
	/** @var \FaceLandmarkDetection */
0 ignored issues
show
The type FaceLandmarkDetection was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
56
	private $fld;
57
58
	/** @var \FaceRecognition */
0 ignored issues
show
The type FaceRecognition was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
59
	private $fr;
60
61
	/** @var CompressionService */
62
	private $compressionService;
63
64
	/** @var DownloadService */
65
	private $downloadService;
66
67
	/** @var ModelService */
68
	private $modelService;
69
70
	/** @var SettingsService */
71
	private $settingsService;
72
73
74
	/**
75
	 * DlibCnnModel __construct.
76
	 *
77
	 * @param CompressionService $compressionService
78
	 * @param DownloadService $downloadService
79
	 * @param ModelService $modelService
80
	 * @param SettingsService $settingsService
81
	 */
82 1
	public function __construct(CompressionService $compressionService,
83
	                            DownloadService $downloadService,
84
	                            ModelService    $modelService,
85
	                            SettingsService $settingsService)
86
	{
87 1
		$this->compressionService = $compressionService;
88 1
		$this->downloadService    = $downloadService;
89 1
		$this->modelService     = $modelService;
90 1
		$this->settingsService  = $settingsService;
91
	}
92
93 4
	public function getId(): int {
94 4
		return static::FACE_MODEL_ID;
95
	}
96
97
	public function getName(): string {
98
		return static::FACE_MODEL_NAME;
99
	}
100
101
	public function getDescription(): string {
102
		return static::FACE_MODEL_DESC;
103
	}
104
105
	public function getDocumentation(): string {
106
		return static::FACE_MODEL_DOC;
107
	}
108
109 4
	public function isInstalled(): bool {
110 4
		if (!$this->modelService->modelFileExists($this->getId(), static::FACE_MODEL_FILES['detector']['filename']))
111 1
			return false;
112 3
		if (!$this->modelService->modelFileExists($this->getId(), static::FACE_MODEL_FILES['predictor']['filename']))
113
			return false;
114 3
		if (!$this->modelService->modelFileExists($this->getId(), static::FACE_MODEL_FILES['resnet']['filename']))
115
			return false;
116 3
		return true;
117
	}
118
119
	public function meetDependencies(string &$error_message): bool {
120
		if (!extension_loaded('pdlib')) {
121
			$error_message = "The PDlib PHP extension is not loaded";
122
			return false;
123
		}
124
		$availableMemory = $this->settingsService->getAssignedMemory();
125
		if ($availableMemory < 0) {
126
			$error_message = "Seems that you still have to configure the assigned memory for image processing.";
127
			return false;
128
		}
129
		if ($availableMemory < static::MINIMUM_MEMORY_REQUIREMENTS) {
130
			$error_message = "Your system does not meet the minimum memory requirements.";
131
			return false;
132
		}
133
		return true;
134
	}
135
136
	public function getMaximumArea(): int {
137
		$assignedMemory = $this->settingsService->getAssignedMemory();
138
		return intval($assignedMemory/static::MEMORY_AREA_RELATIONSHIP);
139
	}
140
141 4
	public function getPreferredMimeType(): string {
142 4
		return static::PREFERRED_MIMETYPE;
143
	}
144
145
	/**
146
	 * @return void
147
	 */
148 4
	public function install() {
149 4
		if ($this->isInstalled()) {
150 3
			return;
151
		}
152
153
		// Create main folder where install models.
154 1
		$this->modelService->prepareModelFolder($this->getId());
155
156
		/* Download and install models */
157 1
		$detectorModelBz2 = $this->downloadService->downloadFile(static::FACE_MODEL_FILES['detector']['url']);
158 1
		$this->compressionService->decompress($detectorModelBz2, $this->modelService->getFileModelPath($this->getId(), static::FACE_MODEL_FILES['detector']['filename']));
159
160 1
		$predictorModelBz2 = $this->downloadService->downloadFile(static::FACE_MODEL_FILES['predictor']['url']);
161 1
		$this->compressionService->decompress($predictorModelBz2, $this->modelService->getFileModelPath($this->getId(), static::FACE_MODEL_FILES['predictor']['filename']));
162
163 1
		$resnetModelBz2 = $this->downloadService->downloadFile(static::FACE_MODEL_FILES['resnet']['url']);
164 1
		$this->compressionService->decompress($resnetModelBz2, $this->modelService->getFileModelPath($this->getId(), static::FACE_MODEL_FILES['resnet']['filename']));
165
166
		/* Clean temporary files */
167 1
		$this->downloadService->clean();
168
	}
169
170
	/**
171
	 * @return void
172
	 */
173 4
	public function open() {
174 4
		$this->cfd = new \CnnFaceDetection($this->modelService->getFileModelPath($this->getId(), static::FACE_MODEL_FILES['detector']['filename']));
175 4
		$this->fld = new \FaceLandmarkDetection($this->modelService->getFileModelPath($this->getId(), static::FACE_MODEL_FILES['predictor']['filename']));
176 4
		$this->fr = new \FaceRecognition($this->modelService->getFileModelPath($this->getId(), static::FACE_MODEL_FILES['resnet']['filename']));
177
	}
178
179 2
	public function detectFaces(string $imagePath, bool $compute = true): array {
180 2
		$faces_detected = $this->cfd->detect($imagePath, 0);
181
182 2
		if (!$compute)
183
			return $faces_detected;
184
185 2
		foreach ($faces_detected as &$face) {
186 1
			$landmarks = $this->fld->detect($imagePath, $face);
187 1
			$descriptor = $this->fr->computeDescriptor($imagePath, $landmarks);
188
189 1
			$face['landmarks'] = $landmarks['parts'];
190 1
			$face['descriptor'] = $descriptor;
191
		}
192 2
		return $faces_detected;
193
	}
194
195
	public function compute(string $imagePath, array $face): array {
196
		$landmarks = $this->fld->detect($imagePath, $face);
197
		$descriptor = $this->fr->computeDescriptor($imagePath, $landmarks);
198
199
		$face['landmarks'] = $landmarks['parts'];
200
		$face['descriptor'] = $descriptor;
201
202
		return $face;
203
	}
204
205
}
206