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

具体的步骤如下:

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

先爆出源码:

 <?php
error_reporting(0);
$fn="./1.jpg";//要识别的答题卡文件名,生产环境中替换为"$fn='./cards/'.$_GET['testno']."/".$_GET['cardno'];"
$m255=200;//图片二值化的阈值
$minx=-1;//定位点坐标,L6同。
$miny=-1;
function gett($res,$i,$j){//求某座标的灰度值
$m255=200;
$rgb = imagecolorat($res,$j,$i); $rgbarray = imagecolorsforindex($res, $rgb);
$r= $rgbarray['red'] * 0.333;
$g= $rgbarray['green'] * 0.333;
$b= $rgbarray['blue'] * 0.333;
$t= round(($r+$g+$b) /$m255);
return $t;
} header('Content-type:image/png');
$res = imagecreatefromjpeg($fn);
$size = getimagesize($fn);
$black = imagecolorallocate($res, 0, 0, 0);
$white = imagecolorallocate($res, 255, 255, 255);
$red=imagecolorallocate($res, 255, 0, 0);
$fl=imagecolorallocate($res, 0, 255, 0);
for($j=0; $j <$size[0]; ++$j)
for($i=0; $i <$size[1]; ++$i)
{
//这一部分代码的Line26-Line35和Line36-Line49借鉴的网上的一位大大的文章,稍作修改,具体是哪位大大的,不太记得了,这一行献给那位大大
{
$rgb = imagecolorat($res,$j,$i);
$rgbarray = imagecolorsforindex($res, $rgb);
$r= $rgbarray['red']*0.333;
$g= $rgbarray['green']*0.333;
$b= $rgbarray['blue']*0.333;
$t= round(($r+$g+$b) /$m255);
if ($t==0)
{
imagesetpixel($res,$j,$i,$black);//原本是$data[$i][$j]=true;因为内存超限,so换成了这个,L47的一样.
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:防止误识别.
//找到左上角的定位点
$minx=$j;
$miny=$i; }
}else{ imagesetpixel($res,$j,$i,$white);
}
}
} //$b=dgcz($res,$miny,$minx,$fl);//这个函数本是用于标记定位点的,后来取消了
imageellipse($res,$minx,$miny,40,40,$red);//标记定位点
//imageline($res,$minx,0,$minx,$size[1],$red);
//imageline($res,$size[0]-$minx,0,$size[0]-$minx,$size[1]-1,$red);
//画切割线 //imageellipse($res,$b-minx,$miny,40,40,$red); $Out = imagecreatetruecolor ($size[0]-2*$minx,$size[1]-2*$miny);//切割后图像存放位置
imagecopy ( $Out,$res , 0,0 ,$minx ,$miny ,$size[0]-2*$minx,$size[1]-2*$miny );//切割
imagepng($Out);
imagedestroy($res);
imagedestroy($Out);
//$fh=fopen("./log.log","a");
//fwrite($fh,"x:".$minx.";y:".$miny."\n");
?>

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

测试图片:

执行结果:

