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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM