1、场景

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

2、原理分析

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

  

        ||

        \/

  

        ||

        \/

  

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

    

3、源码

  3.1 经过我修改后的代码

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

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

 //【获取图片数字】
//$imgPath:图片路径
private function getPhoneByImg($imgPath){ $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/>";
//$this->show($phone); return $phone; }
 <?php
namespace common\models; /**
* 电话号码识别.
* @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)
{
$i_length = count($newdata[1]);
$j_length = count($newdata)+1;
for ($i = 0; $i < $i_length; ++ $i) {
for ($j = 1; $j < $j_length; ++ $j) {
$ndata[$i][$j] = $newdata[$j][$i];
}
} $ndatas= [];
$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 (isset($ndatas[$b]) && in_array(1, $ndatas[$b])) {
$ndatas[$c] = $value;
$c ++;
}
}
} return $this->verData = $ndatas;
} /**
* 显示电话号码...
*
* @return unknown
*/
public function showPhone ($ndatas)
{
$phone = '';
$d = 0;
$ndArr = [];
$ndArr[0] = '';
foreach ($ndatas as $key => $val) { if (in_array(1, $val)) { foreach ($val as $k => $v) {
$ndArr[$d] .= $v;
}
}else{
$d ++;
$ndArr[$d] = '';
} }
array_pop($ndArr);
//return $ndArr; foreach ($ndArr as $key01 => $val01) {
$phone .= $this->initData($val01);
}
return $phone;
} /**
* 分离显示...
*
* @param unknown_type $dataArr
*/
function drawWH ($dataArr)
{
$c = '';
if (is_array($dataArr)) {
foreach ($dataArr as $key => $val) {
foreach ($val as $k => $v) {
if ($v == 0) {
$c .= "<font color='grend'>" . $v . "</font>";
} else {
$c .= $v;
}
}
$c .= "<br/>";
}
}
echo $c;
} /**
* 初始数据...
*
* @param unknown_type $numStr
* @return unknown
*/
public function initData ($numStr)
{
//return 1;
$result = '';
$data = array(
0 => '00011110000011111100011000011011000000111100000011011000011000111111000001111000',
1 => '001000000101100000011111111111111111111100000000010000000001',
2 => '00100000010110000011110000011110000011011000011001110011000101111000010011000001',
//3 => '001000000010011000000011110000000001110000000001110000110001110000110001011001110011011111011111000110001100',
3=> '01000000101100000011100000000110001000011000100001110111001101110111100010001100',
//4 => '000000001100000000111100000001111100000011101100000111001100001100001100011000001100111111111111111111111111000000001100000000000100',
4 => '00000110000000111000000110100000110010000110001000111111111111111111110000001000',
5 => '11111001001111100110100010001110010000011001000001100110001110001111100000011100',
6 => '00111111000111111110110001001110001000011000100001110011001101100111100000001100',
//7 => '110000000000110000000111110000111111110001110000110111000000111100000000111000000000111000000000',
7 => '10000000111000000111100000110010000110001000110000100110000011110000001110000000',
//8 => '000100011110011111111111110011100001110001100001110001100001110001100001110011100001011111111111000100011110',
8 => '00100011000111011110110111001110001000011000100001110111001101110111100010001100',
9 => '00110000000111100110110011001110000100011000010001110010001101111111100011111100', '-' => '00000100000000010000000001000000000100000000010000000001000000000100000000010000'
); foreach ($data as $key => $val) {
similar_text($numStr, $val, $pre);
if ($pre > 95) { // 相似度95%以上 $result .= $key;
break;
}
}
return $result;
}
}

