0

0

PHP之验证码识别,php验证码_PHP教程

php中文网

php中文网

发布时间:2016-07-13 10:21:27

|

2000人浏览过

|

来源于php中文网

原创

PHP之验证码识别,php验证码

首先推荐几篇有关验证码识别的文章,觉得不错

php实现验证码的识别(初级篇)

关于bp神经网格识别验证码

立即学习PHP免费学习笔记(深入)”;

一、思路

碰见一个验证码,如果我们想要识别它,我们需要的是做什么呢?
我们先观察几个验证码............


我们用人眼去观察,会很显然的认出验证码所包含的字符,那么人眼的“识别机理”是什么呢?
大概是验证码图片字符的背景的颜色区别吧,试想,如果字符和背景没有颜色区别,我们能够判断验证码吗,很显然不能。

所以,我们就可以从人出发。

先从图片的颜色着手,即图片的RGB信息。

RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。

定义函数取得RGB信息

<span> 1</span> <span>//</span><span>代码本来是一个类,现在拆开来写的,有可能有不严谨的地方,大家可以看得懂就好了</span>
<span> 2</span> 
<span> 3</span> <span>/*</span>
<span> 4</span> <span> *取得图片路径和图片尺寸
</span><span> 5</span>  <span>*/</span>
<span> 6</span> <span>$this</span>->ImagePath = <span>$Image</span><span>;
</span><span> 7</span> <span>$this</span>->ImageSize = <span>getimagesize</span>(<span>$Image</span><span>);
</span><span> 8</span> 
<span> 9</span> <span>/*</span>
<span>10</span> <span> *获取图像标识符,保存到ImageInfo,只能处理bmp,png,jpg图片
</span><span>11</span> <span> *ImageCreateFromBmp是我自己定义的函数,最后会给出
</span><span>12</span>  <span>*/</span>
<span>13</span> <span>function</span><span> getInfo(){
</span><span>14</span>     <span>$filetype</span> = <span>substr</span>(<span>$this</span>->ImagePath,-3<span>);
</span><span>15</span>     <span>if</span>(<span>$filetype</span> == 'bmp'<span>){
</span><span>16</span>         <span>$this</span>->ImageInfo = <span>$this</span>->ImageCreateFromBmp(<span>$this</span>-><span>ImagePath);
</span><span>17</span>     }<span>elseif</span>(<span>$filetype</span> == 'jpg'<span>){
</span><span>18</span>         <span>$this</span>->ImageInfo = imagecreatefromjpeg(<span>$this</span>-><span>ImagePath);    
</span><span>19</span>     }<span>elseif</span>(<span>$filetype</span> == 'png'<span>){
</span><span>20</span>         <span>$this</span>->ImageInfo = imagecreatefrompng(<span>$this</span>-><span>ImagePath);    
</span><span>21</span> <span>    }
</span><span>22</span> <span>}
</span><span>23</span> 
<span>24</span> <span>/*</span><span>获取图片RGB信息</span><span>*/</span>
<span>25</span> <span>function</span><span> getRgb(){
</span><span>26</span>     <span>$rgbArray</span> = <span>array</span><span>();
</span><span>27</span>     <span>$res</span> = <span>$this</span>-><span>ImageInfo;
</span><span>28</span>     <span>$size</span> = <span>$this</span>-><span>ImageSize;
</span><span>29</span>     <span>$wid</span> = <span>$size</span>['0'<span>];
</span><span>30</span>     <span>$hid</span> = <span>$size</span>['1'<span>];
</span><span>31</span>     <span>for</span>(<span>$i</span>=0; <span>$i</span> < <span>$hid</span>; ++<span>$i</span><span>){
</span><span>32</span>         <span>for</span>(<span>$j</span>=0; <span>$j</span> < <span>$wid</span>; ++<span>$j</span><span>){
</span><span>33</span>             <span>$rgb</span> = imagecolorat(<span>$res</span>,<span>$j</span>,<span>$i</span><span>);
</span><span>34</span>             <span>$rgbArray</span>[<span>$i</span>][<span>$j</span>] = imagecolorsforindex(<span>$res</span>, <span>$rgb</span><span>);
</span><span>35</span> <span>        }
</span><span>36</span> <span>    }
</span><span>37</span>     <span>return</span> <span>$rgbArray</span><span>;
</span><span>38</span> }

 

齐博B2B电子商务系统
齐博B2B电子商务系统

齐博B2B系统是一款基于PHP程序和Mysql数据库为基础的开源B2B行业门户电子商务网站建站系统, 系统代码完整、开源,功能全面,架构优秀,提供良好的用户体验、及管理平台,是目前搭建B2B行业门户网站最好的程序之一。齐博B2B具有的功能特点包括:通行证整合功能通过通行证的整合,可以与流行的PHPWIND论坛或Discuz论坛以及Ucenter中心等进行通讯,从而为用户提供更多的交流场所,增加网站

下载

 

二、二值化

因为人眼可以分别出验证码,所以验证码的RGB信息就会有一定的特点,这时候需要我们观察一下,直接打印RGB数组是不好观察的…………,好多数啊

在php实现验证码的识别(初级篇)中,作者的判断依据是

无论验证数字颜色如何变化,该数字的 RGB 值总有一个值小于 125

我们先获取他的灰度,再判断

<span> 1</span> <span>/*</span>
<span> 2</span> <span> *获取灰度信息
</span><span> 3</span>  <span>*/</span>
<span> 4</span> <span>function</span><span> getGray(){
</span><span> 5</span>     <span>$grayArray</span> = <span>array</span><span>();
</span><span> 6</span>     <span>$size</span> = <span>$this</span>-><span>ImageSize;
</span><span> 7</span>     <span>$rgbarray</span> = <span>$this</span>-><span>getRgb();
</span><span> 8</span>     <span>$wid</span> = <span>$size</span>['0'<span>];
</span><span> 9</span>     <span>$hid</span> = <span>$size</span>['1'<span>];
</span><span>10</span>     <span>for</span>(<span>$i</span>=0; <span>$i</span> < <span>$hid</span>; ++<span>$i</span><span>){
</span><span>11</span>         <span>for</span>(<span>$j</span>=0; <span>$j</span> < <span>$wid</span>; ++<span>$j</span><span>){
</span><span>12</span>             <span>$grayArray</span>[<span>$i</span>][<span>$j</span>] = (299*<span>$rgbarray</span>[<span>$i</span>][<span>$j</span>]['red']+587*<span>$rgbarray</span>[<span>$i</span>][<span>$j</span>]['green']+144*<span>$rgbarray</span>[<span>$i</span>][<span>$j</span>]['blue'])/1000<span>;
</span><span>13</span> <span>        }
</span><span>14</span> <span>    }
</span><span>15</span>     <span>return</span> <span>$grayArray</span><span>;
</span><span>16</span> }

 

 

