gpt4 book ai didi

android - 如何使用 OpenCV 检测 Passport 页面的边界?

转载 作者:可可西里 更新时间:2023-11-01 17:55:43 40 4
gpt4 key购买 nike

我正在尝试开发一种可以用相机扫描护照页面的扫描仪。

所以从像这样的 Passport 页面: Sample passport page

我想剪掉标记的部分。

我已经使用 OpenCV 编写了边缘检测代码,它可以找到轮廓,然后逼近最大的四边形。最后,它进行 4 点透视变换以获得图像的俯 View 。边缘检测代码如下所示:

public static List<MatOfPoint> findContours(Mat src){
Mat img = src.clone();
src.release();
//find contours
double ratio = getScaleRatio(img.size());
int width = (int) (img.size().width / ratio);
int height = (int) (img.size().height / ratio);
Size newSize = new Size(width, height);
Mat resizedImg = new Mat(newSize, CvType.CV_8UC4);
Imgproc.resize(img, resizedImg, newSize);

Imgproc.medianBlur(resizedImg, resizedImg, 5);

Mat cannedImg = new Mat(newSize, CvType.CV_8UC1);
Imgproc.Canny(resizedImg, cannedImg, 70, 200, 3, true);
resizedImg.release();

Imgproc.threshold(cannedImg, cannedImg, 200, 255, Imgproc.THRESH_OTSU);

Mat dilatedImg = new Mat(newSize, CvType.CV_8UC1);
Mat morph = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3));
Imgproc.dilate(cannedImg, dilatedImg, morph, new Point(-1, -1), 2, 1, new Scalar(1));
cannedImg.release();
morph.release();

ArrayList<MatOfPoint> contours = new ArrayList<>();
Mat hierarchy = new Mat();
Imgproc.findContours(dilatedImg, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
hierarchy.release();

Log.d(TAG, "contours found: " + contours.size());

Collections.sort(contours, new Comparator<MatOfPoint>() {
@Override
public int compare(MatOfPoint o1, MatOfPoint o2) {
return Double.valueOf(Imgproc.contourArea(o2)).compareTo(Imgproc.contourArea(o1));
}
});

return contours;
}

for(MatOfPoint contour:contours){
MatOfPoint2f mat = new MatOfPoint2f(contour.toArray());
double peri = Imgproc.arcLength(mat, true);
MatOfPoint2f approx = new MatOfPoint2f();
Imgproc.approxPolyDP(mat, approx, 0.02 * peri, true);

Point[] points = approx.toArray();
Log.d("SCANNER", "approx size " + points.length);

if (points.length == 4) {
Point[] spoints = CVProcessor.sortPoints(points);

if (CVProcessor.insideArea(spoints, newSize)) {
rectContour = contour;
foundPoints = spoints;
break;
}
}
}

此代码适用于单页文档,即身份证、信用卡。其中有 4 个可区分的边缘。

但不适用于护照,因为顶部边缘没有那么明显。

输入将从 Android 上的摄像头获取。知道如何检测护照页吗?我正在使用 OpenCV 3.1。

以下是一些示例输入(从 Google 图片搜索获得): Sample 1 Sample 2

最佳答案

如果您能找到 Machine Readable Zone (MRZ) 就可以提取页面护照(下图中以红色标出的区域)。通常,机读区与其背景之间的对比度非常好,因此可以使用基于梯度的方法或 MSER 进行检测。

假设有一个标准模板(即页面的宽高比、机读区、字段的偏移量等),根据该模板准备护照,一旦找到机读区,就很容易找到页面边框以及其他字段,例如下面模板图像中显示的人的照片,其中 MRZ 以红色勾勒出轮廓,页面边框以绿色勾勒出轮廓。这是假设没有透视失真。如果有这样的失真,首先你应该纠正它,然后再应用模板。您可以使用 MRZ 本身来纠正失真,因为您知道 MRZ 区域的纵横比。

模板准备自 image .

template

检查 here从护照中非常简单地实现基于模板模型的字段提取。它不适用于您的图像,并且需要大量参数调整,因此我不建议立即使用它。我提到它只是为了传达基于模板的提取和其他预处理方法的想法。

但是,如果护照是弯曲的,如下图所示(您可以看到机读区边界无法使用直线追踪),则很难纠正变形。

最后,如果您使用的是高分辨率图像,最好对它们进行下采样和处理,因为这在嵌入式系统上会更快。一旦您从缩减采样的图像中找到 MRZ,您就可以使用高分辨率图像来细化角落。 mrz

关于android - 如何使用 OpenCV 检测 Passport 页面的边界?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40192541/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com