iOS-OpenCV之视频流身份证轮廓识别

来源:互联网 发布:无锡华云数据 编辑:程序博客网 时间:2024/06/01 09:38

身份证就不发了,发个烟盒效果图吧
恩,识别到了利群的轮廓23333
基础步骤:
一:导入OpenCV库,http://opencv.org下载即可,直接导入工程
二:写入C++命名空间:using namespace cv; using namespace std;
三:头文件#import < opencv2/opencv.hpp> 基础类库;#import < opencv2/imgcodecs/ios.h> #import < opencv2/videoio/cap_ios.h> 视频图像处理类库
四:由于用到视频处理,遵循CvVideoCameraDelegate 代理,并设置代理。

代码:

- (void)viewDidLoad {    [super viewDidLoad];   //全局创建一个视频对象并初始化加载在一个imageView上,设置代理    _camera = [[CvVideoCamera alloc]initWithParentView:_imageView];    //开启后摄像头    _camera.defaultAVCaptureDevicePosition = AVCaptureDevicePositionBack;    _camera.delegate = self;}- (IBAction)clickImage:(id)sender {    //按钮点击事件,开启摄像头    [_camera start];}//实现opencv的视频流代理- (void)processImage:(cv::Mat&)image{    //image对象就是视频流时时返回的对象,一秒可达30帧;用一个Mat对象(imageClone)对返回的image对象拷贝    Mat imageClone = image.clone();    std::vector<std::vector<cv::Point> > squares;    //图片灰度处理    cv::Mat src_gray;    //第一个参数为转换前的image,第二个参数为,转换后的image,第三个参数为需要转换成什么样的图片,这边为灰度图片。    cv::cvtColor(image, src_gray, cv::COLOR_BGR2GRAY);    // 滤波降噪,第三个参数为阈值,可以搜搜看    cv::Mat filtered;    cv::blur(src_gray, filtered, cv::Size(7,7));    //边缘检测    cv::Mat edges;    int thresh = 50;    cv::Canny(filtered, edges, thresh, thresh * 2, 3);      //膨胀    cv::Mat dilated_edges;    cv::dilate(edges, dilated_edges, cv::Mat(), cv::Point(-1, -1), 2, 1, 1);    // 找到轮廓并存储    std::vector<std::vector<cv::Point> > contours;    cv::findContours(dilated_edges, contours, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE);    std::vector<cv::Point> approx;    for (size_t i = 0; i < contours.size(); i++) {        //找出轮廓的凸包        cv::convexHull(contours[i], approx) ;        // 对cv::arcLength(cv::Mat(approx), true)*0.02这个阈值外的线条进行拟合        cv::approxPolyDP(cv::Mat(approx), approx, cv::arcLength(cv::Mat(approx), true)*0.02, true);        // Note: absolute value of an area is used because        // area may be positive or negative - in accordance with the        // contour orientation        if (approx.size() == 4 && std::fabs(contourArea(cv::Mat(approx))) > 1000 &&            cv::isContourConvex(cv::Mat(approx)))        {            double maxCosine = 0;            for (int j = 2; j < 5; j++)             {                double cosine = std::fabs(SecondViewControllerAngle(approx[j%4], approx[j-2], approx[j-1]));                maxCosine = MAX(maxCosine, cosine);            }            if (maxCosine < 0.3)                squares.push_back(approx);        }    }    //至此,你可以发现,用了一个白色的框,框住了身份证的大轮廓。    std::vector<cv::Point> largest_square;    findLargestSquare(squares, largest_square);    const cv::Point* p = &largest_square[0];    int n = (int)largest_square.size();    cv::polylines(image, &p, &n, 1, true, cv::Scalar(0, 0, 0), 3, CV_AA);}
原创粉丝点击