然后我们根据灰度信息,打印图片,注意不是打印灰度信息

<span> 1</span> <span>/*</span><span>根据灰度信息打印图片</span><span>*/</span>
<span> 2</span> <span>function</span><span> printByGray(){
</span><span> 3</span>     <span>$size</span> = <span>$this</span>-><span>ImageSize;    
</span><span> 4</span>     <span>$grayArray</span> = <span>$this</span>-><span>getGray();
</span><span> 5</span>     <span>$wid</span> = <span>$size</span>['0'<span>];
</span><span> 6</span>     <span>$hid</span> = <span>$size</span>['1'<span>];
</span><span> 7</span>     <span>for</span>(<span>$k</span>=0;<span>$k</span><25;<span>$k</span>++<span>){
</span><span> 8</span>         <span>echo</span> <span>$k</span>."\n"<span>;
</span><span> 9</span>         <span>for</span>(<span>$i</span>=0; <span>$i</span> < <span>$hid</span>; ++<span>$i</span><span>){
</span><span>10</span>             <span>for</span>(<span>$j</span>=0; <span>$j</span> < <span>$wid</span>; ++<span>$j</span><span>){
</span><span>11</span>                 <span>if</span>(<span>$grayArray</span>[<span>$i</span>][<span>$j</span>] < <span>$k</span>*10<span>){
</span><span>12</span>                     <span>echo</span> '■'<span>;
</span><span>13</span>                 }<span>else</span><span>{
</span><span>14</span>                     <span>echo</span> '□'<span>;
</span><span>15</span> <span>                }
</span><span>16</span> <span>            }
</span><span>17</span>             <span>echo</span> "|\n"<span>;
</span><span>18</span> <span>        }
</span><span>19</span>         <span>echo</span> "---------------------------------------------------------------------------------------------------------------\n"<span>;
</span><span>20</span> <span>    }
</span><span>21</span>     
<span>22</span> }

 

注意到,从$grayArray[$i][$j]

<span> 1</span> <span>/*</span>
<span> 2</span> <span> *根据自定义的规则,获取二值化二维数组
</span><span> 3</span> <span> *@return  图片高*宽的二值数组(0,1)
</span><span> 4</span>  <span>*/</span>
<span> 5</span> <span>function</span><span> getErzhi(){
</span><span> 6</span>     <span>$erzhiArray</span> = <span>array</span><span>();
</span><span> 7</span>     <span>$size</span> = <span>$this</span>-><span>ImageSize;
</span><span> 8</span>     <span>$grayArray</span> = <span>$this</span>-><span>getGray();
</span><span> 9</span>     <span>$wid</span> = <span>$size</span>['0'<span>];
</span><span>10</span>     <span>$hid</span> = <span>$size</span>['1'<span>];
</span><span>11</span>     <span>for</span>(<span>$i</span>=0; <span>$i</span> < <span>$hid</span>; ++<span>$i</span><span>){
</span><span>12</span>         <span>for</span>(<span>$j</span>=0; <span>$j</span> <<span>$wid</span>; ++<span>$j</span><span>){
</span><span>13</span>             <span>if</span>( <span>$grayArray</span>[<span>$i</span>][<span>$j</span>]    < 90<span> ){
</span><span>14</span>                 <span>$erzhiArray</span>[<span>$i</span>][<span>$j</span>]=1<span>;
</span><span>15</span>             }<span>else</span><span>{
</span><span>16</span>                 <span>$erzhiArray</span>[<span>$i</span>][<span>$j</span>]=0<span>;
</span><span>17</span> <span>            }
</span><span>18</span> <span>        }
</span><span>19</span> <span>    }
</span><span>20</span>     <span>return</span> <span>$erzhiArray</span><span>;
</span><span>21</span> }

 

 

三、去除噪点

但是我们发现有一些小点影响了我们的判断

我们可以注意到这些事干扰噪点,但是如果我们是机器的话,我们如何判断这些点是否是字符呢?

 

所以接下来,我们需要将这些字符去除。

我们判断,如果一个黑点的上下左右的八个点全部是白,我们就认为它是噪点,并予以清除,赋为白

