이러한 ID는 특정 폭, 높이, 오프셋, 간격 등을 갖는 표준 템플리트에 따라 준비되었다고 가정하면 템플리트 기반 접근 방식을 시도 할 수 있습니다.
MRZ는 쉽게 감지 할 수 있습니다. 이미지에서이를 감지하면 템플릿의 MRZ를 매핑하는 변환을 찾습니다. 이 변환을 알면 템플릿의 모든 영역 (예 : 개인 사진)을 이미지에 매핑하고 해당 영역을 추출 할 수 있습니다.
다음은 행복한 경로를 따르는 매우 간단한 프로그램입니다. MRZ를 일반적으로 배치하기 위해 더 많은 처리 작업을 수행해야합니다 (예 : 원근 왜곡 또는 회전이있는 경우). 나는 단지 이미지를 측정하여 템플릿을 준비했으며, 귀하의 경우에는 작동하지 않습니다. 나는 그 아이디어를 전하고 싶었다. 이미지는 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);
}
}
결과 : 촬영 한 사진 및 성 영역 오렌지색입니다. 파란색으로 된 MRZ. ![enter image description here](https://i.stack.imgur.com/e6cwG.jpg)
실제 사람이라면 Antoine이 모든 사람이 볼 수 있도록 웹에 게시 된 ID가 마음에 들지 않았 으면합니다. – QED
ID에서 데이터를 추출 하시겠습니까? MRZ에서 필요로하는 모든 데이터가 MRZ에서 찾을 수 있다고 생각합니다. 문제는 MRZ 인식입니다. 맞습니까? –
@Vitalik 당신 말이 맞아, 나는 MRZ의 내용을 알지 못했다. 답장을 보내 주셔서 감사합니다. MRZ 부분 만 찾는 아이디어는 MRZ 부분을 찾기 위해 사각형 탐지를 시도 할 계획입니다. 운동할까요? – 2vision2