项目中需要用到opencv,先了解后做仿照别人做了两个 关于java Opencv 答题卡扫描 银行卡号码截取 的 小程序。

Opencv的安装下载,就不多介绍,主要是贴代码,希望大家能多多指教。

答题卡代码如下

import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;import java.util.*;import static org.opencv.core.CvType.CV_8U;
import static org.opencv.imgproc.Imgproc.MORPH_RECT;/*** @author  lsw* @email lsw_demail@163.com*/
public class OpenCv {static {System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}public static void main(String []args) {String sheet = "D://A4.jpg";//A4 二值化膨胀后生成的图片路径String results = "E://result.jpg";String msg = rowsAndCols(sheet, results);System.out.println(msg);}public static void Canny(String oriImg, String dstImg, int threshold) {//装载图片Mat img = Imgcodecs.imread(oriImg);Mat srcImage2 = new Mat();Mat srcImage3 = new Mat();Mat srcImage4 = new Mat();Mat srcImage5 = new Mat();//图片变成灰度图片Imgproc.cvtColor(img, srcImage2, Imgproc.COLOR_RGB2GRAY);//图片二值化Imgproc.adaptiveThreshold(srcImage2, srcImage3, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY_INV, 255, 1);//确定腐蚀和膨胀核的大小Mat element = Imgproc.getStructuringElement(MORPH_RECT, new Size(1, 6));//腐蚀操作Imgproc.erode(srcImage3, srcImage4, element);//膨胀操作Imgproc.dilate(srcImage4, srcImage5, element);//Imgcodecs.imwrite("E:/picpool/card/enresults.jpg", srcImage4);//确定每张答题卡的ROI区域Mat imag_ch1 = srcImage4.submat(new Rect(200, 1065, 1930, 2210));//识别所有轮廓Vector<MatOfPoint> chapter1 = new Vector<>();Imgproc.findContours(imag_ch1, chapter1, new Mat(), 2, 3);Mat result = new Mat(imag_ch1.size(), CV_8U, new Scalar(255));Imgproc.drawContours(result, chapter1, -1, new Scalar(0), 2);Imgcodecs.imwrite("E://result.jpg", result);//new一个 矩形集合 用来装 轮廓List<RectComp> RectCompList = new ArrayList<>();for (int i = 0; i < chapter1.size(); i++) {Rect rm = Imgproc.boundingRect(chapter1.get(i));RectComp ti = new RectComp(rm);//把轮廓宽度区间在 50 - 80 范围内的轮廓装进矩形集合if (ti.rm.width > 60 && ti.rm.width < 85) {RectCompList.add(ti);}}//new一个 map 用来存储答题卡上填的答案 (A\B\C\D)TreeMap<Integer, String> listenAnswer = new TreeMap<>();//按 X轴 对listenAnswer进行排序RectCompList.sort((o1, o2) -> {if (o1.rm.x > o2.rm.x) {return 1;}if (o1.rm.x == o2.rm.x) {return 0;}if (o1.rm.x < o2.rm.x) {return -1;}return -1;});/*如果精度高,可以通过像素计算for (RectComp rc : RectCompList) {int x = RectCompList.get(t).getRm().x - 16;int y = RectCompList.get(t).getRm().y - 94;//计算x轴上的分割 如果超过5题,那么还会有一个大分割int xSplit = x/85 /5;//因为第一题 x=21 计算机中题目从0开始算,现实是从1开始 所以+1int xTitleNum = x/85 + 1;//由于精度问题  x轴会慢慢递减  递减到上一个答案去 如果不跨过两个答案以上,都没问题  如果答题卡x轴40题左右 会出问题if(x%85>20){System.out.println("x轴递减程度" + x%85);xTitleNum++;}xTitleNum = xTitleNum - xSplit;System.out.println(xTitleNum);}*///根据 Y轴 确定被选择答案 (A\B\C\D)for (RectComp rc : RectCompList) {for (int h = 0; h < 7; h++) {if ((rc.rm.contains(new Point(rc.rm.x + 20, 115 + (320 * h))))) {for (int w = 0; w < 4; w++) {if (rc.rm.contains(new Point(55 + (500 * w), rc.rm.y))) {listenAnswer.put(1 + (20 * h) + (5 * w), "A");} else if (rc.rm.contains(new Point(135 + (500 * w), rc.rm.y))) {listenAnswer.put(2 + (20 * h) + (5 * w), "A");} else if (rc.rm.contains(new Point(215 + (500 * w), rc.rm.y))) {listenAnswer.put(3 + (20 * h) + (5 * w), "A");} else if (rc.rm.contains(new Point(300 + (500 * w), rc.rm.y))) {listenAnswer.put(4 + (20 * h) + (5 * w), "A");} else if (rc.rm.contains(new Point(380 + (500 * w), rc.rm.y))) {listenAnswer.put(5 + (20 * h) + (5 * w), "A");}}} else if ((rc.rm.contains(new Point(rc.rm.x + 20, 165 + (320 * h))))) {for (int w = 0; w < 4; w++) {if (rc.rm.contains(new Point(55 + (500 * w), rc.rm.y))) {listenAnswer.put(1 + (20 * h) + (5 * w), "B");} else if (rc.rm.contains(new Point(135 + (500 * w), rc.rm.y))) {listenAnswer.put(2 + (20 * h) + (5 * w), "B");} else if (rc.rm.contains(new Point(215 + (500 * w), rc.rm.y))) {listenAnswer.put(3 + (20 * h) + (5 * w), "B");} else if (rc.rm.contains(new Point(300 + (500 * w), rc.rm.y))) {listenAnswer.put(4 + (20 * h) + (5 * w), "B");} else if (rc.rm.contains(new Point(380 + (500 * w), rc.rm.y))) {listenAnswer.put(5 + (20 * h) + (5 * w), "B");}}} else if ((rc.rm.contains(new Point(rc.rm.x + 20, 220 + (320 * h))))) {for (int w = 0; w < 4; w++) {if (rc.rm.contains(new Point(55 + (500 * w), rc.rm.y))) {listenAnswer.put(1 + (20 * h) + (5 * w), "C");} else if (rc.rm.contains(new Point(135 + (500 * w), rc.rm.y))) {listenAnswer.put(2 + (20 * h) + (5 * w), "C");} else if (rc.rm.contains(new Point(215 + (500 * w), rc.rm.y))) {listenAnswer.put(3 + (20 * h) + (5 * w), "C");} else if (rc.rm.contains(new Point(300 + (500 * w), rc.rm.y))) {listenAnswer.put(4 + (20 * h) + (5 * w), "C");} else if (rc.rm.contains(new Point(380 + (500 * w), rc.rm.y))) {listenAnswer.put(5 + (20 * h) + (5 * w), "C");}}} else if ((rc.rm.contains(new Point(rc.rm.x + 20, 275 + (320 * h))))) {for (int w = 0; w < 4; w++) {if (rc.rm.contains(new Point(55 + (500 * w), rc.rm.y))) {listenAnswer.put(1 + (20 * h) + (5 * w), "D");} else if (rc.rm.contains(new Point(135 + (500 * w), rc.rm.y))) {listenAnswer.put(2 + (20 * h) + (5 * w), "D");} else if (rc.rm.contains(new Point(215 + (500 * w), rc.rm.y))) {listenAnswer.put(3 + (20 * h) + (5 * w), "D");} else if (rc.rm.contains(new Point(300 + (500 * w), rc.rm.y))) {listenAnswer.put(4 + (20 * h) + (5 * w), "D");} else if (rc.rm.contains(new Point(380 + (500 * w), rc.rm.y))) {listenAnswer.put(5 + (20 * h) + (5 * w), "D");}}}}}Iterator iter = listenAnswer.entrySet().iterator();while (iter.hasNext()) {Map.Entry entry = (Map.Entry) iter.next();Object key = entry.getKey();Object val = entry.getValue();System.out.println("第" + key + "题,分数:" + val);}}public static String rowsAndCols(String oriImg, String dstImg) {String msg = "";Canny(oriImg, dstImg, 50);Mat mat = Imgcodecs.imread(dstImg);msg += "\n行数:" + mat.rows();msg += "\n列数:" + mat.cols();msg += "\nheight:" + mat.height();msg += "\nwidth:" + mat.width();msg += "\nelemSide:" + mat.elemSize();//CvType contourSeq = null;return msg;}
}

核心代码如上图: 还有另外一个类,也很简单  我就不贴出来了,大家可以去我的github上面找得到  通过核心代码就能理解出大概的思路。

github地址 : https://github.com/shiwenlin/opencv

银行卡也很简单最后是也在github上   项目中截取到银行卡的图片,我们也可以用别的插件转成数字,

JavaOpencv实现答题卡扫描 银行卡号码截取相关推荐

  1. 答题卡扫描助手使用说明

    答题卡扫描助手小程序使用说明 使用视频展示 手机扫描答题卡,长见识了 微信扫一扫可以体验 简介 微信小程序答题卡扫描助手软件是一款可以应用在实际教学工作中的工具软件.其优点是可以根据实际教学,需要创建 ...

  2. 比较牛逼的答题卡扫描算法

    http://www.cnblogs.com/jsxyhelu/p/4231728.html 转载于:https://www.cnblogs.com/cyh2009/p/5567112.html

  3. 用计算机获取机读卡是通过什么实现的,一种基于图像识别技术的答题卡及考试系统的制作方法...

    本发明涉及智能考试系统. 背景技术: 传统答题卡具有如下缺陷: 1.答题卡定位需要右侧和底端的黑点来实现定位整张答题卡的行和列: 2.需要专用答题卡识别机(专有硬件)来识别答案: 3.需要用特种铅笔( ...

  4. 终于不用手撸了,解放你的双手,教你用数学建模的方式对答题卡进行有效识别

    前言 声明:后期原力计划活动期间的数学建模类文章都会转入MATLAB深入理解高级教程(附源码)专栏.对于理工科类及马上要毕业设计的小伙伴应该会有很大帮助,有需要的小伙伴赶紧订阅吧.包括AI系列博文,博 ...

  5. opencv +python采集识别填涂卡(答题卡)数据

    在社科研究中的问卷调查,或者需要进行问卷答题的场景中,需要用纸质问卷采集答案,然后将问卷的答案输入电脑.这是一般的问卷采集答案的方法,如果问卷数量并不是很多能很快速的将问卷的结果输入到电脑中,但是如果 ...

  6. 用Python+OpenCV+PyQt开发的答题卡识别软件

    用Python+OpenCV+PyQt开发的答题卡识别软件 软件使用说明 软件设计思路 如何设置答案 界面风格 备注 这是一个可以识别定制答题卡的软件,它可以根据用户自定的答案来进行识别,校对正误并统 ...

  7. 鼎诚网上阅卷系统.html,鑫众博网上阅卷系统各类答题卡轻松识别

    网上阅卷系统工作流程 一.命题及答题卡设计 命题老师采用题.卡分离方式分别制作试题和答题卡,采用系统自带的标准Word答题卡模版,答题卡设计简单.方便. 本系统兼容任意第三方答题卡 二.答题卡印刷 支 ...

  8. 手机扫描答题卡阅卷的小程序

    作为一个老师,在教学中学生测试后的卷子是一件十分头疼的事,答题卡对着答案去改很容易出错.还有就是要统计哪些题目是易错题,逐个去统计很是麻烦. 手机扫描答题卡软件使用操作示范 下面我把这个小程序分享给大 ...

  9. 深入学习OpenCV文档扫描OCR识别及答题卡识别判卷(文档扫描,图像矫正,透视变换,OCR识别)

    人工智能学习离不开实践的验证,推荐大家可以多在FlyAI-AI竞赛服务平台多参加训练和竞赛,以此来提升自己的能力.FlyAI是为AI开发者提供数据竞赛并支持GPU离线训练的一站式服务平台.每周免费提供 ...

  10. 用计算机过去机读卡,阅卷机读卡机答题卡使用流程

    0603SJX阅卷机读卡机答题卡使用流程 云微阅卷机光标阅读机简介 光标阅读机,是用光学扫描的方法来识别按***格式印刷或书写的标记,并将其转换为计算机能接受的电信号的设备.作为一种新的计算机外设,它 ...

最新文章

  1. jsp页面中静态文件的时间戳
  2. Java中的goto实现
  3. 电脑壁纸知乎_电脑壁纸(个人向
  4. 关于fi dd ler 手机抓包 网卡地址地址_实测对比Wireshark利用nRF52832抓包和Packet Sniffer抓包体验...
  5. Windows Phone中Wallet钱包的使用
  6. 程序员面试金典 - 面试题 17.14. 最小K个数(快排划分O(n))
  7. Hibernate查询_HQL_EJBQL_QBC_QBE
  8. Windows 10某个网络端口被占用怎么办?
  9. 2021-06-26JS基本语法 入门
  10. 什么是UI设计?UI学习一般分几个阶段呢?
  11. 未来公园怎么能少了广场舞?
  12. 点云 3D 目标跟踪 - AB3DMOT(IROS 2020, ECCVW 2020)
  13. 解决WIN10打开XBOX闪退问题(2022)
  14. 感悟生活,由一款很火的APP拼多多,想到的
  15. Dell PowerEdge™ R510 Servers 安装 Ubuntu Server 10.04 LTS 笔记
  16. JAVA 面对对象程序设计 习题7.3
  17. ArcGIS Pro 简介(二)
  18. 学军OJ题解——诸葛的理想
  19. 网路设备的端口镜像技术
  20. 东方通应用中间件TongWeb初级考试攻略【实战攻略,1小时通过考试】

热门文章

  1. struts2+quartz定时任务
  2. 【数学】一元函数积分学(宇哥笔记)
  3. Ps怎么做火焰字 PS火焰字制作图文教程
  4. HTML期末作业-我的家乡网页作业
  5. 数据预处理1:无量纲化especially for Scaler
  6. Redis 跳跃表实现原理 时间复杂度分析
  7. c语言折半查找平均查找长度,求折半查找成功时的平均查找长度
  8. 关于Mac上无法进入/var/lib/docker/volumes/的解决方法
  9. 微信小程序android和IOS拨打电话区别
  10. 虚拟实习项目技术架构mal总结