<span> 1</span> <span>/*</span>
<span> 2</span> <span> *二值化图片降噪
</span><span> 3</span> <span> *@param $erzhiArray二值化数组
</span><span> 4</span>  <span>*/</span>
<span> 5</span> <span>function</span> reduceZao(<span>$erzhiArray</span><span>){
</span><span> 6</span>     <span>$data</span> = <span>$erzhiArray</span><span>;
</span><span> 7</span>     <span>$gao</span> = <span>count</span>(<span>$erzhiArray</span><span>);
</span><span> 8</span>     <span>$chang</span> = <span>count</span>(<span>$erzhiArray</span>['0'<span>]);
</span><span> 9</span> 
<span>10</span>     <span>$jiangzaoErzhiArray</span> = <span>array</span><span>();
</span><span>11</span> 
<span>12</span>     <span>for</span>(<span>$i</span>=0;<span>$i</span><<span>$gao</span>;<span>$i</span>++<span>){
</span><span>13</span>         <span>for</span>(<span>$j</span>=0;<span>$j</span><<span>$chang</span>;<span>$j</span>++<span>){
</span><span>14</span>             <span>$num</span> = 0<span>;  
</span><span>15</span>             <span>if</span>(<span>$data</span>[<span>$i</span>][<span>$j</span>] == 1<span>)  
</span><span>16</span> <span>            {
</span><span>17</span>                 <span>//</span><span> 上  </span>
<span>18</span>                 <span>if</span>(<span>isset</span>(<span>$data</span>[<span>$i</span>-1][<span>$j</span><span>])){  
</span><span>19</span>                     <span>$num</span> = <span>$num</span> + <span>$data</span>[<span>$i</span>-1][<span>$j</span><span>];  
</span><span>20</span> <span>                }  
</span><span>21</span>                 <span>//</span><span> 下  </span>
<span>22</span>                 <span>if</span>(<span>isset</span>(<span>$data</span>[<span>$i</span>+1][<span>$j</span><span>])){  
</span><span>23</span>                     <span>$num</span> = <span>$num</span> + <span>$data</span>[<span>$i</span>+1][<span>$j</span><span>];  
</span><span>24</span> <span>                }  
</span><span>25</span>                 <span>//</span><span> 左  </span>
<span>26</span>                 <span>if</span>(<span>isset</span>(<span>$data</span>[<span>$i</span>][<span>$j</span>-1<span>])){  
</span><span>27</span>                     <span>$num</span> = <span>$num</span> + <span>$data</span>[<span>$i</span>][<span>$j</span>-1<span>];  
</span><span>28</span> <span>                }  
</span><span>29</span>                 <span>//</span><span> 右  </span>
<span>30</span>                 <span>if</span>(<span>isset</span>(<span>$data</span>[<span>$i</span>][<span>$j</span>+1<span>])){  
</span><span>31</span>                     <span>$num</span> = <span>$num</span> + <span>$data</span>[<span>$i</span>][<span>$j</span>+1<span>];  
</span><span>32</span> <span>                }  
</span><span>33</span>                 <span>//</span><span> 上左  </span>
<span>34</span>                 <span>if</span>(<span>isset</span>(<span>$data</span>[<span>$i</span>-1][<span>$j</span>-1<span>])){  
</span><span>35</span>                     <span>$num</span> = <span>$num</span> + <span>$data</span>[<span>$i</span>-1][<span>$j</span>-1<span>];  
</span><span>36</span> <span>                }  
</span><span>37</span>                 <span>//</span><span> 上右  </span>
<span>38</span>                 <span>if</span>(<span>isset</span>(<span>$data</span>[<span>$i</span>-1][<span>$j</span>+1<span>])){  
</span><span>39</span>                     <span>$num</span> = <span>$num</span> + <span>$data</span>[<span>$i</span>-1][<span>$j</span>+1<span>];  
</span><span>40</span> <span>                }  
</span><span>41</span>                 <span>//</span><span> 下左  </span>
<span>42</span>                 <span>if</span>(<span>isset</span>(<span>$data</span>[<span>$i</span>+1][<span>$j</span>-1<span>])){  
</span><span>43</span>                     <span>$num</span> = <span>$num</span> + <span>$data</span>[<span>$i</span>+1][<span>$j</span>-1<span>];  
</span><span>44</span> <span>                }  
</span><span>45</span>                 <span>//</span><span> 下右  </span>
<span>46</span>                 <span>if</span>(<span>isset</span>(<span>$data</span>[<span>$i</span>+1][<span>$j</span>+1<span>])){  
</span><span>47</span>                     <span>$num</span> = <span>$num</span> + <span>$data</span>[<span>$i</span>+1][<span>$j</span>+1<span>];  
</span><span>48</span> <span>                }  
</span><span>49</span> <span>            }
</span><span>50</span> 
<span>51</span>                 <span>if</span>(<span>$num</span> < 1<span>){  
</span><span>52</span>                     <span>$jiangzaoErzhiArray</span>[<span>$i</span>][<span>$j</span>] = 0<span>;  
</span><span>53</span>                 }<span>else</span><span>{
</span><span>54</span>                     <span>$jiangzaoErzhiArray</span>[<span>$i</span>][<span>$j</span>] = 1<span>;  
</span><span>55</span> <span>                }
</span><span>56</span> <span>        }
</span><span>57</span> <span>    }
</span><span>58</span>     <span>return</span> <span>$jiangzaoErzhiArray</span><span>;    
</span><span>59</span> 
<span>60</span> }

 

 

我们发现噪点消失了。

 

四、分割

这个时候,我们就需要对单一数字字母进行操作了,我们先将数字提取出来。

有些验证码字符相连,特别难!!!

我们分别从左到右,从右到左,从上到下,从下到上,进行扫描,去除白点,找到边框。

