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".
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.
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.
Card.io est spécialement conçu pour les cartes de crédit en relief. Cela ne fonctionnera pas pour ce cas d'utilisation.
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/