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. 【杂谈】如何对Redis进行原子操作

    什么时候需要进行需要原子操作? 很常见的例子,就是利用Redis实现分布式锁. 实现锁需要哪些条件? 我们知道要实现锁,就需要一个改变锁状态的方法.这个方法能原子地对锁的状态进行检查并修改.如果修改成 ...

  2. java中代码的注释和快捷

    添加必要的注释,对一个有责任心.有道德模范的前端必须具备的好习惯, 可以大大提高代码的可维护性.可读性. java代码注释快捷键:ctrl+shift+/首先熟悉一下html.css.js的注释的写法 ...

  3. ubuntu防火墙规则之ufw

    前言 因公司项目的需求,需要对客户端机器简便使用防火墙的功能,所以可在页面进行简便设置防护墙规则,当然,这个功能需求放到我手上我才有机会学到.因为客户端机器都是ubuntu的,所以当然用了ubuntu ...

  4. python基础学习(起步)

    目录 python基础学习(起步) 变量 常量 变量的内存管理 python垃圾回收机制 变量的其他赋值方式 今日编程小题 本人能力有限,若有偏颇之处请读者大大不吝赐教! 祝大家每天都在成长! pyt ...

  5. 2019.7 佳木斯培训A层

    day1题目及题解 day2题目及题解 day3题目及题解 day4题目及题解 day5题目及题解

  6. Python版:Selenium2.0之WebDriver学习总结_实例1

    Python版:Selenium2.0之WebDriver学习总结_实例1  快来加入群[python爬虫交流群](群号570070796),发现精彩内容. 实属转载:本人看的原文地址 :http:/ ...

  7. Chrome 跨域 disable-web-security 关闭安全策略

    谷歌浏览器暂时关闭跨域. 当遇到以下情况,则可以简单的使用 关闭Chrome 安全策略跨域 开发时跨域,上线后,部署在一个域名下没有跨域问题 开发时,临时解决跨域问题 只有开发时用这个,其他时候,就不 ...

  8. Keil uVision4 ——如何新建一个项目

    一.打开Keil4软件,点击Project,再点击New μVision Projrct. 二.新建一个文件夹,并在里面输入这个项目的名字. 三.点击Intel,根据实际情况选择,这里选择的是80/8 ...

  9. 定时延时设计FPGA

    以50MHZ时钟为例,进行1秒钟延时,并输出延时使能信号. 首先计算需要多少次计时,MHZ=10的六次方HZ.T=20ns 一秒钟需要计时次数为5的七次方即5000_0000. 然后计算需要几位的寄存 ...

  10. 网站安装SSL证书成为影响SEO排名的重要因素之一

    百度谷歌先后发声明倡导站长们使用https链接,同样的网站,https站点要比http站点拥有更好的排名权重.https已经是网站SEO必须要考虑的环节之一了,而https的必要条件就是安装SSL证书 ...