PHP 이미지 인식 기술 원리 및 구현

12600 단어 php이미지식별
사실 이미지 인식 기술 은 우리 가 평소에 하 는 암호 검증 과 같은 것 과 별 차이 가 없다.모두 검사 할 데 이 터 를 미리 입고 한 다음 에 사용 할 때 입력(식별)한 데 이 터 를 라 이브 러 리 의 데이터 와 비교 하 는 것 이다.다만 이미지 인식 기술 은 일부 잘못 사용 되 었 을 뿐 우리 의 평소 암호 검증 은 100%일치 해 야 한다.
며칠 전,어떤 친구 가 게임 클릭 으로 추첨 을 하고 사진 속 의 문 자 를 식별 하 는 것 에 대해 이야기 했다.그 당시 에 바로 생각 한 것 은 js 제어 나 플래시 로 커버 층 을 만 드 는 것 이 었 다.이런 방법 이 가장 편리 하고 빠 르 며 서버 자원 을 절약 하 는 것 이 라 고 느 꼈 다.그러나 그 쪽 에서 제시 한 요 구 는 pp 로 이미지 속 의 문 자 를 식별 하 는 것 이 었 다.
공교롭게도 그 이틀 간 의 뉴스 는 1.마 윈 의 얼굴 인식 결제 가 있 었 다.2.12306 은 새로운 인증 코드 를 사용 하여 현재 국내의 티켓 강탈 소프트웨어 도 사용 할 수 없 게 되 었 고 발표 한 지 하루 도 안 되 어 해결 되 었 다.그리고 공교롭게도 그날 아침 자바 의 이미지 인식 기술 문장 을 보 았 다.그래서 PHP 의 이미지 인식 기술 을 생각해 보 았 다.
사실 이미지 인식 이란 신기 술 이 아니 라 적어도 내 가 찾 은 자 료 는 모두 오래 전의 것 이다.단지 나 는 줄곧 이 방면 의 일 에 관련 되 지 않 았 을 뿐,줄곧 본 적 이 없다.
먼저 이번 실험의 수 요 를 말 해 보 자.한 장의 그림 이 있 는데 그 안의 세 개의 위 치 는 각각 세 개의 숫자 가 있 고 해당 위치의 숫자의 값 을 꺼 내야 한다.(눈치 빠 른 친구 들 은 아래 의 코드 가 내 가 가 진 다른 사람의 것 이라는 것 을 알 수 있 을 것 이다.그래,내 가 직접 다른 사람 을 복사 하고 삭제 한 것 이다.왜냐하면 나 는 이런 것 도 조금 해 보고 그만 두 기 때문에 마지막 에 원작 자의 초기 코드 를 붙 일 것 이다)

class gjPhone
{

  protected $imgPath; //     
  protected $imgSize; //     
  protected $hecData; //      
  protected $horData; //        
  protected $verData; //        
  function __construct ($path)
  {
    $this->imgPath = $path;
  }

  public function getHec ()
  {
    $size = getimagesize($this->imgPath);
    $res = imagecreatefrompng($this->imgPath);
    for ($i = 0; $i < $size[1]; ++ $i) {
      for ($j = 0; $j < $size[0]; ++ $j) {
        $rgb = imagecolorat($res, $j, $i);
        $rgbarray = imagecolorsforindex($res, $rgb);
        if ($rgbarray['red'] < 125 || $rgbarray['green'] < 125 ||
             $rgbarray['blue'] < 125) {
          $data[$i][$j] = 1;
        } else {
          $data[$i][$j] = 0;
        }
      }
    }
    $this->imgSize = $size;
    $this->hecData = $data;
  }

  public function magHorData ()
  {
    $data = $this->hecData;
    $size = $this->imgSize;
    $z = 0;
    for ($i = 0; $i < $size[1]; ++ $i) {
      if (in_array('1', $data[$i])) {
        $z ++;
        for ($j = 0; $j < $size[0]; ++ $j) {
          if ($data[$i][$j] == '1') {
            $newdata[$z][$j] = 1;
          } else {
            $newdata[$z][$j] = 0;
          }
        }
      }
    }
    return $this->horData = $newdata;
  }