<span> 1</span> <span>/*</span>
<span> 2</span> <span> *归一化处理,针对一个个的数字,即去除字符周围的白点
</span><span> 3</span> <span> *@param $singleArray 二值化数组
</span><span> 4</span>  <span>*/</span>
<span> 5</span> <span>function</span> getJinsuo(<span>$singleArray</span><span>){
</span><span> 6</span>     <span>$dianCount</span> = 0<span>;
</span><span> 7</span>     <span>$rearr</span> = <span>array</span><span>();
</span><span> 8</span>     
<span> 9</span>     <span>$gao</span> = <span>count</span>(<span>$singleArray</span><span>);
</span><span>10</span>     <span>$kuan</span> = <span>count</span>(<span>$singleArray</span>['0'<span>]);
</span><span>11</span>     
<span>12</span>     <span>$dianCount</span> = 0<span>;
</span><span>13</span>     <span>$shangKuang</span> = 0<span>;
</span><span>14</span>     <span>$xiaKuang</span> = 0<span>;
</span><span>15</span>     <span>$zuoKuang</span> = 0<span>;
</span><span>16</span>     <span>$youKuang</span> = 0<span>;
</span><span>17</span>     <span>//</span><span>从上到下扫描</span>
<span>18</span>     <span>for</span>(<span>$i</span>=0; <span>$i</span> < <span>$gao</span>; ++<span>$i</span><span>){
</span><span>19</span>         <span>for</span>(<span>$j</span>=0; <span>$j</span> < <span>$kuan</span>; ++<span>$j</span><span>){
</span><span>20</span>             <span>if</span>( <span>$singleArray</span>[<span>$i</span>][<span>$j</span>] == 1<span>){
</span><span>21</span>                 <span>$dianCount</span>++<span>;
</span><span>22</span> <span>            }
</span><span>23</span> <span>        }
</span><span>24</span>         <span>if</span>(<span>$dianCount</span>>1<span>){
</span><span>25</span>             <span>$shangKuang</span> = <span>$i</span><span>;
</span><span>26</span>             <span>$dianCount</span> = 0<span>;
</span><span>27</span>             <span>break</span><span>;
</span><span>28</span> <span>        }
</span><span>29</span> <span>    }
</span><span>30</span>     <span>//</span><span>从下到上扫描</span>
<span>31</span>     <span>for</span>(<span>$i</span>=<span>$gao</span>-1; <span>$i</span> > -1; <span>$i</span>--<span>){
</span><span>32</span>         <span>for</span>(<span>$j</span>=0; <span>$j</span> < <span>$kuan</span>; ++<span>$j</span><span>){
</span><span>33</span>             <span>if</span>( <span>$singleArray</span>[<span>$i</span>][<span>$j</span>] == 1<span>){
</span><span>34</span>                 <span>$dianCount</span>++<span>;
</span><span>35</span> <span>            }
</span><span>36</span> <span>        }
</span><span>37</span>         <span>if</span>(<span>$dianCount</span>>1<span>){
</span><span>38</span>             <span>$xiaKuang</span> = <span>$i</span><span>;
</span><span>39</span>             <span>$dianCount</span> = 0<span>;
</span><span>40</span>             <span>break</span><span>;
</span><span>41</span> <span>        }
</span><span>42</span> <span>    }
</span><span>43</span>     <span>//</span><span>从左到右扫描</span>
<span>44</span>     <span>for</span>(<span>$i</span>=0; <span>$i</span> < <span>$kuan</span>; ++<span>$i</span><span>){
</span><span>45</span>         <span>for</span>(<span>$j</span>=0; <span>$j</span> < <span>$gao</span>; ++<span>$j</span><span>){
</span><span>46</span>             <span>if</span>( <span>$singleArray</span>[<span>$j</span>][<span>$i</span>] == 1<span>){
</span><span>47</span>                 <span>$dianCount</span>++<span>;
</span><span>48</span> <span>            }
</span><span>49</span> <span>        }
</span><span>50</span>         <span>if</span>(<span>$dianCount</span>>1<span>){
</span><span>51</span>             <span>$zuoKuang</span> = <span>$i</span><span>;
</span><span>52</span>             <span>$dianCount</span> = 0<span>;
</span><span>53</span>             <span>break</span><span>;
</span><span>54</span> <span>        }
</span><span>55</span> <span>    }
</span><span>56</span>     <span>//</span><span>从右到左扫描</span>
<span>57</span>     <span>for</span>(<span>$i</span>=<span>$kuan</span>-1; <span>$i</span> > -1; --<span>$i</span><span>){
</span><span>58</span>         <span>for</span>(<span>$j</span>=0; <span>$j</span> < <span>$gao</span>; ++<span>$j</span><span>){
</span><span>59</span>             <span>if</span>( <span>$singleArray</span>[<span>$j</span>][<span>$i</span>] == 1<span>){
</span><span>60</span>                 <span>$dianCount</span>++<span>;
</span><span>61</span> <span>            }
</span><span>62</span> <span>        }
</span><span>63</span>         <span>if</span>(<span>$dianCount</span>>1<span>){
</span><span>64</span>             <span>$youKuang</span> = <span>$i</span><span>;
</span><span>65</span>             <span>$dianCount</span> = 0<span>;
</span><span>66</span>             <span>break</span><span>;
</span><span>67</span> <span>        }
</span><span>68</span> <span>    }
</span><span>69</span>     <span>for</span>(<span>$i</span>=0;<span>$i</span><<span>$xiaKuang</span>-<span>$shangKuang</span>+1;<span>$i</span>++<span>){
</span><span>70</span>         <span>for</span>(<span>$j</span>=0;<span>$j</span><<span>$youKuang</span>-<span>$zuoKuang</span>+1;<span>$j</span>++<span>){
</span><span>71</span>             <span>$rearr</span>[<span>$i</span>][<span>$j</span>] = <span>$singleArray</span>[<span>$shangKuang</span>+<span>$i</span>][<span>$zuoKuang</span>+<span>$j</span><span>];
</span><span>72</span> <span>        }
</span><span>73</span> <span>    }
</span><span>74</span>     <span>return</span> <span>$rearr</span><span>;
</span><span>75</span> }

 

 

然后从左到右扫描,找到字符的分割

返回三维数组,每一维就是一个字符。

<span> 1</span> <span>/*</span>
<span> 2</span> <span> *切割成三维数组,每个小数字在一个数组里面
</span><span> 3</span> <span> *只适用四个数字一起的数组
</span><span> 4</span> <span> *@param 经过归一化处理的二值化数组
</span><span> 5</span>  <span>*/</span>
<span> 6</span> <span>function</span> cutSmall(<span>$erzhiArray</span><span>){
</span><span> 7</span>     <span>$doubleArray</span> = <span>array</span><span>();
</span><span> 8</span>     <span>$jieZouyou</span> = <span>array</span><span>();
</span><span> 9</span>     
<span>10</span>     <span>$gao</span> = <span>count</span>(<span>$erzhiArray</span><span>);
</span><span>11</span>     <span>$kuan</span> = <span>count</span>(<span>$erzhiArray</span>['0'<span>]);
</span><span>12</span>     
<span>13</span>     <span>$jie</span> = 0<span>;
</span><span>14</span>     <span>$s</span> = 0<span>;
</span><span>15</span>     <span>$jieZouyou</span>[<span>$s</span>] = 0<span>;
</span><span>16</span>     <span>$s</span>++<span>;
</span><span>17</span>     <span>//</span><span>从左到右扫描</span>
<span>18</span>     
<span>19</span>     <span>for</span>(<span>$i</span>=0; <span>$i</span> < <span>$kuan</span><span>;){
</span><span>20</span>         <span>for</span>(<span>$j</span>=0; <span>$j</span> < <span>$gao</span>; ++<span>$j</span><span>){
</span><span>21</span>             <span>$jie</span> = <span>$jie</span> + <span>$erzhiArray</span>[<span>$j</span>][<span>$i</span><span>];
</span><span>22</span> <span>        }
</span><span>23</span>         <span>//</span><span>如果有一列全部是白,设置$jieZouyou,并且跳过中间空白部分</span>
<span>24</span>         <span>if</span>(<span>$jie</span> == 0<span>){
</span><span>25</span>             <span>$jieZouyou</span>[<span>$s</span>] = <span>$i</span>+1<span>;
</span><span>26</span>             <span>do</span><span>{
</span><span>27</span>                 <span>$n</span> = ++<span>$i</span><span>;
</span><span>28</span>                 <span>$qian</span> = 0<span>;
</span><span>29</span>                 <span>$hou</span> = 0<span>;
</span><span>30</span>                 <span>for</span>(<span>$m</span>=0; <span>$m</span> < <span>$gao</span>; ++<span>$m</span><span>){
</span><span>31</span>                     <span>$qian</span> = <span>$qian</span> + <span>$erzhiArray</span>[<span>$m</span>][<span>$n</span><span>];
</span><span>32</span>                     <span>$hou</span> = <span>$hou</span> + <span>$erzhiArray</span>[<span>$m</span>][<span>$n</span>+1<span>];                        
</span><span>33</span> <span>                }
</span><span>34</span>                 <span>$jieZouyou</span>[<span>$s</span>+1] = <span>$n</span>+1<span>;
</span><span>35</span> <span>            }
</span><span>36</span>             <span>//</span><span>当有两列同时全部为白,说明有间隙,循环,知道间隙没有了</span>
<span>37</span>             <span>while</span>(<span>$qian</span> == 0 && <span>$hou</span> == 0<span>);
</span><span>38</span>             <span>$s</span>+=2<span>;
</span><span>39</span>             <span>$i</span>++<span>;
</span><span>40</span>         }<span>else</span><span>{
</span><span>41</span>             <span>$i</span>++<span>;    
</span><span>42</span> <span>        }
</span><span>43</span>         
<span>44</span>         <span>$jie</span> = 0<span>;
</span><span>45</span> <span>    }
</span><span>46</span>     <span>$jieZouyou</span>[] = <span>$kuan</span><span>;
</span><span>47</span>     <span>//</span><span>极端节点数量,(应该是字符个数)*2</span>
<span>48</span>     <span>$jieZouyouCount</span> = <span>count</span>(<span>$jieZouyou</span><span>);
</span><span>49</span>     
<span>50</span>     <span>for</span>(<span>$k</span>=0;<span>$k</span><<span>$jieZouyouCount</span>/2;<span>$k</span>++<span>){
</span><span>51</span>         <span>for</span>(<span>$i</span>=0; <span>$i</span> < <span>$gao</span>; <span>$i</span>++<span>){
</span><span>52</span>             <span>for</span>(<span>$j</span>=0; <span>$j</span> < <span>$jieZouyou</span>[<span>$k</span>*2+1]-<span>$jieZouyou</span>[<span>$k</span>*2]-1; ++<span>$j</span><span>){
</span><span>53</span>                 <span>$doubleArray</span>[<span>$k</span>][<span>$i</span>][<span>$j</span>] = <span>$erzhiArray</span>[<span>$i</span>][<span>$j</span>+<span>$jieZouyou</span>[<span>$k</span>*2<span>]];
</span><span>54</span> <span>            }
</span><span>55</span> <span>        }
</span><span>56</span>         
<span>57</span> <span>    }
</span><span>58</span>     <span>return</span> <span>$doubleArray</span><span>;
</span><span>59</span> }

 

