最近期末考试考完了,我们也要放寒假了。于是突发奇想,想用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. Cocoa的MVC架构分析

    Cocoa是Mac OS和iPhone OS上的开发框架,使用Objective-C做为开发语言.当然,在代码中也可以嵌入C和C++的语句.初识Objective-C时会觉得它的语法很奇怪,但本质上和 ...

  2. MySQL改写子查询成Join

    有时用别的方式而不是子查询可以获得更高的性能 : For example: SELECT * FROM t1 WHERE id IN (SELECT id FROM t2); 改写: SELECT D ...

  3. Mybatis问题:There is no getter for property named 'unitId' in 'class java.lang.String'

    Mybatis遇到的问题 问题: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.re ...

  4. eclipes快捷键

    本文原创作者:pipi-changing 本文原创出处:http://www.cnblogs.com/pipi-changing/ Ctrl+1 快速修复(最经典的快捷键,就不用多说了) Ctrl+D ...

  5. JAVA中使用log4j及slf4j进行日志输出的方法详解

    JAVA中输出日志比较常用的是log4j,这里讲下log4j的配置和使用方法,以及slf4j的使用方法.  一.下载log4j的架包,并导入项目中,如下: 二.创建log4j.properties配置 ...

  6. Android5.0新控件

    谷歌在推出Android5.0的同时推出了一些新控件,Android5.0中最常用的新控件有下面5种.  1. CardView(卡片视图) CardView顾名思义是卡片视图,它继承FrameLay ...

  7. 【转】 SED多行模式空间

    1. sed执行模板=sed '模式{命令1;命令2}' 即逐行读入模式空间,执行命令,最后输出打印出来 2. 为方便下面,先说下p和P,p打印当前模式空间内容,追加到默认输出之后,P打印当前模式空间 ...

  8. 用记事本编写java中的HelloWorld

    一.安装并配置jdk(图片来自百度经验) 安装JDK 选择安装目录 安装过程中会出现两次 安装提示 .第一次是安装 jdk ,第二次是安装 jre .建议两个都安装在同一个java文件夹中的不同文件夹 ...

  9. Windows下Nginx实现负载均衡

    Apache,Nginx Apache和Nginx都属于属于 静态页面服务器,都有插件支持动态编程语言处理,但Nginx的IO模比Apache更适合跑代理.所以一般都作为前端缓冲代理(Nginx的反向 ...

  10. XAML: 自定义控件中事件处理的最佳实践

    在开发 XAML(WPF/UWP) 应用程序中,有时候,我们需要创建自定义控件 (Custom Control) 来满足实际需求.而在自定义控件中,我们一般会用到一些原生的控件(如 Button.Te ...