首页 > 技术文章 > PHP识别简单的图片上面的数字(可扩展)

reader 2017-01-18 12:29 原文

 

1、场景

  最近在学习图片处理,就是特意把数字生成一个图片,然后再用程序去识别图片的数字。这就有了一下的学习过程。

 

2、原理分析

  2.1 首先是将图片像素化,二值化,然后和字模去对比(需要相对于配置字模)

   

        ||

        \/

  

        ||

        \/

  

 

  2.2 然后再这每个数字分别取出来,与字模库做比较,匹配成功即可获取对应的值

    

 

 3、源码

  3.1 经过我修改后的代码

    使用说明:通过传入的图片地址获取图片的数字,$imgPath为图片路径

    执行步骤:先把图片像素化,二值化,保存数组,先横向,再纵向,只要因为纵向方便处理单独数字,然后把纵向的数据跟字模库进行匹配,当匹配率达到95%以上即认为识别成功。

 1 //【获取图片数字】
 2 //$imgPath:图片路径
 3     private function getPhoneByImg($imgPath){
 4         
 5         $gjPhone = new GjPhone($imgPath);
 6         // 进行颜色分离
 7         $gjPhone->getHec();
 8         // 画出横向数据
 9         $horData = $gjPhone->magHorData();
10         //echo "===============横向数据==============<br/><br/><br/>";
11         //$gjPhone->drawWH($horData);
12         // 画出纵向数据
13         $verData = $gjPhone->magVerData($horData);
14         //echo "<br/><br/><br/>===============纵向数据==============< br/><br/><br/>";
15         //$gjPhone->drawWH($verData);
16          
17         // 输出电话
18 
19         $phone = $gjPhone->showPhone($verData);
20         //echo "<br/><br/><br/>===============电话==============<br /><br/><br/>";
21         //$this->show($phone);
22         
23         return $phone;
24     
25     }

 

  1 <?php
  2 namespace common\models;
  3 
  4 /**
  5  * 电话号码识别.
  6  * @author by zsc for 2010.03.24
  7  */
  8 class GjPhone
  9 {
 10  
 11   protected $imgPath; // 图片路径
 12   protected $imgSize; // 图片大小
 13   protected $hecData; // 分离后数组
 14   protected $horData; // 横向整理的数据
 15   protected $verData; // 纵向整理的数据
 16   function __construct ($path)
 17   {
 18     $this->imgPath = $path;
 19   }
 20  
 21   /**
 22    * 颜色分离转换...
 23    *
 24    * @param unknown_type $path      
 25    * @return unknown
 26    */
 27   public function getHec ()
 28   {
 29     $size = getimagesize($this->imgPath);
 30     $res = imagecreatefrompng($this->imgPath);
 31     for ($i = 0; $i < $size[1]; ++ $i) {
 32       for ($j = 0; $j < $size[0]; ++ $j) {
 33         $rgb = imagecolorat($res, $j, $i);
 34         $rgbarray = imagecolorsforindex($res, $rgb);
 35         if ($rgbarray['red'] < 125 || $rgbarray['green'] < 125 ||
 36              $rgbarray['blue'] < 125) {
 37           $data[$i][$j] = 1;
 38         } else {
 39           $data[$i][$j] = 0;
 40         }
 41       }
 42     }
 43     $this->imgSize = $size;
 44     $this->hecData = $data;
 45   }
 46  
 47   /**
 48    * 颜色分离后的数据横向整理...
 49    *
 50    * @return unknown
 51    */
 52   public function magHorData ()
 53   {
 54     $data = $this->hecData;
 55     $size = $this->imgSize;
 56     $z = 0;
 57     for ($i = 0; $i < $size[1]; ++ $i) {
 58       if (in_array('1', $data[$i])) {
 59         $z ++;
 60         for ($j = 0; $j < $size[0]; ++ $j) {
 61           if ($data[$i][$j] == '1') {
 62             $newdata[$z][$j] = 1;
 63           } else {
 64             $newdata[$z][$j] = 0;
 65           }
 66         }
 67       }
 68     }
 69     return $this->horData = $newdata;
 70   }
 71  
 72   /**
 73    * 整理纵向数据...
 74    *
 75    * @return unknown
 76    */
 77   public function magVerData ($newdata)
 78   {
 79     $i_length = count($newdata[1]);
 80     $j_length = count($newdata)+1;
 81     for ($i = 0; $i < $i_length; ++ $i) {
 82       for ($j = 1; $j < $j_length; ++ $j) {
 83         $ndata[$i][$j] = $newdata[$j][$i];
 84       }
 85     }
 86      
 87     $ndatas= [];
 88     $sum = count($ndata);
 89     $c = 0;
 90     for ($a = 0; $a < $sum; $a ++) {
 91       $value = $ndata[$a];
 92       if (in_array(1, $value)) {
 93         $ndatas[$c] = $value;
 94         $c ++;
 95       } elseif (is_array($ndatas)) {
 96         $b = $c - 1;
 97         if (isset($ndatas[$b]) && in_array(1, $ndatas[$b])) {
 98           $ndatas[$c] = $value;
 99           $c ++;
100         }
101       }
102     }
103      
104     return $this->verData = $ndatas;
105   }
106  
107   /**
108    * 显示电话号码...
109    *
110    * @return unknown
111    */
112   public function showPhone ($ndatas)
113   {
114     $phone = '';
115     $d = 0;
116     $ndArr = [];
117     $ndArr[0] = '';
118     foreach ($ndatas as $key => $val) {
119         
120       if (in_array(1, $val)) {
121           
122         foreach ($val as $k => $v) {
123           $ndArr[$d] .= $v;
124         }
125       }else{
126           $d ++;
127           $ndArr[$d] = '';
128       }
129      
130     }
131     array_pop($ndArr);
132     //return $ndArr;
133     
134     
135     foreach ($ndArr as $key01 => $val01) {
136       $phone .= $this->initData($val01);
137     }
138     return $phone;
139   }
140  
141   /**
142    * 分离显示...
143    *
144    * @param unknown_type $dataArr      
145    */
146   function drawWH ($dataArr)
147   {
148       $c = '';
149     if (is_array($dataArr)) {
150       foreach ($dataArr as $key => $val) {
151         foreach ($val as $k => $v) {
152           if ($v == 0) {
153             $c .= "<font color='grend'>" . $v . "</font>";
154           } else {
155             $c .= $v;
156           }
157         }
158         $c .= "<br/>";
159       }
160     }
161     echo $c;
162   }
163  
164   /**
165    * 初始数据...
166    *
167    * @param unknown_type $numStr      
168    * @return unknown
169    */
170   public function initData ($numStr)
171   {    
172     //return 1;
173     $result = '';
174     $data = array(
175         0 => '00011110000011111100011000011011000000111100000011011000011000111111000001111000',
176         1 => '001000000101100000011111111111111111111100000000010000000001',
177         2 => '00100000010110000011110000011110000011011000011001110011000101111000010011000001',
178         //3 => '001000000010011000000011110000000001110000000001110000110001110000110001011001110011011111011111000110001100',
179         3=> '01000000101100000011100000000110001000011000100001110111001101110111100010001100',
180         //4 => '000000001100000000111100000001111100000011101100000111001100001100001100011000001100111111111111111111111111000000001100000000000100',
181         4 => '00000110000000111000000110100000110010000110001000111111111111111111110000001000',
182         5 => '11111001001111100110100010001110010000011001000001100110001110001111100000011100',
183         6 => '00111111000111111110110001001110001000011000100001110011001101100111100000001100',
184         //7 => '110000000000110000000111110000111111110001110000110111000000111100000000111000000000111000000000',
185         7 => '10000000111000000111100000110010000110001000110000100110000011110000001110000000',
186         //8 => '000100011110011111111111110011100001110001100001110001100001110001100001110011100001011111111111000100011110',
187         8 => '00100011000111011110110111001110001000011000100001110111001101110111100010001100',
188         9 => '00110000000111100110110011001110000100011000010001110010001101111111100011111100',
189         
190         '-' => '00000100000000010000000001000000000100000000010000000001000000000100000000010000'
191     );
192 
193     
194     
195     foreach ($data as $key => $val) {
196       similar_text($numStr, $val, $pre);
197       if ($pre > 95) { // 相似度95%以上
198         
199         $result .= $key;
200         break;
201       }
202     }
203     return $result;
204   }
205 }
206  
GjPhone.php

    

  3.2 引用的源码

    

  1 /**
  2  * 电话号码识别.
  3  * @author by zsc for 2010.03.24
  4  */
  5 class gjPhone
  6 {
  7  
  8   protected $imgPath; // 图片路径
  9   protected $imgSize; // 图片大小
 10   protected $hecData; // 分离后数组
 11   protected $horData; // 横向整理的数据
 12   protected $verData; // 纵向整理的数据
 13   function __construct ($path)
 14   {
 15     $this->imgPath = $path;
 16   }
 17  
 18   /**
 19    * 颜色分离转换...
 20    *
 21    * @param unknown_type $path      
 22    * @return unknown
 23    */
 24   public function getHec ()
 25   {
 26     $size = getimagesize($this->imgPath);
 27     $res = imagecreatefrompng($this->imgPath);
 28     for ($i = 0; $i < $size[1]; ++ $i) {
 29       for ($j = 0; $j < $size[0]; ++ $j) {
 30         $rgb = imagecolorat($res, $j, $i);
 31         $rgbarray = imagecolorsforindex($res, $rgb);
 32         if ($rgbarray['red'] < 125 || $rgbarray['green'] < 125 ||
 33              $rgbarray['blue'] < 125) {
 34           $data[$i][$j] = 1;
 35         } else {
 36           $data[$i][$j] = 0;
 37         }
 38       }
 39     }
 40     $this->imgSize = $size;
 41     $this->hecData = $data;
 42   }
 43  
 44   /**
 45    * 颜色分离后的数据横向整理...
 46    *
 47    * @return unknown
 48    */
 49   public function magHorData ()
 50   {
 51     $data = $this->hecData;
 52     $size = $this->imgSize;
 53     $z = 0;
 54     for ($i = 0; $i < $size[1]; ++ $i) {
 55       if (in_array('1', $data[$i])) {
 56         $z ++;
 57         for ($j = 0; $j < $size[0]; ++ $j) {
 58           if ($data[$i][$j] == '1') {
 59             $newdata[$z][$j] = 1;
 60           } else {
 61             $newdata[$z][$j] = 0;
 62           }
 63         }
 64       }
 65     }
 66     return $this->horData = $newdata;
 67   }
 68  
 69   /**
 70    * 整理纵向数据...
 71    *
 72    * @return unknown
 73    */
 74   public function magVerData ($newdata)
 75   {
 76     for ($i = 0; $i < 132; ++ $i) {
 77       for ($j = 1; $j < 13; ++ $j) {
 78         $ndata[$i][$j] = $newdata[$j][$i];
 79       }
 80     }
 81      
 82     $sum = count($ndata);
 83     $c = 0;
 84     for ($a = 0; $a < $sum; $a ++) {
 85       $value = $ndata[$a];
 86       if (in_array(1, $value)) {
 87         $ndatas[$c] = $value;
 88         $c ++;
 89       } elseif (is_array($ndatas)) {
 90         $b = $c - 1;
 91         if (in_array(1, $ndatas[$b])) {
 92           $ndatas[$c] = $value;
 93           $c ++;
 94         }
 95       }
 96     }
 97      
 98     return $this->verData = $ndatas;
 99   }
100  
101   /**
102    * 显示电话号码...
103    *
104    * @return unknown
105    */
106   public function showPhone ($ndatas)
107   {
108     $phone = null;
109     $d = 0;
110     foreach ($ndatas as $key => $val) {
111       if (in_array(1, $val)) {
112         foreach ($val as $k => $v) {
113           $ndArr[$d] .= $v;
114         }
115       }
116       if (! in_array(1, $val)) {
117         $d ++;
118       }
119     }
120     foreach ($ndArr as $key01 => $val01) {
121       $phone .= $this->initData($val01);
122     }
123     return $phone;
124   }
125  
126   /**
127    * 分离显示...
128    *
129    * @param unknown_type $dataArr      
130    */
131   function drawWH ($dataArr)
132   {
133     if (is_array($dataArr)) {
134       foreach ($dataArr as $key => $val) {
135         foreach ($val as $k => $v) {
136           if ($v == 0) {
137             $c .= "<font color='#FFFFFF'>" . $v . "</font>";
138           } else {
139             $c .= $v;
140           }
141         }
142         $c .= "<br/>";
143       }
144     }
145     echo $c;
146   }
147  
148   /**
149    * 初始数据...
150    *
151    * @param unknown_type $numStr      
152    * @return unknown
153    */
154   public function initData ($numStr)
155   {
156     $result = null;
157     $data = array(
158         0 => '000011111000001111111110011000000011110000000001110000000001110000000001110000000001011000000011011100000111000111111100000001110000',
159         1 => '011000000000011000000000111111111111111111111111',
160         2 => '001000000011011000000111110000001101110000011001110000011001110000110001111001100001011111100001000110000001',
161         3 => '001000000010011000000011110000000001110000000001110000110001110000110001011001110011011111011111000110001100',
162         4 => '000000001100000000111100000001111100000011101100000111001100001100001100011000001100111111111111111111111111000000001100000000000100',
163         5 => '111111000001111111000001110001000001110001000001110001100001110001100001110000110011110000111111000000001100',
164         6 => '000011111000001111111110011000110011110001100001110001100001110001100001110001100001010001110011010000111111000000001100',
165         7 => '110000000000110000000111110000111111110001110000110111000000111100000000111000000000111000000000',
166         8 => '000100011110011111111111110011100001110001100001110001100001110001100001110011100001011111111111000100011110',
167         9 => '001111000000011111100001110000110001110000110001110000110001110000110001011000100001011111100111000111111110000001110000'
168     );
169     foreach ($data as $key => $val) {
170       similar_text($numStr, $val, $pre);
171       if ($pre > 95) { // 相似度95%以上
172         $result = $key;
173         break;
174       }
175     }
176     return $result;
177   }
178 }
179  
180 $imgPath = "http://bj.ganji.com/tel/5463013757650d6c5e31093e563c51315b6c5c6c5237.png";
181 $gjPhone = new gjPhone($imgPath);
182 // 进行颜色分离
183 $gjPhone->getHec();
184 // 画出横向数据
185 $horData = $gjPhone->magHorData();
186 echo "===============横向数据==============<br/><br/><br/>";
187 $gjPhone->drawWH($horData);
188 // 画出纵向数据
189 $verData = $gjPhone->magVerData($horData);
190 echo "<br/><br/><br/>===============纵向数据==============< br/><br/><br/>";
191 $gjPhone->drawWH($verData);
192  
193 // 输出电话
194 $phone = $gjPhone->showPhone($verData);
195 echo "<br/><br/><br/>===============电话==============<br /><br/><br/>" . $phone;
gjphone.php

 

 

4、扩展说明

  只要适当修改字模库,便可识别字母,特殊字符等,按照纵向数据,修改字模库即可。

  

 

5 查阅文章的地址

  学习过程难免需要大量阅读别人的文章和分析,本人初次接触,收获良多,感谢分享的人!

  原文地址1:http://www.jb51.net/article/95854.htm

  原文地址2:http://www.jb51.net/article/78645.htm

推荐阅读