Rumah  >  Artikel  >  php教程  >  PHP之验证码识别,php验证码

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

WBOY
WBOYasal
2016-06-13 09:27:38753semak imbas

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

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

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

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

一、思路

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


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

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

先从图片的颜色着手,即图片的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> }

 

 

二、二值化

因为人眼可以分别出验证码,所以验证码的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、或者,对黑点白点的坐标进行操作&hellip;&hellip;

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

定义函数

<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> <br> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <br><br>
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 ......余下全文>>
 
Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn