Opencv识别答题卡

来源:互联网 发布:orange软件官方下载 编辑:程序博客网 时间:2024/04/28 07:40

转自:http://blog.csdn.net/cp562090732/article/details/47804003#comments

OpenCV处理答题卡的软件,用于统计答题卡中选择题的得分。

1. 主要步骤

  •     读取图片
  •     图片转化为灰度图
  •     图片设定阈值
  •     开运算(先腐蚀,后膨胀)
  •     指定答题区域
  •     找到涂选框
  •     根据涂选框的坐标确定所涂选的选项及题号

2. 具体实现

#include <opencv2/core.hpp>#include <opencv2/imgcodecs.hpp>#include "opencv2/imgproc.hpp"#include <opencv2/highgui.hpp>#include <iostream>using namespace cv;using namespace std;#include <map>class RectComp{  public:Rect rm;  RectComp(Rect rms)  {  rm = rms;  }  bool operator < (const RectComp& ti) const  {  return rm.x< ti.rm.x;  }  };int main()  {  //装载图片  Mat srcImage1= imread("D:\\opencv_image\\images\\20150820103614491.png");   namedWindow("hello-1", 1);  imshow("hello-1", srcImage1 ); Mat srcImage2,srcImage3,srcImage4,srcImage5;  //图片变成灰度图片  cvtColor(srcImage1,srcImage2,CV_BGR2GRAY);  //图片二值化  threshold(srcImage2,srcImage3,200,255,THRESH_BINARY_INV);  //确定腐蚀和膨胀核的大小  Mat element = getStructuringElement(MORPH_RECT, Size(4, 4));  //腐蚀操作  erode(srcImage3,srcImage4,element);  //膨胀操作  dilate(srcImage4,srcImage5,element);  namedWindow("hello-5", 1);  imshow("hello-5", srcImage5 );  //确定每张答题卡的ROI区域  Mat imag_ch1 = srcImage5(Rect(0,30,100,60));  namedWindow("img1", 1);  imshow("img1",imag_ch1);  //提取已经涂好了的选项  std::vector<std::vector<cv::Point> > chapter1;  findContours(imag_ch1,chapter1,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE);  Mat result(imag_ch1.size(), CV_8U , cv::Scalar(255)) ;  cv::drawContours(result,chapter1,-1,cv::Scalar(0),2);  namedWindow("resultImage", 1);  cv::imshow("resultImage" , result);  vector<RectComp>RectCompList;  for(int i = 0;i<chapter1.size();i++)  {  Rect rm= cv::boundingRect(cv::Mat(chapter1[i]));  RectComp *ti = new RectComp(rm);  RectCompList.push_back(*ti);  //         printf("Rect %d x = %d,y = %d \n",i,rm.x,rm.y);  }  sort(RectCompList.begin(),RectCompList.end());  map<int,string>listenAnswer;  //判断这部分的答题卡是否都已涂上  for(int t = 0;t<RectCompList.size();t++)  {  if(RectCompList.at(t).rm.y<=22)  {  listenAnswer[t] = "A";  }  else if((RectCompList.at(t).rm.y>22)&&(RectCompList.at(t).rm.y<=34))  {  listenAnswer[t] = "B";  }  else if(RectCompList.at(t).rm.y>34)  {  listenAnswer[t] = "C";  }  printf("sorted %d x = %d,y = %d \n",t,RectCompList.at(t).rm.x,RectCompList.at(t).rm.y);  }  for(map<int,string>::iterator it = listenAnswer.begin();it!=listenAnswer.end();++it)  {  cout<<"num:"<<it->first+1<<","<<"answer:"<<it->second<<endl;  }  waitKey(0);  return 0;  }  


3. 结果




0 0
原创粉丝点击