Kennt jemand eine gute Möglichkeit, Gesichtserkennung in PHP zu tun? I came across some code here das behauptet, dies zu tun, aber ich kann nicht scheinen, damit es richtig funktioniert. Ich würde gerne diese Arbeit machen (obwohl es langsam wird) und jede Hilfe, die Sie mir geben können, wäre sehr geschätzt.Gesichtserkennung in PHP
Hier ist der Code aus dem Link:
<?php
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// @Author Karthik Tharavaad
// [email protected]
// @Contributor Maurice Svay
// [email protected]
class Face_Detector {
protected $detection_data;
protected $canvas;
protected $face;
private $reduced_canvas;
public function __construct($detection_file = 'detection.dat') {
if (is_file($detection_file)) {
$this->detection_data = unserialize(file_get_contents($detection_file));
} else {
throw new Exception("Couldn't load detection data");
}
//$this->detection_data = json_decode(file_get_contents('data.js'));
}
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);
}
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;
}
}
Verbrauch:
$detector = new Face_Detector('detection.dat');
$detector->face_detect('maurice_svay_150.jpg');
$detector->toJpeg();
Das Problem, das ich in laufen lasse, scheint in den Kommentaren auch auf dieser Seite kommen zu werden. "imagecolorat() [function.imagecolorat]: 320,1 ist außerhalb der Grenzen." Also, ich habe eine Fehlermeldung (0) an den Anfang der Datei (nicht wirklich die Lösung) hinzugefügt, und es scheint manchmal zu arbeiten, während es manchmal einfach nichts tut.
Irgendwelche Gedanken?
möglich Duplikat [Gesichtserkennung/dete ction PHP oder Software für Foto- und Videogalerien] (http://stackoverflow.com/questions/1210672/facial-recognition-detection-php-o--software-for-photo-and-video-galerien) – Gordon