GjPhone.php

    

  3.2 引用的源码

    

 /**
* 电话号码识别.
* @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;

gjphone.php

4、扩展说明

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

  

5 查阅文章的地址

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

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

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

PHP识别简单的图片上面的数字(可扩展)的更多相关文章

  1. C#识别图片上的数字

    通过Emgu实现对图片上的数字进行识别. 前期步骤: 1.下载Emgu安装文件,我的版本是2.4.2.1777.3.0版本则实现对中文的支持. 2.安装后需填写环境变量,环境变量Path值后加入Emg ...

  2. python 识别图片上的数字

    https://blog.csdn.net/qq_31446377/article/details/81708006 ython 3.6 版本 Pytesseract 图像验证码识别 环境: (1) ...

  3. 分享C#识别图片上的数字

    通过Emgu实现对图片上的数字进行识别.前期步骤:1.下载Emgu安装文件,我的版本是2.4.2.1777.3.0版本则实现对中文的支持.2.安装后需填写环境变量,环境变量Path值后加入Emgu安装 ...

  4. UEditor之实现配置简单的图片上传示例

    UEditor之实现配置简单的图片上传示例 原创 2016年06月11日 18:27:31 开心一笑 下班后,阿华到楼下小超市买毛巾,刚买完出来,就遇到同一办公楼里另一家公司的阿菲,之前与她远远的有过 ...

  5. python 图片上添加数字源代码

    最近因工作需要,需要在图片上添加数字,查询了资料,自己写了一个方法,并进行了测试,由于代码用到了PIL库,需要下载安装,下载地址:http://www.pythonware.com/products/ ...

  6. 一、简单的图片上传并预览功能input[file]

    一.简单的图片上传并预览功能input[file] <!DOCTYPE html> <html lang="en"> <head> <me ...

  7. 微信小程序简单封装图片上传组件

    微信小程序简单封装图片上传组件 希望自己 "day day up" -----小陶 我从哪里来 在写小程序的时候需要上传图片,个人觉得官方提供的 Uploader 组件不是太好用, ...

  8. 一个textview实现文字在图片上面的效果

    类似于这样的,其实很简单,可是以前用的是imageview+textview.布局实现多写了好多代码.又不能在图片加文字,显得没技术含量. xml代码如下: <TextView android: ...

  9. koa2实现简单的图片上传

    1.安装koa-body 2.引入koa-body const koa = require('koa'); const fs = require('fs'); const koaBody = requ ...

随机推荐

  1. 访问腾讯云主机mysql的设置问题

    ---恢复内容开始--- 1.需要打开腾讯云主机的防火墙端口3306,具体实现可以在腾讯云控制台安全组中设置开放全部端口(安全组对应入站.出战规则): 2.将云主机mysql中mysql数据库user ...

  2. 让Controller支持对平铺参数执行@Valid数据校验

    每篇一句 在金字塔塔尖的是实践,学而不思则罔,思而不学则殆(现在很多编程框架都只是教你碎片化的实践) 相关阅读 [小家Java]深入了解数据校验:Java Bean Validation 2.0(JS ...

  3. 【译】在 Linux 上不安装 Mono 构建 .NET Framework 类库

    在这篇文章中,我展示了如何在Linux上构建针对.NET Framework版本的.NET项目,而不使用Mono.通用使用微软新发布的 Mocrosoft.NETFramework.Reference ...

  4. python 实现两个文本文件内容去重

    实现两个文本内容去重,输出两个文本不重复的结果 两个测试文本内容如下 1.txt中内容为 1 2 3 4 5 6 7 8 2.txt中内容为 1 2 3 4 5 6 7 8 9 10 11 12 13 ...

  5. OLE--SWT高级控件

    OLE和ActiveX控件的支持    OLE(Object Link Embeded)是指在程序之间链接和嵌入对象数据.通过OLE技术可以在一个应用程序中执行其他的应用程序.    而ActiveX ...

  6. go 学习之路(二)

    一.文件名 关键字 标识符 所有go源码都以.go结尾 标识符以字母或下划线开头,大小写敏感 a.boy b.Boy c.a+b d.0boy e._boy f.=_boy g._ 以上变量c.d.f ...

  7. bucket list 函数解析

    cls_bucket_list 函数 librados::IoCtx index_ctx; // key   - oid (for different shards if there is any) ...

  8. 基于Spring注解的上下文初始化过程源码解析(二)

    上一篇看完了register方法的代码,继续跟后面代码 后面执行refresh方法,代码清单如下: public void refresh() throws BeansException, Illeg ...

  9. nginx负载均衡策略url_hash配置方法

    参考文章: https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/ 根据路径,进行一致性hash,具体的配 ...

  10. Python3 反射

    反射 python面向对象中的反射:通过字符串的形式操作对象相关的属性 hasattr(obj,name) # hasattr(obj, name) # 判断一个对象是否有指定的属性name,返回Tr ...