  public function showPhone ($ndatas)
  {
    error_reporting(0);
    $phone = null;
    $d = 0;
    foreach ($ndatas as $key => $val) {
      if (in_array(1, $val)) {
        foreach ($val as $k => $v) {
          $ndArr[$d] .= $v;
        }
      }
      if (! in_array(1, $val)) {
        $d ++;
      }
    }
    foreach ($ndArr as $key01 => $val01) {
      $phone .= $this->initData($val01);
    }
    return $phone;
  }

  /**
   *     
   */
  public function initData ($numStr)
  {
    $result = null;
    $data = array(
        '1' => '00000000111000000000000001110000000001001000100000000010100011000000000011000110000000000110000100000000010110011000000',
        '5' => '00000000001000000000000000010000000000100100100000000000101001110000000000100000110000000011000000100000001101000010000',
        '10' => '00000011100011100000000011001100100100100010010001000110000100100010001100001001000100011000010010001001001001100010100'
    );
    foreach ($data as $key => $val) {
      similar_text($numStr, $val, $pre);
      if ($pre > 95) { //    95%  
        $result = $key;
        break;
      }
    }
    return $result;
  }
}

$imgurl = 'jd.png';
list ($width, $heght, $type, $attr) = getimagesize($imgurl);
$new_w = 17;
$new_h = 11;
$thisimage = imagecreatetruecolor($new_w, $new_h); // $new_w, $new_h          
$background = imagecolorallocate($thisimage, 255, 255, 255);
imagefilledrectangle($thisimage, 0, 0, $new_w, $new_h, $background);
$oldimg = imagecreatefrompng($imgurl); //       
                    
//           (        js        ,       ,   ps      )
$weizhi = array(
    '1' => 165,
    '5' => 308,
    '10' => 456
);

foreach ($weizhi as $wwzz) {
  $src_y = 108;
  imagecopy($thisimage, $oldimg, 0, 0, $wwzz, $src_y, $new_w, $new_h); // $src_y,$new_w                       src_im      src_x,src_y  ,   src_w,   src_h       dst_im      dst_x dst_y    。
  $tem_png = 'tem_1.png';
  imagepng($thisimage, __DIR__ . '/' . $tem_png); //         copy                ,            。
  
  $gjPhone = new gjPhone($tem_png); //     
  $gjPhone->getHec(); //         
  $horData = $gjPhone->magHorData(); //          01     、           
  $phone = $gjPhone->showPhone($horData); //      01               ,   95      ,                
  echo '| ' . $phone . ' | ';
}
그 러 고 보 니 12306 인증 코드 가 풀 린 것 도 사정 이 있 는 셈 이 고 그렇게 주필 할 필요 도 없다.인증 코드 그림 을 계속 잡 고 프로그램 에서 읽 을 수 있 는 데이터 로 전환 하여 라 이브 러 리 에 저장 한 다음 검증 할 때 일치 하면 됩 니 다.그렇다면 아 리 의 얼굴 인식 결제 원리 도 이해 한 셈 이지 만 정교 하 게 만 들 수 있 을 것 이다.
전단 시간 에 아 리 운 의 인증 코드 형식 을 보 았 는데 처음에는 좀 나 아 질 것 같 았 는데 지금 보면 마음 만 있 으 면 풀 수 있 잖 아 요.

자,다음은 원작 코드 입 니 다.

/**
 *       .
 * @author by zsc for 2010.03.24
 */
class gjPhone
{

  protected $imgPath; //     
  protected $imgSize; //     
  protected $hecData; //      
  protected $horData; //        
  protected $verData; //        
  function __construct ($path)
  {
    $this->imgPath = $path;
  }

  /**
   *       ...
   *
   * @param unknown_type $path      
   * @return unknown
   */
  public function getHec ()
  {
    $size = getimagesize($this->imgPath);
    $res = imagecreatefrompng($this->imgPath);
    for ($i = 0; $i < $size[1]; ++ $i) {
      for ($j = 0; $j < $size[0]; ++ $j) {
        $rgb = imagecolorat($res, $j, $i);
        $rgbarray = imagecolorsforindex($res, $rgb);
        if ($rgbarray['red'] < 125 || $rgbarray['green'] < 125 ||
             $rgbarray['blue'] < 125) {
          $data[$i][$j] = 1;
        } else {
          $data[$i][$j] = 0;
        }
      }
    }
    $this->imgSize = $size;
    $this->hecData = $data;
  }