五、倾斜调整

我们发现第三个9有一点倾斜,

我们需要将倾斜的图片“正”过来

人怎么处理的呢,先眼睛观察“倾斜了多少度”,然后把图片扭过来多少度,并且观察->负反馈->大脑传递扭转角度时刻在发生,最后图片就“正”过来了。

人是怎么观察“倾斜”的,以上面的“2”做例子,可能是右上方(左下方)的黑色比左上方(右下方)的多?

我们建立X轴正向向下,Y轴向右的直角坐标系

我们计算每一层的黑点的分布中点坐标,得到一系列离散点,计算这些点所在的直线(线性回归方程的计算,),公式y = b*x+a,

竟然有用到这个公式的一天!!!

大概就是一条倾斜的直线了,通过直线计算直线倾斜角度,然后转这么多的角度,图片应该就“正”了吧。

其中a,b的计算如下

<span> 1</span> <span>/*</span>
<span> 2</span> <span> *定义求线性回归A和B的函数
</span><span> 3</span> <span> *@param $zuobiaoArray坐标的三维数组
</span><span> 4</span>  <span>*/</span>
<span> 5</span> <span>function</span> getHuigui(<span>$zuobiaoArray</span><span>){
</span><span> 6</span>     <span>$y8</span> = 0<span>;
</span><span> 7</span>     <span>$x8</span> = 0<span>;
</span><span> 8</span>     <span>$x2</span> = 0<span>;
</span><span> 9</span>     <span>$xy</span> = 0<span>;
</span><span>10</span>     <span>$geshu</span> = <span>count</span>(<span>$zuobiaoArray</span><span>);
</span><span>11</span>     <span>for</span>(<span>$i</span>=0;<span>$i</span><<span>$geshu</span>;<span>$i</span>++<span>){
</span><span>12</span>         <span>$y8</span> = <span>$y8</span>+<span>$zuobiaoArray</span>[<span>$i</span>]['y'<span>];
</span><span>13</span>         <span>$x8</span> = <span>$x8</span>+<span>$zuobiaoArray</span>[<span>$i</span>]['x'<span>];
</span><span>14</span>         <span>$xy</span> = <span>$xy</span>+<span>$zuobiaoArray</span>[<span>$i</span>]['y']*<span>$zuobiaoArray</span>[<span>$i</span>]['x'<span>];
</span><span>15</span>         <span>$x2</span> = <span>$x2</span> + <span>$zuobiaoArray</span>[<span>$i</span>]['x']*<span>$zuobiaoArray</span>[<span>$i</span>]['x'<span>];;
</span><span>16</span> <span>    }
</span><span>17</span>     <span>$y8</span> = <span>$y8</span>/<span>$geshu</span><span>;
</span><span>18</span>     <span>$x8</span> = <span>$x8</span>/<span>$geshu</span><span>;
</span><span>19</span>     
<span>20</span>     <span>$b</span> = (<span>$xy</span>-<span>$geshu</span>*<span>$y8</span>*<span>$x8</span>)/(<span>$x2</span>-<span>$geshu</span>*<span>$x8</span>*<span>$x8</span><span>);
</span><span>21</span>     <span>$a</span> = <span>$y8</span>-<span>$b</span>*<span>$x8</span><span>;
</span><span>22</span>     <span>$re</span>['a'] = <span>$a</span><span>;
</span><span>23</span>     <span>$re</span>['b'] = <span>$b</span><span>;
</span><span>24</span>     <span>return</span> <span>$re</span><span>;
</span><span>25</span>     <span>//</span><span>y = b * x + a</span>
<span>26</span> }

 

怎么转角?

1、可以直接对图片进行操作,但是发现有比较大的失真,就没有继续了。
2、或者,对黑点白点的坐标进行操作……

这就是三角函数了,好长时间不碰三角函数,都差点忘记了。

定义函数

