概述: 本節(jié)主要結(jié)合降噪,色域轉(zhuǎn)換,二值化,邊緣檢測(cè)及獲取輪廓等函數(shù),實(shí)現(xiàn)對(duì)身份證的邊緣位置檢測(cè);
一: 本節(jié)目的:
先展示一下效果:
Snip20171109_1.png
本人真實(shí)身份證(留個(gè)眼睛看著你們...),聽(tīng)說(shuō)最近有一鍵卸妝的軟件,唉,你要真給我卸了也就認(rèn)命了;不扯淡,說(shuō)正題,這個(gè)效果有什么用呢?
說(shuō)實(shí)話我也不知道,恰好最近有這么個(gè)需求而已,要求如下:
檢測(cè)身份證,銀行卡,營(yíng)業(yè)執(zhí)照等等....要在UI上提示用戶拍攝時(shí)目標(biāo)證件是否在要求的框框范圍之內(nèi),不能超出也不能太小,嗯,沒(méi)毛病,就是這樣的;
二.實(shí)現(xiàn)過(guò)程:
Snip20171109_8.png
三. 代碼實(shí)現(xiàn):
#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));
// 轉(zhuǎn)為灰度圖
cvtColor(sourceMatImage, sourceMatImage, CV_BGR2GRAY);
// 二值化
threshold(sourceMatImage, sourceMatImage, 190, 255, CV_THRESH_BINARY);
// 檢測(cè)邊界
Canny(sourceMatImage, sourceMatImage, minThreshold * ratioThreshold, minThreshold);
// 獲取輪廓
std::vector<std::vector<cv::Point>> contours;
findContours(sourceMatImage, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
/*
* 重新繪制輪廓
*/
// 初始化一個(gè)8UC3的純黑圖像
Mat dstImg(sourceMatImage.size(), CV_8UC3, Scalar::all(0));
// 用于存放輪廓折線點(diǎn)集
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++ 少一次內(nè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++ 基礎(chǔ)不夠,可以使用 for 循環(huán)
* 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);
// 顯示繪制結(jié)果
self.desImageView.image = MatToUIImage(dstImg);
補(bǔ)充:截取的邊界應(yīng)該去除透視投影:
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()
);