Do not speak Portuguese? Translate this site with Google or Bing Translator
Reconhecimento Facial com PHP

Posted on: July 31, 2020 03:30 PM

Posted by: Renato

Categories: PHP faceapp

Views: 603

Autor: 

Classe Face_Detector (FaceDetector.php)

detection_data = unserialize(file_get_contents($detection_file));
 } else {
 throw new Exception("Couldn't load detection data");
 }
 }
 
 public function face_detect($file) {
 if (!is_file($file)) {
 throw new Exception("Can not load $file");
 }
 
 $this->canvas = imagecreatefromjpeg($file);
 $im_width = imagesx($this->canvas);
 $im_height = imagesy($this->canvas);

 //Resample before detection?
 $ratio = 0;
 $diff_width = 320 - $im_width;
 $diff_height = 240 - $im_height;
 if ($diff_width > $diff_height) {
 $ratio = $im_width / 320;
 } else {
 $ratio = $im_height / 240;
 }

 if ($ratio != 0) {
 $this->reduced_canvas = imagecreatetruecolor($im_width / $ratio, $im_height / $ratio);
 imagecopyresampled($this->reduced_canvas, $this->canvas, 0, 0, 0, 0, $im_width / $ratio, $im_height / $ratio, $im_width, $im_height);
 
 $stats = $this->get_img_stats($this->reduced_canvas);
 $this->face = $this->do_detect_greedy_big_to_small($stats['ii'], $stats['ii2'], $stats['width'], $stats['height']);
 $this->face['x'] *= $ratio;
 $this->face['y'] *= $ratio;
 $this->face['w'] *= $ratio;
 } else {
 $stats = $this->get_img_stats($this->canvas);
 $this->face = $this->do_detect_greedy_big_to_small($stats['ii'], $stats['ii2'], $stats['width'], $stats['height']);
 }
 return ($this->face['w'] > 0);
 }
 
 
 public function toJpeg() {
 $color = imagecolorallocate($this->canvas, 255, 0, 0); //red
 imagerectangle($this->canvas, $this->face['x'], $this->face['y'], $this->face['x']+$this->face['w'], $this->face['y']+ $this->face['w'], $color);
 header('Content-type: image/jpeg');
 imagejpeg($this->canvas);
 }
 
 /* Added by codediesel - debug by jonatahs guerra */
 public function cropFace() {
 $canvas = imagecreatetruecolor($this->face['w'], $this->face['w']);
 imagecopy($canvas, $this->canvas, 0, 0, $this->face['x'], $this->face['y'], $this->face['w'], $this->face['w']);
 header('Content-type: image/jpeg');
 imagejpeg($canvas);
 }
 
 public function toJson() {
 return "{'x':" . $this->face['x'] . ", 'y':" . $this->face['y'] . ", 'w':" . $this->face['w'] . "}";
 }
 
 public function getFace() {
 return $this->face;
 }
 
 protected function get_img_stats($canvas){
 $image_width = imagesx($canvas);
 $image_height = imagesy($canvas); 
 $iis = $this->compute_ii($canvas, $image_width, $image_height);
 return array(
 'width' => $image_width,
 'height' => $image_height,
 'ii' => $iis['ii'],
 'ii2' => $iis['ii2']
 ); 
 }
 
 protected function compute_ii($canvas, $image_width, $image_height ){
 $ii_w = $image_width+1;
 $ii_h = $image_height+1;
 $ii = array();
 $ii2 = array(); 
 
 for($i=0; $i<$ii_w; $i++ ){
 $ii[$i] = 0;
 $ii2[$i] = 0;
 } 
 
 for($i=1; $i<$ii_w; $i++ ){ 
 $ii[$i*$ii_w] = 0; 
 $ii2[$i*$ii_w] = 0; 
 $rowsum = 0;
 $rowsum2 = 0;
 for($j=1; $j<$ii_h; $j++ ){
 $rgb = ImageColorAt($canvas, $j, $i);
 $red = ($rgb >> 16) & 0xFF;
 $green = ($rgb >> 8) & 0xFF;
 $blue = $rgb & 0xFF;
 $grey = ( 0.2989*$red + 0.587*$green + 0.114*$blue )>>0; // this is what matlab uses
 $rowsum += $grey;
 $rowsum2 += $grey*$grey;
 
 $ii_above = ($i-1)*$ii_w + $j;
 $ii_this = $i*$ii_w + $j;
 
 $ii[$ii_this] = $ii[$ii_above] + $rowsum;
 $ii2[$ii_this] = $ii2[$ii_above] + $rowsum2;
 }
 }
 return array('ii'=>$ii, 'ii2' => $ii2);
 }
 
 protected function do_detect_greedy_big_to_small( $ii, $ii2, $width, $height ){
 $s_w = $width/20.0;
 $s_h = $height/20.0;
 $start_scale = $s_h < $s_w ? $s_h : $s_w;
 $scale_update = 1 / 1.2;
 for($scale = $start_scale; $scale > 1; $scale *= $scale_update ){
 $w = (20*$scale) >> 0;
 $endx = $width - $w - 1;
 $endy = $height - $w - 1;
 $step = max( $scale, 2 ) >> 0;
 $inv_area = 1 / ($w*$w);
 for($y = 0; $y < $endy ; $y += $step ){
 for($x = 0; $x < $endx ; $x += $step ){
 $passed = $this->detect_on_sub_image( $x, $y, $scale, $ii, $ii2, $w, $width+1, $inv_area);
 if( $passed ) {
 return array('x'=>$x, 'y'=>$y, 'w'=>$w);
 }
 } // end x
 } // end y
 } // end scale
 return null;
 }
 
 protected function detect_on_sub_image( $x, $y, $scale, $ii, $ii2, $w, $iiw, $inv_area){
 $mean = ( $ii[($y+$w)*$iiw + $x + $w] + $ii[$y*$iiw+$x] - $ii[($y+$w)*$iiw+$x] - $ii[$y*$iiw+$x+$w] )*$inv_area;
 $vnorm = ( $ii2[($y+$w)*$iiw + $x + $w] + $ii2[$y*$iiw+$x] - $ii2[($y+$w)*$iiw+$x] - $ii2[$y*$iiw+$x+$w] )*$inv_area - ($mean*$mean); 
 $vnorm = $vnorm > 1 ? sqrt($vnorm) : 1;
 
 $passed = true;
 for($i_stage = 0; $i_stage < count($this->detection_data); $i_stage++ ){
 $stage = $this->detection_data[$i_stage]; 
 $trees = $stage[0]; 

 $stage_thresh = $stage[1];
 $stage_sum = 0;
 
 for($i_tree = 0; $i_tree < count($trees); $i_tree++ ){
 $tree = $trees[$i_tree];
 $current_node = $tree[0]; 
 $tree_sum = 0;
 while( $current_node != null ){
 $vals = $current_node[0];
 $node_thresh = $vals[0];
 $leftval = $vals[1];
 $rightval = $vals[2];
 $leftidx = $vals[3];
 $rightidx = $vals[4];
 $rects = $current_node[1];
 
 $rect_sum = 0;
 for( $i_rect = 0; $i_rect < count($rects); $i_rect++ ){
 $s = $scale;
 $rect = $rects[$i_rect];
 $rx = ($rect[0]*$s+$x)>>0;
 $ry = ($rect[1]*$s+$y)>>0;
 $rw = ($rect[2]*$s)>>0; 
 $rh = ($rect[3]*$s)>>0;
 $wt = $rect[4];
 
 $r_sum = ( $ii[($ry+$rh)*$iiw + $rx + $rw] + $ii[$ry*$iiw+$rx] - $ii[($ry+$rh)*$iiw+$rx] - $ii[$ry*$iiw+$rx+$rw] )*$wt;
 $rect_sum += $r_sum;
 } 
 
 $rect_sum *= $inv_area;
 
 $current_node = null;
 if( $rect_sum >= $node_thresh*$vnorm ){
 if( $rightidx == -1 ) 
 $tree_sum = $rightval;
 else
 $current_node = $tree[$rightidx];
 } else {
 if( $leftidx == -1 )
 $tree_sum = $leftval;
 else
 $current_node = $tree[$leftidx];
 }
 } 
 $stage_sum += $tree_sum;
 } 
 if( $stage_sum < $stage_thresh ){
 return false;
 }
 } 
 return true;
 }
}
?>