<span> 1</span> <span>/*</span>
<span> 2</span> <span> *定义转化坐标的函数
</span><span> 3</span> <span> *@param $x x坐标即$i
</span><span> 4</span> <span> *@param $y y坐标,即j
</span><span> 5</span> <span> *@param $b 线性回归方程的b参数 
</span><span> 6</span>  <span>*/</span> 
<span> 7</span> <span>function</span> getNewZuobiao(<span>$x</span>,<span>$y</span>,<span>$b</span><span>){
</span><span> 8</span>     <span>if</span>(<span>$x</span> == 0<span>){
</span><span> 9</span>         <span>if</span>(<span>$y</span>>0<span>){
</span><span>10</span>             <span>$xianJiao</span> = M_PI/2<span>;
</span><span>11</span>         }<span>elseif</span>(<span>$y</span><0<span>){
</span><span>12</span>             <span>$xianJiao</span> = -M_PI/2<span>;
</span><span>13</span>         }<span>else</span><span>{
</span><span>14</span>             <span>$p</span>['x'] = 0<span>;
</span><span>15</span>             <span>$p</span>['y'] = 0<span>;
</span><span>16</span>             <span>return</span> <span>$p</span><span>;
</span><span>17</span> <span>        }
</span><span>18</span>     }<span>else</span><span>{
</span><span>19</span>         <span>$xianJiao</span> = <span>atan</span>(<span>$y</span>/<span>$x</span><span>);    
</span><span>20</span> <span>    }
</span><span>21</span>     <span>$jiao</span> =<span>$xianJiao</span>-<span>atan</span>(<span>$b</span><span>);
</span><span>22</span>     <span>$chang</span> = <span>sqrt</span>(<span>$x</span>*<span>$x</span>+<span>$y</span>*<span>$y</span><span>);
</span><span>23</span>     <span>$p</span>['x'] = <span>$chang</span>*<span>cos</span>(<span>$jiao</span><span>);
</span><span>24</span>     <span>$p</span>['y'] = <span>$chang</span>*<span>sin</span>(<span>$jiao</span><span>);
</span><span>25</span>     <span>return</span> <span>$p</span><span>;
</span><span>26</span> }

 

转角吧

 

<span> 1</span> <span>/*</span>
<span> 2</span> <span> *对【单个】数字的二值化二维数组进行倾斜调整
</span><span> 3</span> <span> *@param  $singleArray  高*宽的二值数组(0,1)
</span><span> 4</span>  <span>*/</span>
<span> 5</span> <span>function</span> singleSlopeAdjust(<span>$singleErzhiArray</span><span>){
</span><span> 6</span>     <span>$slopeArray</span> = <span>array</span><span>();
</span><span> 7</span>     <span>$gao</span> = <span>count</span>(<span>$singleErzhiArray</span><span>);
</span><span> 8</span>     <span>$chang</span> = <span>count</span>(<span>$singleErzhiArray</span>['0'<span>]);
</span><span> 9</span>     
<span>10</span>     <span>//</span><span>初始化$slopeArray</span>
<span>11</span>     <span>for</span>(<span>$i</span>=0;<span>$i</span><<span>$gao</span>*4;<span>$i</span>++<span>){
</span><span>12</span>         <span>for</span>(<span>$j</span>=0;<span>$j</span><<span>$chang</span>*4;<span>$j</span>++<span>){
</span><span>13</span>             <span>$slopeArray</span>[<span>$i</span>][<span>$j</span>] = 0<span>;
</span><span>14</span> <span>        }
</span><span>15</span> <span>    }
</span><span>16</span>     
<span>17</span>     <span>//</span><span>初始化中心坐标(是数组的下标)</span>
<span>18</span>     <span>$centerXfoalt</span> = (<span>$gao</span>-1)/2<span>;
</span><span>19</span>     <span>$centerYfoalt</span> = (<span>$chang</span>-1)/2<span>;
</span><span>20</span>     <span>$centerX</span> = <span>ceil</span>(<span>$centerXfoalt</span><span>);
</span><span>21</span>     <span>$centerY</span> = <span>ceil</span>(<span>$centerYfoalt</span><span>);
</span><span>22</span>     
<span>23</span>     <span>//</span><span>初始化图片倾斜诶角度</span>
<span>24</span>     <span>/*</span><span>斜率的计算!!!!!,回归方程</span><span>*/</span>
<span>25</span>     <span>//</span><span>从上到下扫描,计算中点,求得一串坐标($i,$ava)</span>
<span>26</span>     <span>for</span>(<span>$i</span>=0;<span>$i</span><<span>$gao</span>;<span>$i</span>++<span>){
</span><span>27</span>         <span>$Num</span> = 0<span>;
</span><span>28</span>         <span>$Amount</span> = 0<span>;
</span><span>29</span>         <span>for</span>(<span>$j</span>=0;<span>$j</span><<span>$chang</span>;<span>$j</span>++<span>){
</span><span>30</span>             <span>if</span>(<span>$singleErzhiArray</span>[<span>$i</span>][<span>$j</span>] == 1<span>){
</span><span>31</span>                 <span>$Num</span> = <span>$Num</span>+<span>$j</span><span>;
</span><span>32</span>                 <span>$Amount</span>++<span>;
</span><span>33</span> <span>            }
</span><span>34</span> <span>        }
</span><span>35</span>         <span>if</span>(<span>$Amount</span> == 0<span>){
</span><span>36</span>             <span>$Ava</span>[<span>$i</span>] = <span>$chang</span>/2<span>;    
</span><span>37</span>         }<span>else</span><span>{
</span><span>38</span>             <span>$Ava</span>[<span>$i</span>] = <span>$Num</span>/<span>$Amount</span><span>;
</span><span>39</span> <span>        }
</span><span>40</span> <span>    }
</span><span>41</span> 
<span>42</span>     
<span>43</span>     <span>//</span><span>计算线性回归方程的b与a</span>
<span>44</span>     <span>$zuo</span> = <span>array</span><span>();
</span><span>45</span>     <span>for</span>(<span>$j</span>=0;<span>$j</span><<span>count</span>(<span>$Ava</span>);<span>$j</span>++<span>){
</span><span>46</span>         <span>$zuo</span>[<span>$j</span>]['x'] = <span>$j</span><span>;
</span><span>47</span>         <span>$zuo</span>[<span>$j</span>]['y'] = <span>$Ava</span>[<span>$j</span><span>];
</span><span>48</span> <span>    }
</span><span>49</span>     <span>$res</span> = <span>$this</span>->getHuigui(<span>$zuo</span><span>);
</span><span>50</span>     <span>$zuoB</span> = <span>$res</span>['b'<span>];
</span><span>51</span> 
<span>52</span>     
<span>53</span>     <span>for</span>(<span>$i</span>=0;<span>$i</span><<span>$gao</span>;<span>$i</span>++<span>){
</span><span>54</span>         <span>for</span>(<span>$j</span>=0;<span>$j</span><<span>$chang</span>;<span>$j</span>++<span>){
</span><span>55</span>             <span>if</span>(<span>$singleErzhiArray</span>[<span>$i</span>][<span>$j</span>] == 1<span>){
</span><span>56</span>                 <span>$splodeZuobiao</span> = <span>$this</span>->getNewZuobiao(<span>$i</span>,<span>$j</span>,<span>$zuoB</span><span>);
</span><span>57</span>                 <span>$splodeX</span> = <span>$splodeZuobiao</span>['x'<span>];
</span><span>58</span>                 <span>$splodeY</span> = <span>$splodeZuobiao</span>['y'<span>];
</span><span>59</span>                 <span>$slopeArray</span>[<span>$splodeX</span>+<span>$gao</span>][<span>$splodeY</span>+<span>$chang</span>] = 1<span>;
</span><span>60</span> <span>            }
</span><span>61</span> <span>        }
</span><span>62</span> <span>    }
</span><span>63</span>     
<span>64</span>     <span>//</span><span>将预处理的数组空白清理</span>
<span>65</span>     <span>$slopeArray</span> = <span>$this</span>->getJinsuo(<span>$slopeArray</span><span>);
</span><span>66</span>     <span>return</span> <span>$slopeArray</span><span>;
</span><span>67</span> }

