首页 > 解决方案 > 身份证轮廓

问题描述

我正在尝试检测身份证的轮廓,但它从来没有用过;我尝试了four_point_transform、boundingrect、boundries、active_contours、hough 变换以及相同的结果,用于扫描身份证的轮廓。id 看起来像这样:这里 是代码的样子:

 from trans import four_point_transform
from skimage.filters import threshold_local
import numpy as np
import cv2
import imutils

def edgeDetection(image):        
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(image, (5, 5), 0)
    edged = cv2.Canny(gray, 200,150 )
    return edged

def detectrectarrondi(image,edged):        
    orig = image.copy()
    gray = cv2.cvtColor(orig, cv2.COLOR_BGR2GRAY)
    edged = cv2.Canny(gray, 50, 40)
    orig_edged = edged.copy()

    (_,contours, _) = cv2.findContours(orig_edged, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
    contours = sorted(contours, key=cv2.contourArea, reverse=True)

    for contour in contours:
        c = max(contours, key = cv2.contourArea)
        (x,y,w,h) = cv2.boundingRect(c)
        screen = cv2.rectangle(image, (x,y), (x+w,y+h), (0,255,0), 2)
        return screen              

def scan(screen,image):
    ratio = image.shape[0] / 500.0
    warped = four_point_transform(image, screen.reshape(4, 2) * ratio)
    warped= cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)
    T = threshold_local(warped, 11, offset = 10, method = "gaussian")
    warped = (warped > T).astype("uint8") * 255

    return warped  

标签: pythonopencv

解决方案


因为我没有 50 名声望,所以我无法写评论,我将在此处为您提供一些步骤: 1/ 使用 cvtColor 将您的图像转换为灰度。

2/ 应用 GaussianBlur 来减少噪音。

3/ 应用 Canny 边缘检测器,您需要使用越来越低的阈值来获得最佳结果

4/ 此步骤不是必需的,但可能会有所帮助,应用形态学操作以使用 MORPH_CLOSE 参数关闭不完整的轮廓。

5/ 使用 findContours 查找轮廓

6/遍历找到的轮廓并绘制面积最大的粘合矩形。

我希望这对您有所帮助,如果您想查看一些代码,请告诉我。

编辑:

   Imgproc.cvtColor(origMat, mGray, Imgproc.COLOR_BGR2GRAY);

    Imgproc.GaussianBlur(mGray, mGray, new Size(5, 5), 5);

    Imgproc.Canny(mGray, mGray, 30, 80, 3, false);

    Mat kernell = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(9,9));

    Imgproc.morphologyEx(mGray, mGray, Imgproc.MORPH_CLOSE, kernell);

    Imgproc.dilate(mGray, mGray, Imgproc.getStructuringElement(Imgproc.MORPH_CROSS, new Size(3, 3)));


    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();

    Mat hierarchy = new Mat();

    Imgproc.findContours(mGray, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

    MatOfPoint2f approxCurve = new MatOfPoint2f();

    double largest_area=0;
    int largest_contour_index=0;
    Rect rect = new Rect();

    for (int idx = 0; idx < contours.size() ; idx++) {

        double a = Imgproc.contourArea(contours.get(idx));  //Find the area of contour

        if (a > largest_area) {
            largest_area = a;
            largest_contour_index = idx;
            rect = Imgproc.boundingRect(contours.get(idx));
        }
    }
        Imgproc.rectangle(origMat, rect.tl(), rect.br(), new Scalar(0, 255, 0));

    return origMat;

你可以看看这个很好的答案,使用图像的中值自动设置 Canny 阈值

https://stackoverflow.com/a/41895229


推荐阅读