iOS-opencv识别答题卡

标签:新手 - 参考别人的项目做了略微的修改,大神轻喷。

参考文献:http://www.cuipengfei.cn/2018/04/opencv-answer-sheet-identify/

1.安装opencv,百度安装即可 

注意点:不知道是我自己的问题还是为什么,导入库的时候一定要安装官方提供的顺序倒入,不然会报错,大神如果知道原因望告知我。

2.因为opencv是 c++语言 所以在oc中需要将.m 改为.mm就不报错了

3.因为c++没有uiimage属性 所以需要将 uiimage 转化成 c++的image 也就是 cv::mat

转换方法:

- (cv::Mat)cvMatImage {

    CGColorSpaceRef colorSpace = CGImageGetColorSpace(self.CGImage);

    CGFloat cols = self.size.width;

    CGFloat rows = self.size.height;


    cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels (color channels + alpha)


    CGContextRefcontextRef =CGBitmapContextCreate(cvMat.data,                // Pointer to  data

                                                    cols,                      // Width of bitmap

                                                    rows,                      // Height of bitmap

                                                    8,                          // Bits per component

                                                    cvMat.step[0],              // Bytes per row

                                                    colorSpace,                // Colorspace

                                                    kCGImageAlphaNoneSkipLast|

                                                    kCGBitmapByteOrderDefault);// Bitmap info flags


    CGContextDrawImage(contextRef,CGRectMake(0,0, cols, rows),self.CGImage);

    CGContextRelease(contextRef);


    returncvMat;

}

4.获取到用户的拍照图片转化成cv::mat 之后第一步  灰度处理

代码 cv::cvtColor(inputMat, tmp,CV_BGR2GRAY);

inputMat ->原图像        tmp->灰度处理后的图像     CV_BGR2GRAY ->将rgb转化gray


灰度处理后的图像

5. 去噪声和二值化

    5.1去噪声  cv::blur(outputMat, tmp,cv::Size(3,3)); 

outputMat ->原图像  tmp -> 输出的图像   cv::Size 必须是单数 并且数字越大模糊的与厉害


size(3,3)


size(9,9)


size(25,25)

5.2 二值化 非常重要的一步

代码:cv::adaptiveThreshold(outputMat, tmp, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, 225, 40);

cv::adaptiveThreshold ->自适应阈值化方法

outputMat ->输入图片   tmp ->输出图片  255->最大色差阈值

CV_ADAPTIVE_THRESH_MEAN_C ->见详解  https://blog.csdn.net/superdont/article/details/6661994

CV_THRESH_BINARY_INV ->黑转白 白转黑 


二值化

6.识别边缘,由于代码太长 不复制了 

思想就是 找图片上的直线 

7. 图片纠正

根据 第6步找到的直线,利用直线的交点 找到我们需要的涂填答题卡的区域 将这个区域转化成不是倾斜的图片

核心代码:    

cv::Mat transform =cv::getPerspectiveTransform(src_vertices,dst_vertices); cv::warpPerspective(inputMat, tmp, transform,cv::Size(kuan, gao));

src_vertices ->原始图片有效区域的四个顶点坐标集合 

dst_vertices ->纠正之后的图片四个定点坐标集合

inputMat -> 输入图像

tmp ->输出图像 

cv::Size(kuan, gao) 输出图像的width height


纠正之后的图片

8.切割识别区域

这一步呢 根据每张答题卡不同的行与行 列于列的间距进行处理

就不上代码了,看图


切割有效区域

9.判断有效区域是否属于被涂抹

我判断的依据: 每一题四个选项的阈值 最高比最低多10 这一题算用户涂抹了

然后在判断这四个选项中阈值最大的一个 算用户涂抹的答案


打印的阈值

以上就是我的拙见。


地址: https://github.com/Godwuqiang/shibiedatika.git

你可能感兴趣的:(iOS-opencv识别答题卡)