opencv 识别答题卡
参考这个网站,然后自己 找了张图片试了一下 http://blog.csdn.net/cp562090732/article/details/47804003
// test.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "cv.h" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include "highgui.h" #include "cxcore.h" #include <string> #include <stdlib.h> #include <stdio.h> #include <vector> #include <map> using namespace std; using namespace cv; class RectComp//Rect排序 { 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:\\13.jpg"); Mat srcImage2,srcImage3,srcImage4,srcImage5; //namedWindow("hello-1", 1); //imshow("hello-1",srcImage1); // cv::waitKey(0); //图片变成灰度图片 cvtColor(srcImage1,srcImage2,CV_BGR2GRAY); //imshow("hello-2",srcImage2); // cv::waitKey(0); //图片二值化 threshold(srcImage2,srcImage3,200,255,THRESH_BINARY_INV); imshow("hello-3",srcImage3); cv::waitKey(0); //确定腐蚀和膨胀核的大小 Mat element = getStructuringElement(MORPH_RECT, Size(3, 3)); //腐蚀操作 erode(srcImage3,srcImage4,element); //膨胀操作 dilate(srcImage4,srcImage5,element); namedWindow("hello-5", 1); imshow("hello-5", srcImage5 ); cv::waitKey(0); //确定每张答题卡的ROI区域 Mat imag_ch1 = srcImage5(Rect(2,20,268,40)); namedWindow("img1", 1); imshow("img1",imag_ch1); cv::waitKey(0); //提取已经涂好了的选项 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)); 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()); std::map<int,string>listenAnswer; //判断这部分的答题卡是否都已涂上 for(int t = 0;t<RectCompList.size();t++) { if(RectCompList.at(t).rm.y<5) { listenAnswer[t] = "A"; } else if((RectCompList.at(t).rm.y>5)&&(RectCompList.at(t).rm.y<16)) { listenAnswer[t] = "B"; } else if(RectCompList.at(t).rm.y>16) { 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; } cv::waitKey(0); return 0; }
感觉腐蚀操作的正方形大小选择很关键,过大过小效果都不好。http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.html
posted on 2017-04-11 17:09 zyz913614263 阅读(3683) 评论(0) 编辑 收藏 举报