浅谈PHP答题卡识别(一)的更多相关文章

  1. 机器学习进阶-案例实战-答题卡识别判 1.cv2.getPerspectiveTransform(获得投射变化后的H矩阵) 2.cv2.warpPerspective(H获得变化后的图像) 3.cv2.approxPolyDP(近似轮廓) 4.cv2.threshold(二值变化) 7.cv2.countNonezeros(非零像素点个数)6.cv2.bitwise_and(与判断)

    1.H = cv2.getPerspectiveTransform(rect, transform_axes) 获得投射变化后的H矩阵 参数说明:rect表示原始的位置左上,右上,右下,左下, tra ...

  2. LeadTools答题卡识别方案

    /// <summary> /// 批改操作 /// </summary> public AnswerCard DoCorrect(Stream AnserCardFile) ...

  3. 【4opencv】识别复杂的答题卡1(主要算法)

    一.问题提出 由于GPY进行了纠偏,所以在采集的时候,就已经获得了质量较高的答题卡图片 下一步就是需要从这张图片中,识别出人眼识别出来的那些信息,并且将这个过程尽可能地鲁棒化,提高识别的准确率. 二. ...

  4. 浅谈人脸识别中的loss 损失函数

    浅谈人脸识别中的loss 损失函数 2019-04-17 17:57:33 liguiyuan112 阅读数 641更多 分类专栏: AI 人脸识别   版权声明:本文为博主原创文章,遵循CC 4.0 ...

  5. 识别简单的答题卡(Bubble sheet multiple choice scanner and test grader using OMR, Python and OpenCV——jsxyhelu重新整编)

    该博客转自www.pyimagesearch.com,进行了相关修改补充. Over the past few months I've gotten quite the number of reque ...

  6. opencv 识别答题卡

    参考这个网站,然后自己 找了张图片试了一下 http://blog.csdn.net/cp562090732/article/details/47804003 // test.cpp : 定义控制台应 ...

  7. Android性能优化的浅谈

    一.概要: 本文主要以Android的渲染机制.UI优化.多线程的处理.缓存处理.电量优化以及代码规范等几方面来简述Android的性能优化 二.渲染机制的优化: 大多数用户感知到的卡顿等性能问题的最 ...

  8. 【微信小程序项目实践总结】30分钟从陌生到熟悉 web app 、native app、hybrid app比较 30分钟ES6从陌生到熟悉 【原创】浅谈内存泄露 HTML5 五子棋 - JS/Canvas 游戏 meta 详解,html5 meta 标签日常设置 C#中回滚TransactionScope的使用方法和原理

    [微信小程序项目实践总结]30分钟从陌生到熟悉 前言 我们之前对小程序做了基本学习: 1. 微信小程序开发07-列表页面怎么做 2. 微信小程序开发06-一个业务页面的完成 3. 微信小程序开发05- ...

  9. 浅谈单页应用和多页应用——Vue.js向

    浅谈单页应用和多页应用--Vue.js向 多页面 多页面应用:每次页面跳转,后台都会返回一个新的HTML文档,就是多页面应用. 在以往传统开发的应用(网站)大多都是多页面应用,路由由后端来写. 页面跳 ...

随机推荐

  1. 怎样用PS对照片进行美白?

    摘录自:http://product.pconline.com.cn/itbk/software/ps/1408/5336118.html 步骤1.打开需要美白肤色的照片.本教程为防止侵犯他人肖像权, ...

  2. CCF系列之模板生成系统( 201509-3 )

    试题名称: 模板生成系统 试题编号: 201509-3 时间限制: 1.0s 内存限制: 256.0MB 问题描述 成成最近在搭建一个网站,其中一些页面的部分内容来自数据库中不同的数据记录,但是页面的 ...

  3. redux学习日志:关于异步action

    当我们在执行某个动作的时候,会直接dispatch(action),此时state会立即更新,但是如果这个动作是个异步的呢,我们要等结果出来了才能知道要更新什么样的state(比如ajax请求),那就 ...

  4. docker 安装NexusRepository Manager

    今天学习了一下docker 感觉这东西要学习好多的命令,但是自己又是喜欢这种命令,感觉linux总是高一个等级的东西,这几天学习使用docker安装各种东西,下面记录一些我安装nexus的步骤,还是不 ...

  5. 关于今天esp8266运行失控问题和oled与串口共存尝试成功的总结

    今天2017-12-1720:24:22下午esp8266再次无法刷入固件,导致我一度崩溃,本来已经认为esp8266已经相当稳定了,没想到今天又运行出错,总结如下 今天2017-12-17esp无法 ...

  6. Effective Java 第三版——30. 优先使用泛型方法

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  7. JavaScript中事件绑定的三种方式

    JavaScript使得网页与用户友好交互,在使用 js 进行时间绑定的时候有三种绑定方式. 第一种:初学者以及普通写法 <div id="dom0"> <inp ...

  8. springmvc图片上传(兼容ie8以上,实时预览)

    html代码: <form id="uploadform" method="post" enctype="multipart/form-data ...

  9. javaweb后台转码

    为什么需要转码? 客户端向服务器发送请求的四种情况:1.URL方式直接访问;2.页面链接(属于get请求);3.表单get提交;4.表单post提交 1.url(url和页面链接):各大浏览器.各个操 ...

  10. common-logging源码解析

    OK,现在我们来研究下common-logging的源码.这篇博客有参照上善若水的博客,感谢他的无私分享. 先来随便扯点吧,貌似所有这些流行的Logging框架都和Log4J多少有点关系(不太确定Co ...