| Total Complexity | 159 |
| Total Lines | 558 |
| Duplicated Lines | 0 % |
| Changes | 3 | ||
| Bugs | 1 | Features | 0 |
Complex classes like core often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use core, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 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') { |
||
| 468 | } |
||
| 469 | |||
| 470 | /** |
||
| 471 | * [load_file description] |
||
| 472 | * @param [type] $filename [description] |
||
| 473 | * @return [type] [description] |
||
| 474 | */ |
||
| 475 | protected function createImg() { |
||
| 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) { |
||
| 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) { |
||
| 572 | ; |
||
| 573 | } |
||
| 574 | |||
| 575 | } |
||
| 576 |