OpenCV For iOS(三): 邊界輪廓檢測


概述: 本節主要結合降噪,色域轉換,二值化,邊緣檢測及獲取輪廓等函數,實現對身份證的邊緣位置檢測;


完整Demo 傳送門

一: 本節目的:

先展示一下效果:


Snip20171109_1.png

本人真實身份證(留個眼睛看著你們...),聽說最近有一鍵卸妝的軟件,唉,你要真給我卸了也就認命了;不扯淡,說正題,這個效果有什么用呢?

說實話我也不知道,恰好最近有這么個需求而已,要求如下:
檢測身份證,銀行卡,營業執照等等....要在UI上提示用戶拍攝時目標證件是否在要求的框框范圍之內,不能超出也不能太小,嗯,沒毛病,就是這樣的;

二.實現過程:

Snip20171109_8.png

三. 代碼實現:

#import <opencv2/highgui/cap_ios.h>
...
...
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<std::vector<cv::Point>> contours;
    findContours(sourceMatImage, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
    
    /*
     *  重新繪制輪廓
     */
    // 初始化一個8UC3的純黑圖像
    Mat dstImg(sourceMatImage.size(), CV_8UC3, Scalar::all(0));
    // 用于存放輪廓折線點集
    std::vector<std::vector<cv::Point>> contours_poly(contours.size());
    // STL遍歷
    std::vector<std::vector<cv::Point>>::const_iterator itContours = contours.begin();
    std::vector<std::vector<cv::Point>>::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()
);
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。