  /**
   *             ...
   *
   * @return unknown
   */
  public function magHorData ()
  {
    $data = $this->hecData;
    $size = $this->imgSize;
    $z = 0;
    for ($i = 0; $i < $size[1]; ++ $i) {
      if (in_array('1', $data[$i])) {
        $z ++;
        for ($j = 0; $j < $size[0]; ++ $j) {
          if ($data[$i][$j] == '1') {
            $newdata[$z][$j] = 1;
          } else {
            $newdata[$z][$j] = 0;
          }
        }
      }
    }
    return $this->horData = $newdata;
  }

  /**
   *       ...
   *
   * @return unknown
   */
  public function magVerData ($newdata)
  {
    for ($i = 0; $i < 132; ++ $i) {
      for ($j = 1; $j < 13; ++ $j) {
        $ndata[$i][$j] = $newdata[$j][$i];
      }
    }
    
    $sum = count($ndata);
    $c = 0;
    for ($a = 0; $a < $sum; $a ++) {
      $value = $ndata[$a];
      if (in_array(1, $value)) {
        $ndatas[$c] = $value;
        $c ++;
      } elseif (is_array($ndatas)) {
        $b = $c - 1;
        if (in_array(1, $ndatas[$b])) {
          $ndatas[$c] = $value;
          $c ++;
        }
      }
    }
    
    return $this->verData = $ndatas;
  }

  /**
   *       ...
   *
   * @return unknown
   */
  public function showPhone ($ndatas)
  {
    $phone = null;
    $d = 0;
    foreach ($ndatas as $key => $val) {
      if (in_array(1, $val)) {
        foreach ($val as $k => $v) {
          $ndArr[$d] .= $v;
        }
      }
      if (! in_array(1, $val)) {
        $d ++;
      }
    }
    foreach ($ndArr as $key01 => $val01) {
      $phone .= $this->initData($val01);
    }
    return $phone;
  }

  /**
   *     ...
   *
   * @param unknown_type $dataArr      
   */
  function drawWH ($dataArr)
  {
    if (is_array($dataArr)) {
      foreach ($dataArr as $key => $val) {
        foreach ($val as $k => $v) {
          if ($v == 0) {
            $c .= "<font color='#FFFFFF'>" . $v . "</font>";
          } else {
            $c .= $v;
          }
        }
        $c .= "<br/>";
      }
    }
    echo $c;
  }

  /**
   *     ...
   *
   * @param unknown_type $numStr      
   * @return unknown
   */
  public function initData ($numStr)
  {
    $result = null;
    $data = array(
        0 => '000011111000001111111110011000000011110000000001110000000001110000000001110000000001011000000011011100000111000111111100000001110000',
        1 => '011000000000011000000000111111111111111111111111',
        2 => '001000000011011000000111110000001101110000011001110000011001110000110001111001100001011111100001000110000001',
        3 => '001000000010011000000011110000000001110000000001110000110001110000110001011001110011011111011111000110001100',
        4 => '000000001100000000111100000001111100000011101100000111001100001100001100011000001100111111111111111111111111000000001100000000000100',
        5 => '111111000001111111000001110001000001110001000001110001100001110001100001110000110011110000111111000000001100',
        6 => '000011111000001111111110011000110011110001100001110001100001110001100001110001100001010001110011010000111111000000001100',
        7 => '110000000000110000000111110000111111110001110000110111000000111100000000111000000000111000000000',
        8 => '000100011110011111111111110011100001110001100001110001100001110001100001110011100001011111111111000100011110',
        9 => '001111000000011111100001110000110001110000110001110000110001110000110001011000100001011111100111000111111110000001110000'
    );
    foreach ($data as $key => $val) {
      similar_text($numStr, $val, $pre);
      if ($pre > 95) { //    95%  
        $result = $key;
        break;
      }
    }
    return $result;
  }
}

$imgPath = "http://bj.ganji.com/tel/5463013757650d6c5e31093e563c51315b6c5c6c5237.png";
$gjPhone = new gjPhone($imgPath);
//       
$gjPhone->getHec();
//       
$horData = $gjPhone->magHorData();
echo "===============    ==============<br/><br/><br/>";
$gjPhone->drawWH($horData);
//       
$verData = $gjPhone->magVerData($horData);
echo "<br/><br/><br/>===============    ==============< br/><br/><br/>";
$gjPhone->drawWH($verData);

//     
$phone = $gjPhone->showPhone($verData);
echo "<br/><br/><br/>===============  ==============<br /><br/><br/>" . $phone;

이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기