一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - PHP教程 - PHP圖像識(shí)別技術(shù)原理與實(shí)現(xiàn)

PHP圖像識(shí)別技術(shù)原理與實(shí)現(xiàn)

2021-03-16 16:16ruesin PHP教程

本篇文章主要介紹了PHP圖像識(shí)別技術(shù)原理與實(shí)現(xiàn),這個(gè)平時(shí)做的密碼驗(yàn)證有異曲同工之處,有需要的可以了解一下。

其實(shí)圖像識(shí)別技術(shù)與我們平時(shí)做的密碼驗(yàn)證之類的沒有什么區(qū)別,都是事先把要校驗(yàn)的數(shù)據(jù)入庫,然后使用時(shí)將錄入(識(shí)別)的數(shù)據(jù)與庫中的數(shù)據(jù)做對(duì)比,只不過圖像識(shí)別技術(shù)有一部分的容錯(cuò)性,而我們平時(shí)的密碼驗(yàn)證是要100%匹配。

前幾天,有朋友談到做游戲點(diǎn)擊抽獎(jiǎng),識(shí)別圖片中的文字,當(dāng)時(shí)立馬想到的就是js控制或者flash做遮罩層,感覺這種辦法是最方便快捷效果好,而且節(jié)省服務(wù)器資源,但是那邊提的要求竟然是通過php識(shí)別圖像中的文字。

趕巧那兩天的新聞?dòng)校?、馬云人臉識(shí)別支付;2、12306使用新的驗(yàn)證碼,說什么現(xiàn)在國內(nèi)的搶票軟件都不能用了,發(fā)布不到一天就被破解。然后又很湊巧的那天早上看了一篇java的圖像識(shí)別技術(shù)文章。于是就琢磨著看一下php的圖像識(shí)別技術(shù)。

其實(shí)所謂的圖像識(shí)別,已經(jīng)不是什么新技術(shù)了,起碼我找到的資料都是很早之前的了。只不過我一直沒涉及到這方面的工作,就一直沒看過。

先說下這次實(shí)驗(yàn)的需求:有一張圖片,里面三個(gè)位置分別有三個(gè)數(shù)字,要求取出相應(yīng)位置的數(shù)字的值。(眼尖的同學(xué)可能會(huì)看出下面的代碼是我拿的別人的,沒錯(cuò),的確是我直接copy別人并刪減的,畢竟我對(duì)這些也是淺嘗輒止,最后會(huì)貼出原作者的初始代碼)

PHP圖像識(shí)別技術(shù)原理與實(shí)現(xiàn)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
class gjphone
{
 
  protected $imgpath; // 圖片路徑
  protected $imgsize; // 圖片大小
  protected $hecdata; // 分離后數(shù)組
  protected $hordata; // 橫向整理的數(shù)據(jù)
  protected $verdata; // 縱向整理的數(shù)據(jù)
  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;
  }
 
  /**
   * 初始數(shù)據(jù)
   */
  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或者其他手段定位,由于我這是測(cè)試,所以就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為原圖中裁剪區(qū)域的左上角坐標(biāo)拷貝圖像的一部分將src_im圖像中坐標(biāo)從src_x,src_y開始,寬度為src_w,高度為src_h的一部分拷貝到dst_im圖像中坐標(biāo)為dst_x和dst_y的位置上。
  $tem_png = 'tem_1.png';
  imagepng($thisimage, __dir__ . '/' . $tem_png); // 通過定位從原圖中copy出想要識(shí)別的位置并生成新的緩存圖,用以后面的圖像識(shí)別類使用。
  
  $gjphone = new gjphone($tem_png); // 實(shí)例化類
  $gjphone->gethec(); // 進(jìn)行圖像像素分離
  $hordata = $gjphone->maghordata(); // 將分離出是數(shù)據(jù)轉(zhuǎn)成01表示的圖像、這里可以根據(jù)自己喜好定
  $phone = $gjphone->showphone($hordata); // 將轉(zhuǎn)換好的01表示的數(shù)據(jù)與庫中的數(shù)據(jù)進(jìn)行匹配,匹配度95以上就算成功,庫這里由于是做測(cè)試就直接寫了數(shù)組
  echo '| ' . $phone . ' | ';
}

