2014-06-16 13 views
13

Ich versuche, die nationale ID des folgenden Typs zu erkennen und die Details dazu zu erhalten. Zum Beispiel sollte sich der Ort der Unterschrift in der oberen rechten Ecke des Personenbildes befinden , in diesem Fall "BC".Den Personalausweis ausfindig machen und die Details bekommen

enter image description here

Ich brauche diese Anwendung in iPhone zu tun. Ich dachte daran, Opencv dafür zu verwenden, aber wie kann ich die markierten Details erreichen? Muss ich die Anwendung mit ähnlichen Karten ausbilden? Oder OCR könnte helfen?

Gibt es spezifische Implementierungen für mobile Anwendungen?

Ich bin auch durch card-io gegangen, die die Kreditkartendetails erkennt, erkennt Card-io die anderen Kartendetails auch?

Update:

I tesseract für Texterkennung verwendet haben. Tesseract funktioniert gut, wenn das Bild nur Text enthält. Also habe ich die rot markierten Bereiche abgeschnitten und als Eingabe für Tesseract angegeben, es funktioniert gut mit dem MRZ-Teil.

Es gibt eine IOS implementation für Tesseract, mit der ich getestet habe.

Was muss ich tun?

Jetzt versuche ich den Text Erkennungsteil zu automatisieren. Jetzt plane ich, die folgenden Punkte zu automatisieren:

1) Das Gesicht zuschneiden (Ich habe mit Viola-Jones Gesichtsdetektor getan).

2) Müssen Sie die Initiale in diesem Beispiel "BC" aus dem Foto nehmen.

3) Extrahieren/Erkennen der MRZ-Region von der ID-Karte.

Ich versuche zu tun 2 & 3, Ideen oder Code-Schnipsel wäre toll.

+4

Wenn das eine echte Person ist, dann hoffe ich, dass Antoine nichts dagegen hat, seine ID im Web für alle sichtbar zu sehen! – QED

+0

Möchten Sie Daten aus IDs extrahieren? Ich denke, alle Daten, die Sie brauchen, finden Sie in MRZ, also ist das Problem MRZ-Erkennung, habe ich recht? –

+0

@Vitalik Sie haben Recht, ich habe den Inhalt in MRZ nicht bemerkt. Danke für die Antwort. Irgendwelche Ideen, den MRZ-Teil allein zu finden, plane ich, eine quadratische Erkennung zu versuchen, um den MRZ-Teil zu finden. Wird es trainieren? – 2vision2

Antwort

2

Card.io wurde speziell für geprägte Kreditkarten entwickelt. Es wird für diesen Anwendungsfall nicht funktionieren.

+0

Danke für die Antwort. Kann ich diesen Anwendungsfall auf andere Weise erreichen? – 2vision2

+0

Alles ist mit ausreichendem Aufwand möglich. ;) Ich würde hier beginnen: http://stackoverflow.com/questions/3750719/getting-started-in-computervision-road-tracking – tomwhipple

14

Angenommen, diese IDs werden gemäß einer Standardvorlage mit spezifischen Breiten, Höhen, Offsets, Abständen usw. vorbereitet. Sie können also einen auf Vorlagen basierenden Ansatz verwenden.

MRZ wäre leicht zu erkennen. Sobald Sie es im Bild gefunden haben, finden Sie die Transformation, die die MRZ in Ihrer Vorlage darauf abbildet. Wenn Sie diese Transformation kennen, können Sie eine beliebige Region Ihrer Vorlage (z. B. das Foto der Person) dem Bild zuordnen und diese Region extrahieren.

Unten ist ein sehr einfaches Programm, das einem glücklichen Weg folgt. Sie müssen mehr Verarbeitung durchführen, um die MRZ im Allgemeinen zu lokalisieren (zum Beispiel, wenn es perspektivische Verzerrungen oder Drehungen gibt). Ich habe die Vorlage vorbereitet, indem ich nur das Bild gemessen habe, und es wird nicht für Ihren Fall funktionieren. Ich wollte nur die Idee vermitteln. Das Bild wurde genommen von 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); 
     } 
    } 

Ergebnis: Foto und Namen Regionen in Orange. MRZ in blau. enter image description here

2

Die PassportEye-Bibliothek ist jetzt für diesen Zweck verfügbar. Es ist nicht perfekt, aber funktioniert ziemlich gut in meiner Erfahrung: https://pypi.python.org/pypi/PassportEye/

+0

von meinen Tests und anderen Kommentaren hier http://www.pyimagesearch.com/2015/11/30/Detektieren von maschinenlesbaren Zonen-in-Pass-Bildern/(siehe Don's), dieses Modul ist nicht bereit für Prod (weit davon entfernt) – comte