web-dev-qa-db-fra.com

Détection de la carte d'identité nationale et obtention des détails

J'essaie de détecter l'ID national du type ci-dessous et d'en obtenir les détails. Par exemple, l'emplacement de la signature doit être trouvé dans le coin supérieur droit de l'image des personnes, dans ce cas "BC".

enter image description here

J'ai besoin de faire cette application sur iphone. J'ai pensé à utiliser Opencv pour cela, mais comment puis-je obtenir les détails marqués? Dois-je former l'application avec des cartes de type similaire ou OCR pourrait aider?

Existe-t-il des implémentations spécifiques pour les applications mobiles?

J'ai également utilisé card-io qui détecte les détails de la carte de crédit. Est-ce que Card-io détecte également les autres détails de la carte?

Mise à jour:

J'ai utilisé tesseract pour la détection de texte. Tesseract fonctionne bien si l'image ne contient que du texte. J'ai donc recadré les régions marquées en rouge et donné en entrée à Tesseract, cela fonctionne bien avec la partie MRZ.

Il y a implémentation IOS pour Tesseract, avec lequel j'ai testé.

Ce que je dois faire?

Maintenant, j'essaie d'automatiser la partie de détection de texte. Maintenant, je prévois d'automatiser les éléments suivants,

1) Recadrage du visage (j'ai utilisé le détecteur de visage Viola-jones).

2) Besoin de prendre l'initiale dans cet exemple "BC" de la photo.

3) Extraire/détecter la région MRZ de la carte d'identité.

J'essaie de faire 2 et 3, toutes les idées ou extraits de code seraient formidables.

21
2vision2

En supposant que ces ID sont préparés selon un modèle standard ayant des largeurs, hauteurs, décalages, espacements, etc. spécifiques, vous pouvez essayer une approche basée sur un modèle.

MRZ serait facile à détecter. Une fois que vous l'avez détecté dans l'image, recherchez la transformation qui mappe la MRZ dans votre modèle. Lorsque vous connaissez cette transformation, vous pouvez mapper n'importe quelle région de votre modèle (par exemple, la photo de l'individu) sur l'image et extraire cette région.

Voici un programme très simple qui suit un chemin heureux. Vous devrez faire plus de traitement pour localiser la MRZ en général (par exemple, s'il y a des distorsions ou des rotations de perspective). J'ai préparé le modèle juste en mesurant l'image, et cela ne fonctionnera pas pour votre cas. Je voulais juste transmettre l'idée. L'image a été prise de wiki

    Mat rgb = imread(INPUT_FILE);
    Mat gray;
    cvtColor(rgb, gray, CV_BGR2GRAY);

    Mat grad;
    Mat morphKernel = getStructuringElement(MORPH_ELLIPSE, Size(3, 3));
    morphologyEx(gray, grad, MORPH_GRADIENT, morphKernel);

    Mat bw;
    threshold(grad, bw, 0.0, 255.0, THRESH_BINARY | THRESH_OTSU);

    // connect horizontally oriented regions
    Mat connected;
    morphKernel = getStructuringElement(MORPH_RECT, Size(9, 1));
    morphologyEx(bw, connected, MORPH_CLOSE, morphKernel);

    // find contours
    Mat mask = Mat::zeros(bw.size(), CV_8UC1);
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    findContours(connected, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

    vector<Rect> mrz;
    double r = 0;
    // filter contours
    for(int idx = 0; idx >= 0; idx = hierarchy[idx][0])
    {
        Rect rect = boundingRect(contours[idx]);
        r = rect.height ? (double)(rect.width/rect.height) : 0;
        if ((rect.width > connected.cols * .7) && /* filter from rect width */
            (r > 25) && /* filter from width:hight ratio */
            (r < 36) /* filter from width:hight ratio */
            )
        {
            mrz.Push_back(rect);
            rectangle(rgb, rect, Scalar(0, 255, 0), 1);
        }
        else
        {
            rectangle(rgb, rect, Scalar(0, 0, 255), 1);
        }
    }
    if (2 == mrz.size())
    {
        // just assume we have found the two data strips in MRZ and combine them
        CvRect max = cvMaxRect(&(CvRect)mrz[0], &(CvRect)mrz[1]);
        rectangle(rgb, max, Scalar(255, 0, 0), 2);  // draw the MRZ

        vector<Point2f> mrzSrc;
        vector<Point2f> mrzDst;

        // MRZ region in our image
        mrzDst.Push_back(Point2f((float)max.x, (float)max.y));
        mrzDst.Push_back(Point2f((float)(max.x+max.width), (float)max.y));
        mrzDst.Push_back(Point2f((float)(max.x+max.width), (float)(max.y+max.height)));
        mrzDst.Push_back(Point2f((float)max.x, (float)(max.y+max.height)));

        // MRZ in our template
        mrzSrc.Push_back(Point2f(0.23f, 9.3f));
        mrzSrc.Push_back(Point2f(18.0f, 9.3f));
        mrzSrc.Push_back(Point2f(18.0f, 10.9f));
        mrzSrc.Push_back(Point2f(0.23f, 10.9f));

        // find the transformation
        Mat t = getPerspectiveTransform(mrzSrc, mrzDst);

        // photo region in our template
        vector<Point2f> photoSrc;
        photoSrc.Push_back(Point2f(0.0f, 0.0f));
        photoSrc.Push_back(Point2f(5.66f, 0.0f));
        photoSrc.Push_back(Point2f(5.66f, 7.16f));
        photoSrc.Push_back(Point2f(0.0f, 7.16f));

        // surname region in our template
        vector<Point2f> surnameSrc;
        surnameSrc.Push_back(Point2f(6.4f, 0.7f));
        surnameSrc.Push_back(Point2f(8.96f, 0.7f));
        surnameSrc.Push_back(Point2f(8.96f, 1.2f));
        surnameSrc.Push_back(Point2f(6.4f, 1.2f));

        vector<Point2f> photoDst(4);
        vector<Point2f> surnameDst(4);

        // map the regions from our template to image
        perspectiveTransform(photoSrc, photoDst, t);
        perspectiveTransform(surnameSrc, surnameDst, t);
        // draw the mapped regions
        for (int i = 0; i < 4; i++)
        {
            line(rgb, photoDst[i], photoDst[(i+1)%4], Scalar(0,128,255), 2);
        }
        for (int i = 0; i < 4; i++)
        {
            line(rgb, surnameDst[i], surnameDst[(i+1)%4], Scalar(0,128,255), 2);
        }
    }

Résultat: régions photo et nom de famille en orange. MRZ en bleu. enter image description here

21
dhanushka

Card.io est spécialement conçu pour les cartes de crédit en relief. Cela ne fonctionnera pas pour ce cas d'utilisation.

3
tomwhipple

Il y a maintenant la bibliothèque PassportEye disponible à cet effet. Ce n'est pas parfait, mais fonctionne assez bien dans mon expérience: https://pypi.python.org/pypi/PassportEye/

2
user1747134