您的位置:首页 > 移动开发 > IOS开发

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

2017-08-21 15:41 531 查看
身份证就不发了,发个烟盒效果图吧



基础步骤:

一:导入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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息