浅谈PHP答题卡识别(一)
最近期末考试考完了,我们也要放寒假了。于是突发奇想,想用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.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 ...
- LeadTools答题卡识别方案
/// <summary> /// 批改操作 /// </summary> public AnswerCard DoCorrect(Stream AnserCardFile) ...
- 【4opencv】识别复杂的答题卡1(主要算法)
一.问题提出 由于GPY进行了纠偏,所以在采集的时候,就已经获得了质量较高的答题卡图片 下一步就是需要从这张图片中,识别出人眼识别出来的那些信息,并且将这个过程尽可能地鲁棒化,提高识别的准确率. 二. ...
- 浅谈人脸识别中的loss 损失函数
浅谈人脸识别中的loss 损失函数 2019-04-17 17:57:33 liguiyuan112 阅读数 641更多 分类专栏: AI 人脸识别 版权声明:本文为博主原创文章,遵循CC 4.0 ...
- 识别简单的答题卡(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 ...
- opencv 识别答题卡
参考这个网站,然后自己 找了张图片试了一下 http://blog.csdn.net/cp562090732/article/details/47804003 // test.cpp : 定义控制台应 ...
- Android性能优化的浅谈
一.概要: 本文主要以Android的渲染机制.UI优化.多线程的处理.缓存处理.电量优化以及代码规范等几方面来简述Android的性能优化 二.渲染机制的优化: 大多数用户感知到的卡顿等性能问题的最 ...
- 【微信小程序项目实践总结】30分钟从陌生到熟悉 web app 、native app、hybrid app比较 30分钟ES6从陌生到熟悉 【原创】浅谈内存泄露 HTML5 五子棋 - JS/Canvas 游戏 meta 详解,html5 meta 标签日常设置 C#中回滚TransactionScope的使用方法和原理
[微信小程序项目实践总结]30分钟从陌生到熟悉 前言 我们之前对小程序做了基本学习: 1. 微信小程序开发07-列表页面怎么做 2. 微信小程序开发06-一个业务页面的完成 3. 微信小程序开发05- ...
- 浅谈单页应用和多页应用——Vue.js向
浅谈单页应用和多页应用--Vue.js向 多页面 多页面应用:每次页面跳转,后台都会返回一个新的HTML文档,就是多页面应用. 在以往传统开发的应用(网站)大多都是多页面应用,路由由后端来写. 页面跳 ...
随机推荐
- 怎样用PS对照片进行美白?
摘录自:http://product.pconline.com.cn/itbk/software/ps/1408/5336118.html 步骤1.打开需要美白肤色的照片.本教程为防止侵犯他人肖像权, ...
- CCF系列之模板生成系统( 201509-3 )
试题名称: 模板生成系统 试题编号: 201509-3 时间限制: 1.0s 内存限制: 256.0MB 问题描述 成成最近在搭建一个网站,其中一些页面的部分内容来自数据库中不同的数据记录,但是页面的 ...
- redux学习日志:关于异步action
当我们在执行某个动作的时候,会直接dispatch(action),此时state会立即更新,但是如果这个动作是个异步的呢,我们要等结果出来了才能知道要更新什么样的state(比如ajax请求),那就 ...
- docker 安装NexusRepository Manager
今天学习了一下docker 感觉这东西要学习好多的命令,但是自己又是喜欢这种命令,感觉linux总是高一个等级的东西,这几天学习使用docker安装各种东西,下面记录一些我安装nexus的步骤,还是不 ...
- 关于今天esp8266运行失控问题和oled与串口共存尝试成功的总结
今天2017-12-1720:24:22下午esp8266再次无法刷入固件,导致我一度崩溃,本来已经认为esp8266已经相当稳定了,没想到今天又运行出错,总结如下 今天2017-12-17esp无法 ...
- Effective Java 第三版——30. 优先使用泛型方法
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- JavaScript中事件绑定的三种方式
JavaScript使得网页与用户友好交互,在使用 js 进行时间绑定的时候有三种绑定方式. 第一种:初学者以及普通写法 <div id="dom0"> <inp ...
- springmvc图片上传(兼容ie8以上,实时预览)
html代码: <form id="uploadform" method="post" enctype="multipart/form-data ...
- javaweb后台转码
为什么需要转码? 客户端向服务器发送请求的四种情况:1.URL方式直接访问;2.页面链接(属于get请求);3.表单get提交;4.表单post提交 1.url(url和页面链接):各大浏览器.各个操 ...
- common-logging源码解析
OK,现在我们来研究下common-logging的源码.这篇博客有参照上善若水的博客,感谢他的无私分享. 先来随便扯点吧,貌似所有这些流行的Logging框架都和Log4J多少有点关系(不太确定Co ...