PHP识别简单的图片上面的数字(可扩展)
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识别简单的图片上面的数字(可扩展)的更多相关文章
- C#识别图片上的数字
通过Emgu实现对图片上的数字进行识别. 前期步骤: 1.下载Emgu安装文件,我的版本是2.4.2.1777.3.0版本则实现对中文的支持. 2.安装后需填写环境变量,环境变量Path值后加入Emg ...
- python 识别图片上的数字
https://blog.csdn.net/qq_31446377/article/details/81708006 ython 3.6 版本 Pytesseract 图像验证码识别 环境: (1) ...
- 分享C#识别图片上的数字
通过Emgu实现对图片上的数字进行识别.前期步骤:1.下载Emgu安装文件,我的版本是2.4.2.1777.3.0版本则实现对中文的支持.2.安装后需填写环境变量,环境变量Path值后加入Emgu安装 ...
- UEditor之实现配置简单的图片上传示例
UEditor之实现配置简单的图片上传示例 原创 2016年06月11日 18:27:31 开心一笑 下班后,阿华到楼下小超市买毛巾,刚买完出来,就遇到同一办公楼里另一家公司的阿菲,之前与她远远的有过 ...
- python 图片上添加数字源代码
最近因工作需要,需要在图片上添加数字,查询了资料,自己写了一个方法,并进行了测试,由于代码用到了PIL库,需要下载安装,下载地址:http://www.pythonware.com/products/ ...
- 一、简单的图片上传并预览功能input[file]
一.简单的图片上传并预览功能input[file] <!DOCTYPE html> <html lang="en"> <head> <me ...
- 微信小程序简单封装图片上传组件
微信小程序简单封装图片上传组件 希望自己 "day day up" -----小陶 我从哪里来 在写小程序的时候需要上传图片,个人觉得官方提供的 Uploader 组件不是太好用, ...
- 一个textview实现文字在图片上面的效果
类似于这样的,其实很简单,可是以前用的是imageview+textview.布局实现多写了好多代码.又不能在图片加文字,显得没技术含量. xml代码如下: <TextView android: ...
- koa2实现简单的图片上传
1.安装koa-body 2.引入koa-body const koa = require('koa'); const fs = require('fs'); const koaBody = requ ...
随机推荐
- pycharm remote debug
换工作了好久没写blog了,堕落了,哈哈,发现了好的东西分享一下,和以前使用的pycharm的远程debug相比,更为方便,原理同步本地和远程的代码,加载远程的环境运行,使用本地的代码+远程的环境,方 ...
- SQL SERVER中生僻字问题存储与查询问题
以下仅记录碰到的几个问题 1.首先字段设置为varchar的时候存储后无法进行正常的显示 显示为? 此状态下匹配查询或者Like模糊查询都没问题 2.将字段设置为nvarchar,在进行插入或者跟新时 ...
- Javaweb入门 数据库第一天
数据库概述 本菜鸟使用的数据库软件为Mariadb,以下内容都是以Mariadb数据库软件来写的学习总结. 数据库 所谓的数据库就是用于存储.管理数据的仓库,数据库根据底层存储数据结构的不同可以分为很 ...
- 【Machine Learning·机器学习】决策树之ID3算法(Iterative Dichotomiser 3)
目录 1.什么是决策树 2.如何构造一棵决策树? 2.1.基本方法 2.2.评价标准是什么/如何量化评价一个特征的好坏? 2.3.信息熵.信息增益的计算 2.4.决策树构建方法 3.算法总结 @ 1. ...
- OOM和JVM配置优化
OOM这个缩写就是Java程序开发过程中让人最头痛的问题:Out of Memory.在很多开发人员的开发过程中,或多或少的都会遇到这类问题,这类问题定位比较困难,往往需要根据经验来判断可能出现问题的 ...
- 调试过程中发现按f5无法走进jdk源码
debug 模式 ,在fis=new FileInputStream(file); 行打断点 调试过程中发现按f5无法走进jdk源码 package com.lzl.spring.test; impo ...
- Java equal() 和 == 详细分析
1 == 返回值是true/false; (1) 基本数据类型比较的就是值(2)引用型数据类型就是地址值 public class Test1 { public static void main(S ...
- S2:.net
1.net框架结构 主要包含公共语言运行时(CLR)和框架类库(.NET Framework 类库 ,FCL) 2.CLR 1.对于一个将要面向.NET平台进行开发的人来说,了解一下.NET平台的整 ...
- 夯实Java基础(十二)——异常处理
1.异常处理概述 在Java程序执行过程中, 总是会发生不被期望的事件, 阻止程序按照程序员预期正常运行, 这就是Java程序出现的异常. 异常处理是基于面向对象的一种运行错误处理机制,通过对异常问题 ...
- Codeforces Round #527 (Div. 3) 总结 A B C D1 D2 F
传送门 A 贪心的取 每个字母n/k次 令r=n%k 让前r个字母各取一次 #include <bits/stdc++.h> using namespace std; typedef lo ...