看到正了一些

 

六、统一大小

上文中因为各种操作,每个字符大小不一,我们需要统一大小

 

七、特征值的建立

有很多方法

1、逐像素特征提取法
这是一种最简单的特征提取方法。它可以对图像进行逐行逐列的扫描,当遇到黑色像素时取其特征值为1,遇到白色像素时取其特征值为0,这样当扫描结束后就获得一个维数与图像中的像素点的个数相同的特征向量矩阵。
这种方法提取的信息量最大,但是它的缺点也很明显,就是适应性不强。

2、骨架特征提取法
两幅图像由于它们的线条的粗细不同,使得两幅图像差别很大,但是将它们的线条进行细化后,统一到相同的宽度,如一个像素宽时,这是两幅图像的差距就不那么明显。利用图形的骨架作为特征来进行数码识别,就使得识别有了一定的适应性。一般使用细化的方法来提取骨架,细化的算法有很多,如Hilditch算法、Rosenfeld算法等。对经过细化的图像利用EveryPixel函数进行处理就可以得到细化后图像的特征向量矩阵。骨架特征提取的方法对于线条粗细不同的数码有一定的适应性,但是图像一旦出现偏移就难以识别。

3、微结构法
微结构法将图像分为几个小块,统计每个小块的像素分布。本文提取出汉字的39个特征,存储在数组f[0]~f[38]中。具体算法可分为四步:

 步骤一:把字符平均分成9份,如图4.1所示,给每一份编号如图4.2,统计每一份内黑色像素的个数,存储在数字tz[0]~tz[9]中,统计在行方向和列方向上每一份内的黑色像素个数和与之相邻的一份内黑色像素个数的比值作为一个特征,例如:行方向上提取特征f[0]=tz[1]/ tz[0],f[1]=tz[2]/ tz[1],f[2]=tz[0]/ tz[2],…,f[8]=tz[6]/ tz[8];列方向上f[9]=tz[3]/ tz[0],f[10]=tz[6]/ tz[3],f[11]=tz[0]/ tz[6],…,f[17]=tz[2]/ tz[8],共18个特征。

步骤二:把字符横向分成三份,如图4.3所示,统计每一份内的黑色像素个数,每一份内的黑色像素个数与前一份内黑色像素个数的比值作为一个特征,f[18]=tz[10]/ tz[9],f[19]=tz[11]/ tz[10],f[20]=tz[9]/ tz[11];把字符纵向分成三份,如图4.4所示,统计每一份内的黑色像素个数,每一份内的黑色像素个数与前一份内黑色像素个数的比值作为一个特征,f[21]=tz[13]/ tz[12],f[22]=tz[14]/ tz[13],f[23]=tz[12]/ tz[14];共六个特征。

步骤三:如图4.5,在竖直方向上找出三列,统计在该列中跳变点的个数,即相邻点像素值从0变到255的次数,共三个特征,记为f[24],f[25],f[26];在水平方向上找出三行列,统计在该行中跳变点的个数,即相邻点象素值从0变到255的次数,共三个特征,记为f[27],f[28],f[29]。

图4.5

步骤四:把每一份内黑色象素的个数tz[0]~tz[9],作为9个特征,记为:f[30]~f[38]。

这样得到汉字的共39个特征,根据这些特征就可以区分每个车牌汉字,进行识别。

 

 

我们使用最简单的逐像素特征提取法。

多多增加数据库,识别率会增加的

 

八、识别验证码

对于一个新的验证码,进行上文操作,然后对比数据库就可以了

