2014-06-16 11 views
13

Sto cercando di rilevare l'ID nazionale del tipo sottostante e ottenere i dettagli di esso, ad esempio la posizione della firma dovrebbe essere trovata nell'angolo in alto a destra dell'immagine delle persone , in questo caso "BC".Rilevamento della carta di identità nazionale e ottenere i dettagli

enter image description here

ho bisogno di fare questa applicazione iPhone. Ho pensato di usare Opencv per questo, ma come posso ottenere i dettagli marcati? Devo allenare l'applicazione con carte simili o OCR potrebbe aiutare?

Esiste qualche implementazione specifica per le applicazioni mobili?

Ho anche provato il card-io che rileva i dettagli della carta di credito, Card-io rileva anche gli altri dettagli della carta?

Aggiornamento:

ho usato tesseract per il rilevamento di testo. Tesseract funziona bene se l'immagine ha solo testo. Così ho ritagliato le regioni contrassegnate in rosso e dato come input per Tesseract, funziona bene con la parte MRZ.

C'è un IOS implementation per Tesseract, con cui ho provato.

Cosa devo fare?

Ora sto cercando di automatizzare la parte di rilevamento del testo. Ora sto pianificando di automatizzare i seguenti elementi,

1) Ritagliare il viso (ho utilizzato il rilevatore di volti Viola-jones).

2) È necessario prendere l'iniziale in questo esempio "BC" dalla foto.

3) Estrazione/rilevamento della regione MRZ dalla scheda ID.

Sto cercando di fare 2 & 3, Qualsiasi idea o frammento di codice sarebbe fantastico.

+4

Se questa è una persona reale, allora spero che a Antoine non dispiaccia che il suo ID sia pubblicato sul web perché tutti lo vedano! – QED

+0

Vuoi estrarre i dati dagli ID? Penso che tutti i dati di cui hai bisogno possano essere trovati in MRZ, quindi il problema è il riconoscimento MRZ, vero? –

+0

@Vitalik Hai ragione, non ho notato il contenuto in MRZ. Grazie per la risposta. Qualche idea su come trovare la parte MRZ da solo, sto pensando di provare il rilevamento quadrato per trovare la parte MRZ. Allenerà? – 2vision2

risposta

2

Card.io è progettato specificamente per carte di credito in rilievo. Non funzionerà per questo caso d'uso.

+0

Grazie per la risposta. Posso raggiungere questo caso d'uso con altri metodi. – 2vision2

+0

Tutto è possibile con uno sforzo sufficiente. ;) Vorrei iniziare qui: http://stackoverflow.com/questions/3750719/getting-started-in-computervision-road-tracking – tomwhipple

14

Supponendo che questi ID siano preparati secondo un modello standard con larghezze, altezze, offset, spaziatura, ecc. Specifici, è possibile provare un approccio basato su modelli.

MRZ sarebbe facile da rilevare. Una volta individuato nell'immagine, trova la trasformazione che mappa la MRZ nel tuo modello. Quando conosci questa trasformazione, puoi mappare qualsiasi regione sul modello (ad esempio, la foto dell'individuo) all'immagine ed estrarla.

Di seguito è riportato un programma molto semplice che segue un percorso felice. Dovrai fare più elaborazioni per localizzare la MRZ in generale (ad esempio, se ci sono distorsioni o rotazioni in prospettiva). Ho preparato il modello semplicemente misurando l'immagine e non funzionerà per il tuo caso. Volevo solo trasmettere l'idea. L'immagine è stata presa da 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); 
     } 
    } 

Risultato: foto e cognome regioni in arancione. MRZ in blu. enter image description here

2

C'è ora la libreria PassportEye disponibile per questo scopo. Non è perfetto, ma funziona abbastanza bene nella mia esperienza: https://pypi.python.org/pypi/PassportEye/

+0

dai miei test e altri commenti qui http://www.pyimagesearch.com/2015/11/30/zone-leggibili-rilevabili dalla macchina-in-passport-images/(vedi Don's), questo modulo non è pronto per prod (lontano da esso) – comte

Problemi correlati