PHP识别简单的图片上面的数字(可扩展)
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
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;
4、扩展说明
只要适当修改字模库,便可识别字母,特殊字符等,按照纵向数据,修改字模库即可。
5 查阅文章的地址
学习过程难免需要大量阅读别人的文章和分析,本人初次接触,收获良多,感谢分享的人!
原文地址1:http://www.jb51.net/article/95854.htm
原文地址2:http://www.jb51.net/article/78645.htm
生命不息,学习不止