Exemplo

O código de exemplo mostra como identificar um rosto. Mesmo que a imagem tenhas mais de um rosto, apenas o primeiro é detectado. Embora possa parecer uma limitação, isso pode ser útil em aplicações web que necessitam para criar uma imagem no perfil do usuário a partir de uma imagem crua. De modo que se um usuário carrega uma imagem de corpo inteiro, o código pode detectar o rosto e criar automaticamente uma imagem no perfil para o usuário. (Isso é muito important pro projeto que estou desenvolvendo)

 

Download detection.dat

http://jonathasguerra.com.br/blog/wp-content/uploads/2015/10/detection.dat_.zip

 

 face_detect("anadearmas.jpg ');
 $detect -> toJpeg();

 ?>

Reconhecendo Rosto

Reconhecendo Rosto

O código acima mostra uma borda ao redor do rosto detectado, em vez disso, podemos cortar diretamente a área do rosto.

 

 face_detect("anadearmas.jpg ');
 $detect -> cropFace();

 ?>

Retornando somente rosto

Retornando somente rosto

Coordenadas do rosto

Caso precise das coordenadas exatas do rosto para usar de alguma maneira, é possível com o código abaixo.

 

toJson();
 
// OU
 
// Retorna coordenadas em um Array
$detect->getFace();
  ?> 

Extensão da Classe

Você pode estender a classe Face_Detector usando seus próprios métodos. Por exemplo esse três métodos – rodar(), tamanho() e escalazina() para a classe, o que permite que você modifique ainda mais o resultado.

 

face['w'], $this->face['w']);
    imagecopy($canvas, $this->canvas, 0, 0, $this->face['x'], 
              $this->face['x'], $this->face['w'], $this->face['w']);
    $canvas = imagerotate($canvas, 180, 0);
    $this->_outImage($canvas);
  }
 
  public function escalacinza() {
    $canvas = imagecreatetruecolor($this->face['w'], $this->face['w']);
    imagecopy($canvas, $this->canvas, 0, 0, $this->face['x'], 
              $this->face['x'], $this->face['w'], $this->face['w']);
    imagefilter ($canvas, IMG_FILTER_GRAYSCALE);
    $this->_outImage($canvas);
  }
 
  public function tamanho($width, $height) {
    $canvas = imagecreatetruecolor($width, $width);
    imagecopyresized($canvas, $this->canvas, 0, 0, $this->face['x'], 
                     $this->face['y'], $width, $height, 
                     $this->face['w'], $this->face['w']);
    $this->_outImage($canvas);
  }
 
  private function _outImage($canvas) {
    header('Content-type: image/jpeg');
    imagejpeg($canvas);
  }
}
 
 
/* Usando */
$detect = new FaceModify('detection.dat');
$detect->face_detect('anadearmas.jpg');
$detect->resizeFace(100,100);
 