如此看來,其實(shí)12306驗(yàn)證碼被破解也算是有情可原了,也沒必要那么的口誅筆伐了罷。只要不斷的抓驗(yàn)證碼圖片并轉(zhuǎn)成自己程序可讀的數(shù)據(jù)存入庫里,然后驗(yàn)證的時(shí)候進(jìn)行匹配就可以了。那么阿里的人臉識(shí)別支付原理也算是理解了,只不過他們做的可能會(huì)很精細(xì)。

前端時(shí)間有看到阿里云的一個(gè)驗(yàn)證碼形式,剛開始感覺可能會(huì)好點(diǎn),現(xiàn)在看來,只要有心,其實(shí)也是可以破解的啊。

PHP圖像識(shí)別技術(shù)原理與實(shí)現(xiàn)

好了,下面是原作代碼。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/**
 * 電話號(hào)碼識(shí)別.
 * @author by zsc for 2010.03.24
 */
class gjphone
{
 
  protected $imgpath; // 圖片路徑
  protected $imgsize; // 圖片大小
  protected $hecdata; // 分離后數(shù)組
  protected $hordata; // 橫向整理的數(shù)據(jù)
  protected $verdata; // 縱向整理的數(shù)據(jù)
  function __construct ($path)
  {
    $this->imgpath = $path;
  }
 
  /**
   * 顏色分離轉(zhuǎn)換...
   *
   * @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;
  }
 
  /**
   * 顏色分離后的數(shù)據(jù)橫向整理...
   *
   * @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;
  }
 
  /**
   * 整理縱向數(shù)據(jù)...
   *
   * @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;
  }
 
  /**
   * 顯示電話號(hào)碼...
   *
   * @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;
  }
 
  /**
   * 初始數(shù)據(jù)...
   *
   * @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);
// 進(jìn)行顏色分離
$gjphone->gethec();
// 畫出橫向數(shù)據(jù)
$hordata = $gjphone->maghordata();
echo "===============橫向數(shù)據(jù)==============<br/><br/><br/>";
$gjphone->drawwh($hordata);
// 畫出縱向數(shù)據(jù)
$verdata = $gjphone->magverdata($hordata);
echo "<br/><br/><br/>===============縱向數(shù)據(jù)==============< br/><br/><br/>";
$gjphone->drawwh($verdata);
 
// 輸出電話
$phone = $gjphone->showphone($verdata);
echo "<br/><br/><br/>===============電話==============<br /><br/><br/>" . $phone;

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 教练你好大轻点漫 | 99久久国产综合精麻豆 | 欧美视频在线一区 | 亚洲色图网址 | 丰满的闺蜜2中文字幕 | 亚洲精品成人A8198A片漫画 | 日韩二三区 | 天天草b | 免费观看毛片视频 | 欧美成狂野欧美在线观看 | 亚洲免费在线视频 | 国产在线观看a | 欧美日韩精彩视频 | 青青在线香蕉国产精品 | 男人天堂亚洲 | 青青草99热这里都是精品 | 国产一级真人毛爱做毛片 | 国产精品第四页 | 日本久本草精品 | 污污免费 | 王淑兰与铁柱全文免费阅读 | 青青青久热国产精品视频 | 九九在线免费视频 | 短篇小说肉 | 青草视频在线观看视频 | 日本xxxxx69hd日本 | 交换朋友夫妇3中文字幕 | 大乳一级一区二区三区 | 日本一区二区视频在线观看 | 蜜桃久久久亚洲精品成人 | 女人张开腿让男人桶爽 | a天堂在线视频 | 国产精品一区久久精品 | 九九精品99久久久香蕉 | 91久久国产视频 | 国内精品中文字幕 | 成人小视频在线观看免费 | tube99大学生 | 国产精品边做边接电话在线观看 | 波多野结衣中文字幕在线 | 国产精品午夜国产小视频 |