浅谈PHP答题卡识别(一)

最近期末考试考完了,我们也要放寒假了。于是突发奇想,想用PHP写一个答题卡识别程序。已经实现了一些,现分享给大家。

 

具体的步骤如下:

上传答题卡=>图片二值化(已实现)=>寻找定位点(已实现)=>使用定位点切割掉不要的部分(已实现)=>切割小题=>客观题自动阅卷&主观题切割后交由阅卷老师批改=>统计分数=>生成csv文档

 

先爆出源码:

 1 <?php
 2 error_reporting(0);
 3 $fn="./1.jpg";//要识别的答题卡文件名,生产环境中替换为"$fn='./cards/'.$_GET['testno']."/".$_GET['cardno'];"
 4 $m255=200;//图片二值化的阈值
 5 $minx=-1;//定位点坐标,L6同。
 6 $miny=-1;
 7 function gett($res,$i,$j){//求某座标的灰度值
 8 $m255=200;
 9  $rgb = imagecolorat($res,$j,$i);
10 
11     $rgbarray = imagecolorsforindex($res, $rgb);
12       $r= $rgbarray['red'] * 0.333;
13       $g= $rgbarray['green'] * 0.333;
14       $b= $rgbarray['blue'] * 0.333;
15       $t= round(($r+$g+$b) /$m255);
16     return $t;
17 }
18 
19   header('Content-type:image/png');
20 $res = imagecreatefromjpeg($fn);
21 $size = getimagesize($fn);
22 $black = imagecolorallocate($res, 0, 0, 0); 
23 $white = imagecolorallocate($res, 255, 255, 255); 
24 $red=imagecolorallocate($res, 255, 0, 0); 
25 $fl=imagecolorallocate($res, 0, 255, 0); 
26    for($j=0; $j <$size[0]; ++$j)
27 for($i=0; $i <$size[1]; ++$i)
28   {
29       //这一部分代码的Line26-Line35和Line36-Line49借鉴的网上的一位大大的文章,稍作修改,具体是哪位大大的,不太记得了,这一行献给那位大大
30       {
31     $rgb = imagecolorat($res,$j,$i);
32     $rgbarray = imagecolorsforindex($res, $rgb);
33       $r= $rgbarray['red']*0.333;
34       $g= $rgbarray['green']*0.333;
35       $b= $rgbarray['blue']*0.333;
36       $t= round(($r+$g+$b) /$m255);
37      if ($t==0)
38     {
39         imagesetpixel($res,$j,$i,$black);//原本是$data[$i][$j]=true;因为内存超限,so换成了这个,L47的一样.
40         if($minx==-1 and $miny==-1 and $i>=10 and $j>=10 and gett($res,$i+5,$j)==0 and gett($res,$i,$j+5)==0){//gett($res,$i+5,$j)==0 and gett($res,$i,$j+5)==0:防止误识别.
41          //找到左上角的定位点
42          $minx=$j;
43          $miny=$i;
44          
45       }
46     }else{
47      
48        imagesetpixel($res,$j,$i,$white);
49     }
50    }
51   }
52 
53   //$b=dgcz($res,$miny,$minx,$fl);//这个函数本是用于标记定位点的,后来取消了
54 imageellipse($res,$minx,$miny,40,40,$red);//标记定位点
55 //imageline($res,$minx,0,$minx,$size[1],$red);
56 //imageline($res,$size[0]-$minx,0,$size[0]-$minx,$size[1]-1,$red);
57 //画切割线
58 
59 
60 //imageellipse($res,$b-minx,$miny,40,40,$red); 
61 
62 $Out = imagecreatetruecolor ($size[0]-2*$minx,$size[1]-2*$miny);//切割后图像存放位置
63 imagecopy ( $Out,$res , 0,0 ,$minx ,$miny ,$size[0]-2*$minx,$size[1]-2*$miny );//切割
64 imagepng($Out);
65 imagedestroy($res);
66 imagedestroy($Out); 
67 //$fh=fopen("./log.log","a");
68 //fwrite($fh,"x:".$minx.";y:".$miny."\n");
69 ?>

但效率有点低。需要二十多秒才能完成。

测试图片:

 

执行结果:

posted @ 2018-02-04 16:07  xieyi1393  阅读(1600)  评论(0编辑  收藏  举报