OpenCV For iOS(三): 边界轮廓检测


概述: 本节主要结合降噪,色域转换,二值化,边缘检测及获取轮廓等函数,实现对身份证的边缘位置检测;


完整Demo 传送门

一: 本节目的:

先展示一下效果:


OpenCV For iOS(三): 边界轮廓检测_第1张图片
Snip20171109_1.png

本人真实身份证(留个眼睛看着你们...),听说最近有一键卸妆的软件,唉,你要真给我卸了也就认命了;不扯淡,说正题,这个效果有什么用呢?

说实话我也不知道,恰好最近有这么个需求而已,要求如下:
检测身份证,银行卡,营业执照等等....要在UI上提示用户拍摄时目标证件是否在要求的框框范围之内,不能超出也不能太小,嗯,没毛病,就是这样的;

二.实现过程:

OpenCV For iOS(三): 边界轮廓检测_第2张图片
Snip20171109_8.png

三. 代码实现:

#import 
...
...
using namespace cv;
using namespace std;
double  minThreshold = 10;
double  ratioThreshold = 3;

- (void)viewDidLoad{
    [super viewDidLoad];

    Mat sourceMatImage;
    UIImageToMat(self.imageView.image, sourceMatImage);
    // 降噪
    blur(sourceMatImage, sourceMatImage, cv::Size(3,3));
    // 转为灰度图
    cvtColor(sourceMatImage, sourceMatImage, CV_BGR2GRAY);
    // 二值化
    threshold(sourceMatImage, sourceMatImage, 190, 255, CV_THRESH_BINARY);
    // 检测边界
    Canny(sourceMatImage, sourceMatImage, minThreshold * ratioThreshold, minThreshold);
    // 获取轮廓
    std::vector> contours;
    findContours(sourceMatImage, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
    
    /*
     *  重新绘制轮廓
     */
    // 初始化一个8UC3的纯黑图像
    Mat dstImg(sourceMatImage.size(), CV_8UC3, Scalar::all(0));
    // 用于存放轮廓折线点集
    std::vector> contours_poly(contours.size());
    // STL遍历
    std::vector>::const_iterator itContours = contours.begin();
    std::vector>::const_iterator itContourEnd = contours.end();
    // ++i 比 i++ 少一次内存写入,性能更高
    for (int i=0 ; itContours != itContourEnd; ++itContours,++i) {
        approxPolyDP(Mat(contours[i]), contours_poly[i], 15, true);
        // 绘制处理后的轮廓,可以一段一段绘制,也可以一次性绘制
        // drawContours(dstImg, contours_poly, i, Scalar(208, 19, 29), 8, 8);
    }
    
   /*如果C++ 基础不够,可以使用 for 循环
    *    for (int i = 0; i < contours.size(); i ++) {
    *        approxPolyDP(contours[i] , contours_poly[i], 5, YES);
    *    }
    */
    
    // 绘制处理后的轮廓,一次性绘制
    drawContours(dstImg, contours_poly, -1, Scalar(208, 19, 29), 8, 8);
    // 显示绘制结果
    self.desImageView.image = MatToUIImage(dstImg);

补充:截取的边界应该去除透视投影:

CV_EXPORTS Mat getPerspectiveTransform( const Point2f src[], const Point2f dst[] );
   

CV_EXPORTS_W void warpPerspective( InputArray src,
                                  OutputArray dst,
                                     InputArray M, 
                                       Size dsize,   
                           int flags=INTER_LINEAR,
                   int borderMode=BORDER_CONSTANT,
               const Scalar& borderValue=Scalar()
);

你可能感兴趣的:(OpenCV For iOS(三): 边界轮廓检测)