|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace darknet; |
|
4
|
|
|
|
|
5
|
|
|
use FFI; |
|
6
|
|
|
use darknet\Exception\coreException; |
|
7
|
|
|
|
|
8
|
|
|
/** |
|
9
|
|
|
* Description of core |
|
10
|
|
|
* @package php-darknet (yolo v2,v3,v4) |
|
11
|
|
|
* @author Shubham Chaudhary <[email protected]> |
|
12
|
|
|
* @copyright (c) 2019,2020, Shubham Chaudhary |
|
13
|
|
|
*/ |
|
14
|
|
|
class core { |
|
15
|
|
|
|
|
16
|
|
|
protected const LIBDIR = '/home/ghost/bin/c-lib/darknet/'; |
|
17
|
|
|
protected const CFG_FASTEST_YOLO = __DIR__.'/cfg/yolo-fastest.cfg'; |
|
18
|
|
|
protected const WEIGHT_FASTEST_YOLO = __DIR__.'/weight/yolo-fastest.weights'; |
|
19
|
|
|
protected const CFG_FASTEST_YOLO_XL = __DIR__.'/cfg/yolo-fastest-xl.cfg'; |
|
20
|
|
|
protected const WEIGHT_FASTEST_YOLO_XL = __DIR__.'/weight/yolo-fastest-xl.weights'; |
|
21
|
|
|
protected const CFG_MOBILENET_V2_LITE = self::LIBDIR.'cfg/MobileNetV2-YOLOv3-Lite-coco.cfg'; |
|
22
|
|
|
protected const WEIGHT_MOBILENET_V2_LITE = self::LIBDIR.'backup/MobileNetV2-YOLOv3-Lite-coco.weights'; |
|
23
|
|
|
protected const CFG_MOBILENET_V2_VOC = self::LIBDIR.'cfg/MobileNetV2-yolo-Fastest-voc-v2.cfg'; |
|
24
|
|
|
protected const WEIGHT_MOBILENET_V2_VOC = self::LIBDIR.'backup/MobileNetV2-YOLO-Fastest-voc-v2.weights'; |
|
25
|
|
|
protected const CFG_VOC_TINY_2 = self::LIBDIR.'cfg/yolov2-tiny-voc.cfg'; |
|
26
|
|
|
protected const WEIGHT_VOC_TINY_2 = self::LIBDIR.'backup/yolov2-tiny-voc.weights'; |
|
27
|
|
|
protected const CFG_TINY_2 = self::LIBDIR.'cfg/yolov2-tiny.cfg'; |
|
28
|
|
|
protected const WEIGHT_TINY_2 = self::LIBDIR . 'backup/yolov2-tiny.weights'; |
|
29
|
|
|
protected const CFG_TINY_3 = self::LIBDIR . 'cfg/yolov3-tiny.cfg'; |
|
30
|
|
|
protected const WEIGHT_TINY_3 = self::LIBDIR . 'backup/yolov3-tiny.weights'; |
|
31
|
|
|
protected const CFG_TINY_4 = self::LIBDIR . 'cfg/yolov4-tiny.cfg'; |
|
32
|
|
|
protected const WEIGHT_TINY_4 = self::LIBDIR . 'backup/yolov4-tiny.weights'; |
|
33
|
|
|
protected const CFG_MAIN = self::LIBDIR . 'cfg/yolov3.cfg'; |
|
34
|
|
|
protected const WEIGHT_MAIN = self::LIBDIR . 'backup/yolov3.weights'; |
|
35
|
|
|
public const DATA_COCO = self::LIBDIR . 'cfg/coco.data'; |
|
36
|
|
|
public const DATA_IMGNET1k = self::LIBDIR . 'cfg/imagenet1k.data'; |
|
37
|
|
|
public const DATA_OPNIMG = self::LIBDIR . 'cfg/openimages.data'; |
|
38
|
|
|
public const DATA_COBIN9k = self::LIBDIR . 'cfg/combine9k.data'; |
|
39
|
|
|
public const DATA_VOC = self::LIBDIR . 'cfg/voc.data'; |
|
40
|
|
|
protected const OUTFILE_DIR = __DIR__ . '/../temp/out/'; |
|
41
|
|
|
public const YOLO4TINY = 4; |
|
42
|
|
|
public const YOLO3TINY = 3; |
|
43
|
|
|
public const YOLO3MAIN = 2; |
|
44
|
|
|
public const YOLO2TINY = 1; |
|
45
|
|
|
public const YOLOFASTEST = 7; |
|
46
|
|
|
public const YOLOFASTEST_XL = 8; |
|
47
|
|
|
public const YOLO_VOC_TINY = 5; |
|
48
|
|
|
public const MOBILE_NET_V2_LITE_YOLO = 6; |
|
49
|
|
|
public const MOBILE_NET_V2_VOC = 9; |
|
50
|
|
|
|
|
51
|
|
|
protected $image, $itme, $net, $outPut, $pathInfo, $rawImage, $temp_name, $dets, $imgInfo; |
|
52
|
|
|
public $darknetFFI, $meta, $classes, $numBox; |
|
53
|
|
|
|
|
54
|
|
|
public function __construct($netType = self::YOLO4TINY, $metaData = self::DATA_COCO) { |
|
55
|
|
|
$this->numBox = FFI::new('int32_t'); |
|
56
|
|
|
$this->darknetFFI = FFI::load(__DIR__ . '/dn_api_4.h'); |
|
57
|
|
|
$this->getMeta($metaData); |
|
58
|
|
|
$this->classes(); |
|
59
|
|
|
$this->loadNetwork($netType); |
|
60
|
|
|
} |
|
61
|
|
|
|
|
62
|
|
|
public function classify($img) { |
|
63
|
|
|
$this->loadImage($img); |
|
64
|
|
|
$out = $this->predictImg(); |
|
65
|
|
|
$res = []; |
|
66
|
|
|
for ($i = 0; $i < $this->meta->classes; ++$i) { |
|
67
|
|
|
$res[$i] = (FFI::string($this->meta->names[$i], $out[$i])); |
|
68
|
|
|
} |
|
69
|
|
|
return $res; |
|
70
|
|
|
} |
|
71
|
|
|
|
|
72
|
|
|
public function detect($img, $remote = false, $thresh = .25, $hier_thresh = .5, $nms = .45) { |
|
73
|
|
|
$time = microtime(true); |
|
74
|
|
|
if ($remote) { |
|
75
|
|
|
$img = $this->img4base64($img); |
|
76
|
|
|
$this->loadImage($img); |
|
77
|
|
|
} else { |
|
78
|
|
|
$this->loadImage($img); |
|
79
|
|
|
} |
|
80
|
|
|
|
|
81
|
|
|
$this->imgInfo($img); |
|
82
|
|
|
$this->predictImg(); |
|
83
|
|
|
$this->getNetworkBoxes($this->net, $this->image->w, $this->image->h, $thresh, $hier_thresh, null, 0, $this->numBox); |
|
84
|
|
|
$this->doNmsSort($this->dets, $this->numBox, $this->meta, $nms); |
|
85
|
|
|
|
|
86
|
|
|
for ($obj = 0; $obj < $this->numBox->cdata; ++$obj) { |
|
|
|
|
|
|
87
|
|
|
foreach ($this->classes as $key => $val) { |
|
88
|
|
|
if ($this->dets[$obj]->prob[$key]) { |
|
89
|
|
|
$res[] = $this->detectObject($this->dets[$obj], $key, $val); |
|
90
|
|
|
} |
|
91
|
|
|
} |
|
92
|
|
|
} |
|
93
|
|
|
if ($remote) { |
|
94
|
|
|
$msg = $this->drawBbox($res); |
|
|
|
|
|
|
95
|
|
|
echo PHP_EOL; |
|
96
|
|
|
echo "FPS:{$this->fps($time)}".PHP_EOL; |
|
97
|
|
|
echo "Execution time:" . $this->consumedTime($time) . PHP_EOL; |
|
98
|
|
|
unlink($img); |
|
99
|
|
|
$this->freeImage($this->image); |
|
100
|
|
|
$this->freeDetections($this->dets, $this->numBox); |
|
101
|
|
|
unset($res); |
|
102
|
|
|
return $msg; |
|
103
|
|
|
} else { |
|
104
|
|
|
$this->drawBbox($res, self::OUTFILE_DIR . $this->imgInfo->name); |
|
105
|
|
|
unset($res); |
|
106
|
|
|
} |
|
107
|
|
|
echo PHP_EOL; |
|
108
|
|
|
echo "FPS:{$this->fps($time)}".PHP_EOL; |
|
109
|
|
|
echo "Execution time:" . $this->consumedTime($time) . PHP_EOL; |
|
110
|
|
|
$this->freeImage($this->image); |
|
111
|
|
|
$this->freeDetections($this->dets, $this->numBox); |
|
112
|
|
|
unset($time); |
|
113
|
|
|
} |
|
114
|
|
|
|
|
115
|
|
|
public function remotePR($client, $frame, $server = '') { |
|
116
|
|
|
if ($server !== '') { |
|
117
|
|
|
$msg = $this->detect($frame->data, true); |
|
118
|
|
|
$data = ['id' => $frame->fd, 'msg' => $msg]; |
|
119
|
|
|
$server->push($client, json_encode($data)); |
|
120
|
|
|
} else { |
|
121
|
|
|
$msg = $this->detect($frame, true); |
|
122
|
|
|
$data = ['id' => $client->resourceId, 'msg' => $msg]; |
|
123
|
|
|
$client->send(json_encode($data)); |
|
124
|
|
|
} |
|
125
|
|
|
unset($msg); |
|
126
|
|
|
unset($data); |
|
127
|
|
|
} |
|
128
|
|
|
|
|
129
|
|
|
protected function loadNetwork($yolov) { |
|
130
|
|
|
switch ($yolov) { |
|
131
|
|
|
case self::YOLO4TINY: |
|
132
|
|
|
$this->net = $this->darknetFFI->load_network(self::CFG_TINY_4, self::WEIGHT_TINY_4, 0); |
|
|
|
|
|
|
133
|
|
|
break; |
|
134
|
|
|
case self::YOLO3TINY: |
|
135
|
|
|
$this->net = $this->darknetFFI->load_network(self::CFG_TINY_3, self::WEIGHT_TINY_3, 0); |
|
136
|
|
|
break; |
|
137
|
|
|
case self::YOLO2TINY; |
|
138
|
|
|
$this->net = $this->darknetFFI->load_network(self::CFG_TINY_2, self::WEIGHT_TINY_2, 0); |
|
139
|
|
|
break; |
|
140
|
|
|
case self::YOLO_VOC_TINY; |
|
141
|
|
|
$this->net = $this->darknetFFI->load_network(self::CFG_VOC_TINY_2, self::WEIGHT_VOC_TINY_2, 0); |
|
142
|
|
|
break; |
|
143
|
|
|
case self::MOBILE_NET_V2_LITE_YOLO; |
|
144
|
|
|
$this->net = $this->darknetFFI->load_network(self::CFG_MOBILENET_V2_LITE, self::WEIGHT_MOBILENET_V2_LITE, 0); |
|
145
|
|
|
break; |
|
146
|
|
|
case self::MOBILE_NET_V2_VOC; |
|
147
|
|
|
$this->net = $this->darknetFFI->load_network(self::CFG_MOBILENET_V2_VOC, self::WEIGHT_MOBILENET_V2_VOC, 0); |
|
148
|
|
|
break; |
|
149
|
|
|
case self::YOLOFASTEST; |
|
150
|
|
|
$this->net = $this->darknetFFI->load_network(self::CFG_FASTEST_YOLO, self::WEIGHT_FASTEST_YOLO, 0); |
|
151
|
|
|
break; |
|
152
|
|
|
case self::YOLOFASTEST_XL; |
|
153
|
|
|
$this->net = $this->darknetFFI->load_network(self::CFG_FASTEST_YOLO_XL, self::WEIGHT_FASTEST_YOLO_XL, 0); |
|
154
|
|
|
break; |
|
155
|
|
|
case self::YOLO3MAIN; |
|
156
|
|
|
$this->net = $this->darknetFFI->load_network(self::CFG_MAIN, self::WEIGHT_MAIN, 0); |
|
157
|
|
|
break; |
|
158
|
|
|
default: |
|
159
|
|
|
throw new coreException("Not a valid version of yolo!\n"); |
|
160
|
|
|
break; |
|
161
|
|
|
} |
|
162
|
|
|
} |
|
163
|
|
|
|
|
164
|
|
|
protected function loadImage($imgfile) { |
|
165
|
|
|
return $this->image = $this->darknetFFI->load_image_color($imgfile, 0, 0); |
|
|
|
|
|
|
166
|
|
|
} |
|
167
|
|
|
|
|
168
|
|
|
/** |
|
169
|
|
|
* [make_image description] |
|
170
|
|
|
* @param int $w [description] |
|
171
|
|
|
* @param int $h [description] |
|
172
|
|
|
* @param int $c [description] |
|
173
|
|
|
* @return [type] [description] |
|
|
|
|
|
|
174
|
|
|
*/ |
|
175
|
|
|
public function makeImg(int $w, int $h, int $c) { |
|
176
|
|
|
return $this->darknetFFI->make_image($w, $h, $c); |
|
|
|
|
|
|
177
|
|
|
} |
|
178
|
|
|
|
|
179
|
|
|
/** |
|
180
|
|
|
* [resize_image description] |
|
181
|
|
|
* @param FFI\CData $im [image] |
|
182
|
|
|
* @return [type] [description] |
|
|
|
|
|
|
183
|
|
|
*/ |
|
184
|
|
|
public function resizeImg(FFI\CData $im) { |
|
185
|
|
|
return $this->darknetFFI->resize_image($im, $this->net->w, $this->net->h); |
|
|
|
|
|
|
186
|
|
|
} |
|
187
|
|
|
|
|
188
|
|
|
/** |
|
189
|
|
|
* [letterbox_image description] |
|
190
|
|
|
* @param FFI\CData $im [description] |
|
191
|
|
|
* @param int $w [description] |
|
192
|
|
|
* @param int $h [description] |
|
193
|
|
|
* @return [type] [description] |
|
|
|
|
|
|
194
|
|
|
*/ |
|
195
|
|
|
protected function letterBoxImg(FFI\CData $im, int $w, int $h) { |
|
196
|
|
|
return $this->darknetFFI->letterbox_image($im, $w, $h); |
|
|
|
|
|
|
197
|
|
|
} |
|
198
|
|
|
|
|
199
|
|
|
protected function predictImg() { |
|
200
|
|
|
return $this->darknetFFI->network_predict_image($this->net, $this->image); |
|
|
|
|
|
|
201
|
|
|
} |
|
202
|
|
|
|
|
203
|
|
|
protected function getMeta($data) { |
|
204
|
|
|
return $this->meta = $this->darknetFFI->get_metadata($data); |
|
|
|
|
|
|
205
|
|
|
} |
|
206
|
|
|
|
|
207
|
|
|
protected function classes() { |
|
208
|
|
|
for ($i = 0; $i < $this->meta->classes; ++$i) { |
|
209
|
|
|
$this->classes[$i] = \FFI::string($this->meta->names[$i]); |
|
210
|
|
|
} |
|
211
|
|
|
return $this->classes; |
|
212
|
|
|
} |
|
213
|
|
|
|
|
214
|
|
|
protected function getNetworkBoxes(FFI\CData $net, int $w, int $h, float $thresh, float $hier, $map, int $relative, $num) { |
|
215
|
|
|
return $this->dets = $this->darknetFFI->get_network_boxes($net, $w, $h, $thresh, $hier, $map, $relative, FFI::addr($num), 0); |
|
|
|
|
|
|
216
|
|
|
} |
|
217
|
|
|
|
|
218
|
|
|
protected function doNmsSort(FFI\CData $dects, FFI\CData $nmBox, FFI\CData $meta, float $nms) { |
|
219
|
|
|
return $this->darknetFFI->do_nms_sort($dects, $nmBox->cdata, $meta->classes, $nms); |
|
|
|
|
|
|
220
|
|
|
} |
|
221
|
|
|
|
|
222
|
|
|
protected function freeImage(FFI\CData $im) { |
|
223
|
|
|
return $this->darknetFFI->free_image($im); |
|
|
|
|
|
|
224
|
|
|
} |
|
225
|
|
|
|
|
226
|
|
|
protected function freeDetections(FFI\CData $dets, $num) { |
|
227
|
|
|
return $this->darknetFFI->free_detections($dets, $num->cdata); |
|
|
|
|
|
|
228
|
|
|
} |
|
229
|
|
|
|
|
230
|
|
|
/** |
|
231
|
|
|
* [free_network description] |
|
232
|
|
|
* @return [type] [description] |
|
|
|
|
|
|
233
|
|
|
*/ |
|
234
|
|
|
protected function freeNetwork() { |
|
235
|
|
|
return $this->darknetFFI->free_network($this->net); |
|
|
|
|
|
|
236
|
|
|
} |
|
237
|
|
|
|
|
238
|
|
|
protected function detectObject(FFI\CData $det, $key, $val) { |
|
239
|
|
|
return (object) ['label' => $val, 'confidence' => $det->prob[$key], 'box' => $this->bbox2obj($det->bbox)]; |
|
|
|
|
|
|
240
|
|
|
} |
|
241
|
|
|
|
|
242
|
|
|
protected function bbox2Obj(FFI\CData $t) { |
|
243
|
|
|
return (object) ['x' => $t->x, 'y' => $t->y, 'w' => $t->w, 'h' => $t->h]; |
|
|
|
|
|
|
244
|
|
|
} |
|
245
|
|
|
|
|
246
|
|
|
protected function gbBox(object $b) { |
|
247
|
|
|
$h = $b->h / 2; |
|
248
|
|
|
$w = $b->w / 2; |
|
249
|
|
|
$x = $b->x; |
|
250
|
|
|
$y = $b->y; |
|
251
|
|
|
return (object) ['x1' => $x - $w, 'y1' => $y - $h, 'x2' => $x + $w, 'y2' => $y + $h]; |
|
252
|
|
|
} |
|
253
|
|
|
|
|
254
|
|
|
protected function drawBbox($inp, $outFile = null) { |
|
255
|
|
|
$this->rawImage = $this->createImg(); |
|
256
|
|
|
imagesetthickness($this->rawImage, 2); |
|
257
|
|
|
if ($inp !== null) { |
|
258
|
|
|
foreach ($inp as $i) { |
|
259
|
|
|
$box = $this->gbBox($i->box); |
|
260
|
|
|
$label = $i->label . '-' . round($i->confidence, 2) . '%'; |
|
261
|
|
|
switch ($i->label) { |
|
262
|
|
|
case 'bear': |
|
263
|
|
|
case 'cat': |
|
264
|
|
|
case 'cow': |
|
265
|
|
|
case 'dog': |
|
266
|
|
|
case 'elephant': |
|
267
|
|
|
case 'giraffe': |
|
268
|
|
|
case 'horse': |
|
269
|
|
|
case 'sheep': |
|
270
|
|
|
case 'zebra': |
|
271
|
|
|
$this->truthLabel($box, $label, 'yellow', 'black'); |
|
272
|
|
|
break; |
|
273
|
|
|
|
|
274
|
|
|
case 'bird': |
|
275
|
|
|
$this->truthLabel($box, $label, 'teal', 'white'); |
|
276
|
|
|
break; |
|
277
|
|
|
|
|
278
|
|
|
case 'cake': |
|
279
|
|
|
case 'donut': |
|
280
|
|
|
case 'pizza': |
|
281
|
|
|
case 'hot dog': |
|
282
|
|
|
case 'carrot': |
|
283
|
|
|
case 'broccoli': |
|
284
|
|
|
case 'orange': |
|
285
|
|
|
case 'sandwich': |
|
286
|
|
|
case 'apple': |
|
287
|
|
|
case 'banana': |
|
288
|
|
|
$this->truthLabel($box, $label, 'magenta', 'white'); |
|
289
|
|
|
break; |
|
290
|
|
|
|
|
291
|
|
|
case 'toaster': |
|
292
|
|
|
case 'oven': |
|
293
|
|
|
case 'microwave': |
|
294
|
|
|
case 'cell phone': |
|
295
|
|
|
case 'keyboard': |
|
296
|
|
|
case 'remote': |
|
297
|
|
|
case 'mouse': |
|
298
|
|
|
case 'laptop': |
|
299
|
|
|
case 'tvmonitor': |
|
300
|
|
|
case 'refrigerator': |
|
301
|
|
|
$this->truthLabel($box, $label, 'blue', 'white'); |
|
302
|
|
|
break; |
|
303
|
|
|
|
|
304
|
|
|
case 'toothbrush': |
|
305
|
|
|
case 'hair drier': |
|
306
|
|
|
case 'vase': |
|
307
|
|
|
case 'clock': |
|
308
|
|
|
case 'bottle': |
|
309
|
|
|
case 'spoon': |
|
310
|
|
|
case 'cup': |
|
311
|
|
|
case 'suitcase': |
|
312
|
|
|
case 'tie': |
|
313
|
|
|
case 'handbag': |
|
314
|
|
|
case 'umbrella': |
|
315
|
|
|
case 'book': |
|
316
|
|
|
case 'backpack': |
|
317
|
|
|
case 'wine glass': |
|
318
|
|
|
case 'fork': |
|
319
|
|
|
case 'bowl': |
|
320
|
|
|
case 'knife': |
|
321
|
|
|
$this->truthLabel($box, $label, 'purple', 'white'); |
|
322
|
|
|
break; |
|
323
|
|
|
|
|
324
|
|
|
case 'diningtable': |
|
325
|
|
|
case 'bed': |
|
326
|
|
|
case 'bench': |
|
327
|
|
|
case 'sofa': |
|
328
|
|
|
case 'chair': |
|
329
|
|
|
case 'sink': |
|
330
|
|
|
case 'scissors': |
|
331
|
|
|
$this->truthLabel($box, $label, 'cyan', 'black'); |
|
332
|
|
|
break; |
|
333
|
|
|
|
|
334
|
|
|
case 'car': |
|
335
|
|
|
case 'bus': |
|
336
|
|
|
case 'boat': |
|
337
|
|
|
case 'truck': |
|
338
|
|
|
case 'bicycle': |
|
339
|
|
|
case 'motorbike': |
|
340
|
|
|
case 'aeroplane': |
|
341
|
|
|
$this->truthLabel($box, $label, 'red', 'white'); |
|
342
|
|
|
break; |
|
343
|
|
|
case 'person': |
|
344
|
|
|
$this->truthLabel($box, $label, 'green', 'black'); |
|
345
|
|
|
break; |
|
346
|
|
|
|
|
347
|
|
|
case 'skis': |
|
348
|
|
|
case 'snowboard': |
|
349
|
|
|
case 'sports ball': |
|
350
|
|
|
case 'kite': |
|
351
|
|
|
case 'baseball bat': |
|
352
|
|
|
case 'baseball glove': |
|
353
|
|
|
case 'skateboard': |
|
354
|
|
|
case 'surfboard': |
|
355
|
|
|
case 'tennis racket': |
|
356
|
|
|
case 'teddy bear': |
|
357
|
|
|
$this->truthLabel($box, $label, 'purple', 'white'); |
|
358
|
|
|
break; |
|
359
|
|
|
|
|
360
|
|
|
case 'traffic light': |
|
361
|
|
|
case 'fire hydrant': |
|
362
|
|
|
case 'stop sign': |
|
363
|
|
|
case 'parking meter': |
|
364
|
|
|
$this->truthLabel($box, $label, 'blueViolet', 'white'); |
|
365
|
|
|
break; |
|
366
|
|
|
|
|
367
|
|
|
default : |
|
368
|
|
|
$this->truthLabel($box, $label, 'black', 'white'); |
|
369
|
|
|
break; |
|
370
|
|
|
} |
|
371
|
|
|
} |
|
372
|
|
|
} else { |
|
373
|
|
|
imagestring($this->rawImage, 5, 0, 20, "NULL [ Accuracy:- 00.00% ]", $this->color('black')); |
|
374
|
|
|
} |
|
375
|
|
|
if (is_null($outFile)) { |
|
376
|
|
|
return $this->img64Encode(); |
|
377
|
|
|
} else { |
|
378
|
|
|
imagejpeg($this->rawImage, $outFile); |
|
379
|
|
|
} |
|
380
|
|
|
imagedestroy($this->rawImage); |
|
381
|
|
|
} |
|
382
|
|
|
|
|
383
|
|
|
/** |
|
384
|
|
|
* [color description] |
|
385
|
|
|
* @param string $Colorname [description] |
|
386
|
|
|
* @return [type] [description] |
|
|
|
|
|
|
387
|
|
|
*/ |
|
388
|
|
|
protected function color($Colorname = 'yellow') { |
|
389
|
|
|
|
|
390
|
|
|
switch ($Colorname) { |
|
391
|
|
|
case 'red': |
|
392
|
|
|
$color = imagecolorallocate($this->rawImage, 255, 0, 0); |
|
393
|
|
|
break; |
|
394
|
|
|
case 'green': |
|
395
|
|
|
$color = imagecolorallocate($this->rawImage, 0, 255, 0); |
|
396
|
|
|
break; |
|
397
|
|
|
case 'blue': |
|
398
|
|
|
$color = imagecolorallocate($this->rawImage, 0, 0, 255); |
|
399
|
|
|
break; |
|
400
|
|
|
case 'yellow': |
|
401
|
|
|
$color = imagecolorallocate($this->rawImage, 255, 255, 0); |
|
402
|
|
|
break; |
|
403
|
|
|
case 'magenta': |
|
404
|
|
|
$color = imagecolorallocate($this->rawImage, 255, 0, 255); |
|
405
|
|
|
break; |
|
406
|
|
|
case 'cyan': |
|
407
|
|
|
$color = imagecolorallocate($this->rawImage, 0, 255, 255); |
|
408
|
|
|
break; |
|
409
|
|
|
case 'purple': |
|
410
|
|
|
$color = imagecolorallocate($this->rawImage, 160, 32, 240); |
|
411
|
|
|
break; |
|
412
|
|
|
case 'teal': |
|
413
|
|
|
$color = imagecolorallocate($this->rawImage, 0, 128, 128); |
|
414
|
|
|
break; |
|
415
|
|
|
case 'blueViolet': |
|
416
|
|
|
$color = imagecolorallocate($this->rawImage, 138, 43, 226); |
|
417
|
|
|
break; |
|
418
|
|
|
case 'pink': |
|
419
|
|
|
$color = imagecolorallocate($this->rawImage, 255, 192, 203); |
|
420
|
|
|
break; |
|
421
|
|
|
case 'chocolate': |
|
422
|
|
|
$color = imagecolorallocate($this->rawImage, 210, 105, 30); |
|
423
|
|
|
break; |
|
424
|
|
|
case 'white': |
|
425
|
|
|
$color = imagecolorallocate($this->rawImage, 255, 255, 255); |
|
426
|
|
|
break; |
|
427
|
|
|
case 'aquamarine1': |
|
428
|
|
|
$color = imagecolorallocate($this->rawImage, 127, 255, 212); |
|
429
|
|
|
break; |
|
430
|
|
|
case 'azurel': |
|
431
|
|
|
$color = imagecolorallocate($this->rawImage, 240, 255, 255); |
|
432
|
|
|
break; |
|
433
|
|
|
case 'maroon': |
|
434
|
|
|
$color = imagecolorallocate($this->rawImage, 176, 48, 96); |
|
435
|
|
|
break; |
|
436
|
|
|
case 'orchid': |
|
437
|
|
|
$color = imagecolorallocate($this->rawImage, 218, 112, 214); |
|
438
|
|
|
break; |
|
439
|
|
|
case 'plum': |
|
440
|
|
|
$color = imagecolorallocate($this->rawImage, 221, 160, 221); |
|
441
|
|
|
break; |
|
442
|
|
|
case 'voilet': |
|
443
|
|
|
$color = imagecolorallocate($this->rawImage, 238, 130, 238); |
|
444
|
|
|
break; |
|
445
|
|
|
case 'salmon': |
|
446
|
|
|
$color = imagecolorallocate($this->rawImage, 250, 128, 114); |
|
447
|
|
|
break; |
|
448
|
|
|
case 'brown': |
|
449
|
|
|
$color = imagecolorallocate($this->rawImage, 165, 42, 42); |
|
450
|
|
|
break; |
|
451
|
|
|
case 'orange': |
|
452
|
|
|
$color = imagecolorallocate($this->rawImage, 255, 165, 0); |
|
453
|
|
|
break; |
|
454
|
|
|
case 'darkgreen': |
|
455
|
|
|
$color = imagecolorallocate($this->rawImage, 0, 100, 0); |
|
456
|
|
|
break; |
|
457
|
|
|
case 'navy': |
|
458
|
|
|
$color = imagecolorallocate($this->rawImage, 0, 0, 128); |
|
459
|
|
|
break; |
|
460
|
|
|
case 'slateblue': |
|
461
|
|
|
$color = imagecolorallocate($this->rawImage, 106, 90, 205); |
|
462
|
|
|
break; |
|
463
|
|
|
default : |
|
464
|
|
|
$color = imagecolorallocate($this->rawImage, 0, 0, 0); |
|
465
|
|
|
break; |
|
466
|
|
|
} |
|
467
|
|
|
return $color; |
|
468
|
|
|
} |
|
469
|
|
|
|
|
470
|
|
|
/** |
|
471
|
|
|
* [load_file description] |
|
472
|
|
|
* @param [type] $filename [description] |
|
|
|
|
|
|
473
|
|
|
* @return [type] [description] |
|
|
|
|
|
|
474
|
|
|
*/ |
|
475
|
|
|
protected function createImg() { |
|
476
|
|
|
switch ($this->imgInfo->type) { |
|
477
|
|
|
case 'png': |
|
478
|
|
|
$image = imagecreatefrompng($this->imgInfo->dir . DIRECTORY_SEPARATOR . $this->imgInfo->name); |
|
479
|
|
|
break; |
|
480
|
|
|
case 'jpg': |
|
481
|
|
|
$image = imagecreatefromjpeg($this->imgInfo->dir . DIRECTORY_SEPARATOR . $this->imgInfo->name); |
|
482
|
|
|
break; |
|
483
|
|
|
case 'bmp': |
|
484
|
|
|
$image = imagecreatefrombmp($this->imgInfo->dir . DIRECTORY_SEPARATOR . $this->imgInfo->name); |
|
485
|
|
|
break; |
|
486
|
|
|
case 'webp': |
|
487
|
|
|
$image = imagecreatefromwebp($this->imgInfo->dir . DIRECTORY_SEPARATOR . $this->imgInfo->name); |
|
488
|
|
|
break; |
|
489
|
|
|
|
|
490
|
|
|
default : |
|
491
|
|
|
throw new Exception('The image is not a resource or valid image file' . PHP_EOL); |
|
492
|
|
|
break; |
|
493
|
|
|
} |
|
494
|
|
|
return $image; |
|
495
|
|
|
} |
|
496
|
|
|
|
|
497
|
|
|
public function img4base64($url) { |
|
498
|
|
|
$url64 = $this->base64ImgDecode($url); |
|
499
|
|
|
if (!empty($url64)) { |
|
500
|
|
|
$im = imagecreatefromstring($url64); |
|
501
|
|
|
imagejpeg($im, __DIR__ . '/../temp/in/' . $this->tempImgName() . '.jpg', 100); |
|
502
|
|
|
imagedestroy($im); |
|
503
|
|
|
return __DIR__ . '/../temp/in/' . $this->temp_name . '.jpg'; |
|
504
|
|
|
} else { |
|
505
|
|
|
return false; |
|
506
|
|
|
} |
|
507
|
|
|
} |
|
508
|
|
|
|
|
509
|
|
|
public function base64ImgDecode($url) { |
|
510
|
|
|
if ($url == 'data:,') { |
|
511
|
|
|
return null; |
|
512
|
|
|
} else { |
|
513
|
|
|
$data = str_replace("data:image/webp;base64", "", $url); |
|
514
|
|
|
return base64_decode($data); |
|
515
|
|
|
} |
|
516
|
|
|
} |
|
517
|
|
|
|
|
518
|
|
|
protected function img64Encode() { |
|
519
|
|
|
ob_start(); |
|
520
|
|
|
imagewebp($this->rawImage, null, 100); |
|
521
|
|
|
$res = ob_get_contents(); |
|
522
|
|
|
imagedestroy($this->rawImage); |
|
523
|
|
|
ob_end_clean(); |
|
524
|
|
|
return "data:image/webp;base64," . base64_encode($res); |
|
525
|
|
|
} |
|
526
|
|
|
|
|
527
|
|
|
/** |
|
528
|
|
|
* [temp_imgName description] |
|
529
|
|
|
* @return [type] [description] |
|
|
|
|
|
|
530
|
|
|
*/ |
|
531
|
|
|
protected function tempImgName() { |
|
532
|
|
|
return $this->temp_name = ++$this->temp_name; |
|
533
|
|
|
} |
|
534
|
|
|
|
|
535
|
|
|
protected function consumedTime($startTime) { |
|
536
|
|
|
return microtime(true) - $startTime; |
|
537
|
|
|
} |
|
538
|
|
|
|
|
539
|
|
|
protected function fps($startTime) { |
|
540
|
|
|
return (1.0/(microtime(true) - $startTime)); |
|
541
|
|
|
} |
|
542
|
|
|
|
|
543
|
|
|
protected function imgInfo($img) { |
|
544
|
|
|
list($w, $h) = getimagesize($img); |
|
545
|
|
|
$info = pathinfo($img); |
|
546
|
|
|
return $this->imgInfo = (object) ['w' => $w, 'h' => $h, 'name' => $info['basename'], 'type' => $info['extension'], 'dir' => $info['dirname']]; |
|
547
|
|
|
} |
|
548
|
|
|
|
|
549
|
|
|
protected function imgResizeGD($img, $w = 416, $h = 416) { |
|
550
|
|
|
$ratio_orig = $this->image->w / $this->image->h; |
|
551
|
|
|
if ($w / $h > $ratio_orig) { |
|
552
|
|
|
$w = $h * $ratio_orig; |
|
553
|
|
|
} else { |
|
554
|
|
|
$h = $w / $ratio_orig; |
|
555
|
|
|
} |
|
556
|
|
|
|
|
557
|
|
|
$image_p = imagecreatetruecolor($w, $h); |
|
558
|
|
|
$image = imagecreatefromjpeg($img); |
|
559
|
|
|
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $w, $h, imagesx($img), imagesy($img)); |
|
560
|
|
|
imagejpeg($image, __DIR__ . '/../temp/in/' . $this->tempImgName() . '.jpg', 100); |
|
561
|
|
|
imagedestroy($image_p); |
|
562
|
|
|
imagedestroy($image); |
|
563
|
|
|
} |
|
564
|
|
|
|
|
565
|
|
|
protected function truthLabel($box, $label, $bbcolor, $fncolor) { |
|
566
|
|
|
$strlen = strlen($label); |
|
567
|
|
|
$fw = $strlen * imagefontwidth(4); |
|
568
|
|
|
$fh = imagefontheight(4); |
|
569
|
|
|
imagefilledrectangle($this->rawImage, $box->x1 - 1, $box->y1 - $fh, $box->x1 + $fw, $box->y1, $this->color($bbcolor)); |
|
570
|
|
|
imagerectangle($this->rawImage, $box->x1, $box->y1, $box->x2, $box->y2, $this->color($bbcolor)); |
|
571
|
|
|
imagestring($this->rawImage, 4, $box->x1, $box->y1 - 16, $label, $this->color($fncolor)); |
|
572
|
|
|
; |
|
573
|
|
|
} |
|
574
|
|
|
|
|
575
|
|
|
} |
|
576
|
|
|
|