Passed
Push — self-contained-model ( 6fc33a...d2c701 )
by Matias
04:01
created

DlibCnnModel::meetDependencies()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 4
ccs 0
cts 4
cp 0
crap 6
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2020, 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 OCP\IDBConnection;
28
29
use OCA\FaceRecognition\Helper\Requirements;
30
31
use OCA\FaceRecognition\Service\FileService;
32
use OCA\FaceRecognition\Service\ModelService;
33
use OCA\FaceRecognition\Service\SettingsService;
34
35
use OCA\FaceRecognition\Model\IModel;
36
37
class DlibCnnModel implements IModel {
38
39
	/*
40
	 * Model files.
41
	 */
42
	const FACE_MODEL_ID = -1;
43
	const FACE_MODEL_NAME = "";
44
	const FACE_MODEL_DESC = "";
45
46
	const FACE_MODEL_BZ2_URLS = array();
47
	const FACE_MODEL_FILES = array();
48
49
	const I_MODEL_DETECTOR = 0;
50
	const I_MODEL_PREDICTOR = 1;
51
	const I_MODEL_RESNET = 2;
52
53
	/** @var \CnnFaceDetection */
0 ignored issues
show
Bug introduced by
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...
54
	private $cfd;
55
56
	/** @var \FaceLandmarkDetection */
0 ignored issues
show
Bug introduced by
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...
57
	private $fld;
58
59
	/** @var \FaceRecognition */
0 ignored issues
show
Bug introduced by
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...
60
	private $fr;
61
62
	/** @var IDBConnection */
63
	private $connection;
64
65
	/** @var FileService */
66
	private $fileService;
67
68
	/** @var ModelService */
69
	private $modelService;
70
71
	/** @var SettingsService */
72
	private $settingsService;
73
74
75
	/**
76
	 * DlibCnnModel __construct.
77
	 *
78
	 * @param IDBConnection $connection
79
	 * @param FileService $fileService
80
	 * @param ModelService $modelService
81
	 * @param SettingsService $settingsService
82
	 */
83
	public function __construct(IDBConnection   $connection,
84
	                            FileService     $fileService,
85
	                            ModelService    $modelService,
86
	                            SettingsService $settingsService)
87
	{
88
		$this->connection       = $connection;
89
		$this->fileService      = $fileService;
90
		$this->modelService     = $modelService;
91
		$this->settingsService  = $settingsService;
92
	}
93
94
	public function getId(): int {
95
		return static::FACE_MODEL_ID;
96
	}
97
98
	public function getName(): string {
99
		return static::FACE_MODEL_NAME;
100
	}
101
102
	public function getDescription(): string {
103
		return static::FACE_MODEL_DESC;
104
	}
105
106
	public function isInstalled(): bool {
107
		$requirements = new Requirements($this->modelService, $this->getId());
108
		return $requirements->modelFilesPresent();
109
	}
110
111
	public function meetDependencies(): bool {
112
		$model = $this->settingsService->getCurrentFaceModel();
113
		$requirements = new Requirements($this->modelService, $model);
114
		return extension_loaded('pdlib') && $requirements->modelFilesPresent();
115
	}
116
117
	public function install() {
118
		if ($this->isInstalled()) {
119
			return;
120
		}
121
122
		/* Still not installed but it is necessary to get the model folders */
123
		$this->modelService->useModelVersion($this->getId());
124
125
		/* Download and install models */
126
		$detectorModelBz2 = $this->fileService->downloaldFile(static::FACE_MODEL_BZ2_URLS[self::I_MODEL_DETECTOR]);
127
		$this->fileService->bunzip2($detectorModelBz2, $this->modelService->getModelPath(static::FACE_MODEL_FILES[self::I_MODEL_DETECTOR]));
128
129
		$predictorModelBz2 = $this->fileService->downloaldFile(static::FACE_MODEL_BZ2_URLS[self::I_MODEL_PREDICTOR]);
130
		$this->fileService->bunzip2($predictorModelBz2, $this->modelService->getModelPath(static::FACE_MODEL_FILES[self::I_MODEL_PREDICTOR]));
131
132
		$resnetModelBz2 = $this->fileService->downloaldFile(static::FACE_MODEL_BZ2_URLS[self::I_MODEL_RESNET]);
133
		$this->fileService->bunzip2($resnetModelBz2, $this->modelService->getModelPath(static::FACE_MODEL_FILES[self::I_MODEL_RESNET]));
134
135
		/* Clean temporary files */
136
		$this->fileService->clean();
137
138
		// Insert on database and enable it
139
		$qb = $this->connection->getQueryBuilder();
140
		$query = $qb->select($qb->createFunction('COUNT(' . $qb->getColumnName('id') . ')'))
141
			->from('facerecog_models')
142
			->where($qb->expr()->eq('id', $qb->createParameter('id')))
143
			->setParameter('id', $this->getId());
144
		$resultStatement = $query->execute();
145
		$data = $resultStatement->fetch(\PDO::FETCH_NUM);
146
		$resultStatement->closeCursor();
147
148
		if ((int)$data[0] <= 0) {
149
			$query = $this->connection->getQueryBuilder();
150
			$query->insert('facerecog_models')
151
			->values([
152
				'id' => $query->createNamedParameter($this->getId()),
153
				'name' => $query->createNamedParameter($this->getName()),
154
				'description' => $query->createNamedParameter($this->getDescription())
155
			])
156
			->execute();
157
		}
158
	}
159
160
	public function setDefault() {
161
		// Use default model, if it is not set already.
162
		if ($this->settingsService->getCurrentFaceModel() !== $this->getId()) {
163
			$this->settingsService->setCurrentFaceModel($this->getId());
164
		}
165
	}
166
167
	public function open() {
168
		$this->modelService->useModelVersion($this->getId());
169
170
		$this->cfd = new \CnnFaceDetection($this->modelService->getModelPath(static::FACE_MODEL_FILES[self::I_MODEL_DETECTOR]));
171
		$this->fld = new \FaceLandmarkDetection($this->modelService->getModelPath(static::FACE_MODEL_FILES[self::I_MODEL_PREDICTOR]));
172
		$this->fr = new \FaceRecognition($this->modelService->getModelPath(static::FACE_MODEL_FILES[self::I_MODEL_RESNET]));
173
	}
174
175
	public function detectFaces(string $imagePath): array {
176
		return $this->cfd->detect($imagePath);
177
	}
178
179
	public function detectLandmarks(string $imagePath, array $rect): array {
180
		return $this->fld->detect($imagePath, $rect);
181
	}
182
183
	public function computeDescriptor(string $imagePath, array $landmarks): array {
184
		return $this->fr->computeDescriptor($imagePath, $landmarks);
185
	}
186
187
}
188