<span> 1</span> <span>/*</span>
<span> 2</span> <span> *进行匹配
</span><span> 3</span> <span> *@param  $Image  图片路径
</span><span> 4</span>  <span>*/</span>
<span> 5</span> <span>public</span> <span>function</span> run(<span>$Image</span><span>){
</span><span> 6</span>     <span>$data</span> = <span>array</span>('','','',''<span>);
</span><span> 7</span>     <span>$result</span>=""<span>;
</span><span> 8</span>     <span>$bilu</span> = ''<span>;
</span><span> 9</span>     <span>$maxarr</span> = ''<span>;
</span><span>10</span>     
<span>11</span>     <span>//</span><span>提取特征</span>
<span>12</span>     <span>$this</span>->prepare(<span>$Image</span><span>);
</span><span>13</span>     <span>$yuanshi</span> = <span>$this</span>-><span>getErzhi();
</span><span>14</span>     <span>$yijijiangzao</span> = <span>$this</span>->reduceZao(<span>$yuanshi</span><span>);
</span><span>15</span>     <span>$small</span> = <span>$this</span>->cutSmall(<span>$yijijiangzao</span><span>);
</span><span>16</span>     <span>for</span>(<span>$k</span>=0;<span>$k</span><4;<span>$k</span>++<span>){
</span><span>17</span>         <span>$tianchong</span> = <span>$this</span>->tianChong(<span>$small</span>[<span>$k</span><span>]);
</span><span>18</span>         <span>$tiaozhenjiaodu</span> = <span>$this</span>->singleSlopeAdjust(<span>$tianchong</span><span>);
</span><span>19</span>         <span>$tongyidaxiao</span> = <span>$this</span>->tongyiDaxiao(<span>$tiaozhenjiaodu</span><span>);
</span><span>20</span>         <span>for</span>(<span>$i</span>=0;<span>$i</span><20;<span>$i</span>++<span>){
</span><span>21</span>             <span>for</span>(<span>$j</span>=0;<span>$j</span><20;<span>$j</span>++<span>){
</span><span>22</span>                 <span>$data</span>[<span>$k</span>] .= <span>$tongyidaxiao</span>[<span>$i</span>][<span>$j</span><span>];    
</span><span>23</span> <span>            }    
</span><span>24</span> <span>        }
</span><span>25</span> <span>    }
</span><span>26</span> 
<span>27</span>     <span>//</span><span> 进行关键字匹配</span>
<span>28</span>     <span>foreach</span>(<span>$data</span> <span>as</span> <span>$numKey</span> => <span>$numString</span><span>)
</span><span>29</span> <span>    {
</span><span>30</span> 
<span>31</span>         <span>$max</span> = 0<span>;
</span><span>32</span>         <span>$num</span> = 0<span>;
</span><span>33</span>         <span>foreach</span>(<span>$this</span>->Keys <span>as</span> <span>$value</span> => <span>$key</span><span>)
</span><span>34</span> <span>        {
</span><span>35</span>             <span>similar_text</span>(<span>$value</span>, <span>$numString</span>,<span>$percent</span><span>);
</span><span>36</span>             <span>if</span>(<span>$percent</span> > <span>$max</span><span>)
</span><span>37</span> <span>            {
</span><span>38</span>                 <span>$max</span> = <span>$percent</span><span>;
</span><span>39</span>                 <span>$num</span> = <span>$key</span><span>;
</span><span>40</span>                 <span>$zim</span> = <span>$value</span><span>;
</span><span>41</span> <span>            }
</span><span>42</span>             <span>if</span>(<span>$max</span>>95<span>){
</span><span>43</span>                 <span>break</span><span>;
</span><span>44</span> <span>            }
</span><span>45</span> <span>        }
</span><span>46</span>         <span>$result</span> .=<span>$num</span><span>;
</span><span>47</span>         <span>$maxarr</span>[] = <span>$max</span><span>;
</span><span>48</span> <span>    }
</span><span>49</span>     <span>//</span><span> 查找最佳匹配数字</span>
<span>50</span>     <span>$re</span> = <span>$maxarr</span><span>;
</span><span>51</span>     <span>$re</span>[] = <span>$result</span><span>;
</span><span>52</span>     <span>return</span> <span>$re</span><span>;
</span><span>53</span>     <span>//</span><span>return $result.'|max|一:'.$maxarr['0'].'|二:'.$maxarr['1'].'|三:'.$maxarr['2'].'|四:'.$maxarr['3'];</span>
<span>54</span> }

 

试试:

 

PHP图形验证码识别

Header("Content-type: image/gif");
/*
* 初始化
*/
$border = 0; //是否要边框 1要:0不要
$how = 4; //验证码位数
$w = $how*15; //图片宽度
$h = 20; //图片高度
$fontsize = 5; //字体大小
$alpha = "abcdefghijkmnopqrstuvwxyz"; //验证码内容1:字母
$number = "023456789"; //验证码内容2:数字
$randcode = ""; //验证码字符串初始化
srand((double)microtime()*1000000); //初始化随机数种子

$im = ImageCreate($w, $h); //创建验证图片

/*
* 绘制基本框架
*/
$bgcolor = ImageColorAllocate($im, 255, 255, 255); //设置背景颜色
ImageFill($im, 0, 0, $bgcolor); //填充背景色
if($border)
{
$black = ImageColorAllocate($im, 0, 0, 0); //设置边框颜色
ImageRectangle($im, 0, 0, $w-1, $h-1, $black);//绘制边框
}

/*
* 逐位产生随机字符
*/
for($i=0; $i{
$alpha_or_number = mt_rand(0, 1); //字母还是数字
$str = $alpha_or_number ? $alpha : $number;
$which = mt_rand(0, strlen($str)-1); //取哪个字符
$code = substr($str, $which, 1); //取字符
$j = !$i ? 4 : $j+15; //绘字符位置
$color3 = ImageColorAllocate($im, mt_rand(0,100), mt_rand(0,100), mt_rand(0,100)); //字符随即颜色
ImageChar($im, $fontsize, $j, 3, $code, $color3); //绘字符
$randcode .= $code; //逐位加入验证码字符串
}

/*
* 添加干扰
*/
for($i=0; $i{
$color1 = ImageColorAllocate($im, mt_rand(0,255), mt_rand(0,255), mt_rand(0,255)); //干扰线颜色
ImageArc($im, mt_ra......余下全文>>
 

PHP 验证码识别 或者ASP程序也行怎写程序识别

原理不难,只需通过PHP来生成一张图片!在这张图片上通过PHP的图片处理函数在图片上写几个字符就Ok啦!在写字符时注意将写的字符记录下,这个记录是通过session来做!然后在验证时直接调用$_SESSION变量就可以了!

具体的代码如下:
有两个文件
yangzhengma.php用来显示图片和验证输入的验证码

session_start();
if(!empty($_GET['sub'])){
if($_SESSION['checks'] == $_GET['ma']){
echo "验证码正确
";
}else{
echo "验证码不正确!
";
}
}
?>


<br> 验证码实例<br>



PHP之验证码识别,php验证码_PHP教程



请输入验证码:





注意图片的地址写到PHP生成图片的文件地址

check.php用来生成图片

session_start();
header('content-type:image/jpeg');
$image_width=70;
$image_height=25;
$str="";
$arr=array(1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F','G','H','I','J','K','L','M','N','P','Q','R','S','T','U','V','W','X','Y','Z');
for ($i =0 ; $i ......余下全文>>
 

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/857272.htmlTechArticlePHP之验证码识别,php验证码 首先推荐几篇有关验证码识别的文章,觉得不错 php实现验证码的识别(初级篇) 关于bp神经网格识别验证码 一、思...

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

616

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

194

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

91

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

20

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

54

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

29

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

15

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

598

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

56

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号