?>

Fontes:

https://jonathasguerra.com.br/blog/reconhecimento-facial-com-php-identificando-rosto-em-- imagem-e-cortando/

http://facedetection.jaysalvat.com/

https://github.com/mauricesvay/php-facedetection

https://www.faceplusplus.com/

https://github.com/FacePlusPlus


2

Share

Donate to Site


About Author

Renato

Developer

Add a Comment
Comments 1 Comments
  • Renato de Oliveira Lucena
    Renato de Oliveira Lucena - há 3 anos
    https://github.com/FacePlusPlus/facepp-php-sdk

Blog Search


Categories

OUTROS (15) Variados (109) PHP (130) Laravel (157) Black Hat (3) front-end (28) linux (111) postgresql (39) Docker (25) rest (5) soap (1) webservice (6) October (1) CMS (2) node (7) backend (13) ubuntu (54) devops (25) nodejs (5) npm (2) nvm (1) git (8) firefox (1) react (6) reactnative (5) collections (1) javascript (6) reactjs (7) yarn (0) adb (1) Solid (2) blade (3) models (1) controllers (0) log (0) html (2) hardware (3) aws (14) Transcribe (2) transcription (1) google (4) ibm (1) nuance (1) PHP Swoole (5) mysql (31) macox (4) flutter (1) symfony (1) cor (1) colors (2) homeOffice (2) jobs (3) imagick (2) ec2 (1) sw (1) websocket (1) markdown (1) ckeditor (1) tecnologia (14) faceapp (1) eloquent (14) query (4) sql (40) ddd (3) nginx (9) apache (4) certbot (1) lets-encrypt (3) debian (11) liquid (1) magento (2) ruby (1) LETSENCRYPT (1) Fibonacci (1) wine (1) transaction (1) pendrive (1) boot (1) usb (1) prf (1) policia (2) federal (1) lucena (1) mongodb (4) paypal (1) payment (1) zend (1) vim (4) ciencia (6) js (1) nosql (1) java (1) JasperReports (1) phpjasper (1) covid19 (1) saude (1) athena (1) cinnamon (1) phpunit (2) binaural (1) mysqli (3) database (42) windows (6) vala (1) json (2) oracle (1) mariadb (4) dev (12) webdev (24) s3 (4) storage (1) kitematic (1) gnome (2) web (2) intel (3) piada (1) cron (2) dba (18) lumen (1) ffmpeg (2) android (2) aplicativo (1) fedora (2) shell (4) bash (3) script (3) lider (1) htm (1) csv (1) dropbox (1) db (3) combustivel (2) haru (1) presenter (1) gasolina (1) MeioAmbiente (1) Grunt (1) biologia (1) programming (22) performance (3) brain (1) smartphones (1) telefonia (1) privacidade (1) opensource (3) microg (1) iode (1) ssh (3) zsh (2) terminal (3) dracula (1) spaceship (1) mac (2) idiomas (1) laptop (2) developer (37) api (4) data (1) matematica (1) seguranca (2) 100DaysOfCode (9) hotfix (1) documentation (1) laravelphp (10) RabbitMQ (1) Elasticsearch (1) redis (2) Raspberry (4) Padrao de design (4) JQuery (1) angularjs (4) Dicas (37) Kubernetes (2) vscode (2) backup (1) angular (3) servers (2) pipelines (1) AppSec (1) DevSecOps (4) rust (1) RustLang (1) Mozilla (1) algoritimo (1) sqlite (1) Passport (1) jwt (4) security (2) translate (1) kube (1) iot (1) politica (2) bolsonaro (1) flow (1) podcast (1) Brasil (1) containers (2) traefik (1) networking (1) host (1) POO (2) microservices (2) bug (1) cqrs (1) arquitetura (2) Architecture (3) sail (3) militar (1) artigo (1) economia (1) forcas armadas (1) ffaa (1) autenticacao (1) autorizacao (2) authentication (4) authorization (2) NoCookies (1) wsl (4) memcached (1) macos (2) unix (2) kali-linux (1) linux-tools (5) apple (1) noticias (2) composer (1) rancher (1) k8s (1) escopos (1) orm (1) jenkins (4) github (5) gitlab (3) queue (1) Passwordless (1) sonarqube (1) phpswoole (1) laraveloctane (1) Swoole (1) Swoole (1) octane (1) Structurizr (1) Diagramas (1) c4 (1) c4-models (1) compactar (1) compression (1) messaging (1) restfull (1) eventdrive (1) services (1) http (1) Monolith (1) microservice (1) historia (1) educacao (1) cavalotroia (1) OOD (0) odd (1) chatgpt (1) openai (3) vicuna (1) llama (1) gpt (1) transformers (1) pytorch (1) tensorflow (1) akitando (1) ia (1) nvidia (1) agi (1) guard (1) multiple_authen (2) rpi (1) auth (1) auth (1) livros (2) ElonMusk (2) Oh My Zsh (1) Manjaro (1) BigLinux (2) ArchLinux (1) Migration (1) Error (1) Monitor (1) Filament (1) LaravelFilament (1) replication (1) phpfpm (1) cache (1) vpn (1) l2tp (1) zorin-os (1) optimization (1) scheduling (1) monitoring (2) linkedin (1) community (1) inteligencia-artificial (2) wsl2 (1) maps (1) API_KEY_GOOGLE_MAPS (1) repmgr (1) altadisponibilidade (1) banco (1) modelagemdedados (1) inteligenciadedados (4) governancadedados (1) bancodedados (2) Observability (1) picpay (1) ecommerce (1)

New Articles



Get Latest Updates by Email