Sie sind auf Seite 1von 4

public Object[] cropImageICAO(Bitmap inputImage)

{
// Converte a imagem passada para o formato utilizado pelo EMGU
Image<Bgr, Byte> image = new Image<Bgr, Byte>(inputImage);
// Realiza a deteco da face
detectFace(image);
// Calcula o ponto central entre os centros dos olhos
int eyeCenterPointX = (int)((BioICAOCaller.BioFace.eyeLeftX + BioICA
OCaller.BioFace.eyeRightX) / 2.0);
int eyeCenterPointY = (int)((BioICAOCaller.BioFace.eyeLeftY + BioICA
OCaller.BioFace.eyeRightY) / 2.0);
eyeCenterPoint = new Point(eyeCenterPointX, eyeCenterPointY);
// Calcula o ponto de origem, P0, para posicionar a caixa de crop
Object[] cropBoxData = calculatePointForCropBox(image);
HelpersLib.Util.SaveImage(HelpersLib.Util.convertBitmapToBitmapSourc
e(image.Bitmap), @"C:\Temp\SavedImg.bmp");
Image<Bgr, Byte> fullFrontalImage = CropImage(image, (Point) cropBox
Data[0], fullFrontalWidth, fullFrontalHeight);
Object[] result = new Object[2];
result[0] = fullFrontalImage.ToBitmap();
result[1] = cropBoxData[1];
return result;
}
private Object[] calculatePointForCropBox(Image<Bgr, Byte> image) {
Object[] result = new Object[2];
List<string> errorList = new List<string>();
/*
* Na pgina 28 do documento ISO/IEC 19794-5:2005(E) tem o diagrama co
m as caractersticas geomtricas de uma imagem de face
* full frontal. Neste diagrama esto descritas as dimenses A, B, AA, B
B, CC, DD, onde:
* A - Largura da imagem
* B - Altura da imagem
* AA - Posio da linha vertical que passa pelo centro do nariz e do ce
ntro da boca
* BB - Distncia da linha horizontal que passa pelos olhos at o fundo
da imagem
* CC - Largura da cabea
* DD - Altura da cabea
*
* Aqui definiremos outras duas dimenses:
* EE - Distncia da linha horizontal que passa pelos olhos at o topo d
a cabea
* FF - Distncia do topo da cabea at o topo da imagem - Esta distncia pa
ra garantir que toda a cabea est dentro da imagem
*/
// Identifica aonde est o topo da cabea
Point ptTopHead = new Point();
ptTopHead = GetTopHead(image);
// Desenha um crculo no ponto encontrado
if (debug)
image.Draw(new CircleF(ptTopHead, 2), new Bgr(Color.Red), 2);
// Como o topo da imagem a origem do eixo Y, a distncia do topo da ca
bea para o topo da imagem ser o valor do ponto
// encontrado no eixo Y
int FF = ptTopHead.Y;
// Pega os limites da face identificada
var faceData = BioICAOCaller.BioFace;
int A = fullFrontalWidth;
int B = fullFrontalHeight;
// Old Luis rect rosto atravs do BioIcao.
//int CC = faceData.faceWidth;
//int DD = faceData.faceHeight;
// New utiliza como referencia o rect rosto do OpenCV.
int CC = CVRectFace.Width;
//int DD = CVRectFace.Height;
int DD = (CVRectFace.Y + CVRectFace.Height) - ptTopHead.Y;
image.Draw(new Rectangle(ptTopHead.X, 0, 1, ptTopHead.Y), new Bgr(Co
lor.Red), 2);

// Old calculos com base em BioICAO
//int faceTop = faceData.faceTop;
//int faceBottom = faceTop + DD;
//int faceLeft = faceData.faceLeft;
//int faceRight = faceLeft + CC;
// New calculos com base no OpenCV
int faceTop = CVRectFace.X;
int faceBottom = faceTop + DD;
int faceLeft = CVRectFace.Y;
int faceRight = faceLeft + CC;
image.Draw(new Rectangle(CVRectFace.X, CVRectFace.Y, CVRectFace.Widt
h, CVRectFace.Height), new Bgr(Color.Red), 2);
image.Draw(new Rectangle(faceData.faceLeft, faceData.faceTop, faceDa
ta.faceWidth, faceData.faceHeight), new Bgr(Color.Green), 2);
int EE = eyeCenterPoint.Y - FF;
Point nosePoint = new Point(faceData.noseX, faceData.noseY);
Point mouthPoint = new Point(faceData.mouthX, faceData.mouthY);

// Pela norma ICAO, a distncia AA definida como a linha vertical que
passa pelo ponto, no eixo X, definido pela
// mdia dos pontos X do nariz e da boca
int AA = (nosePoint.X + mouthPoint.X) / 2;
int BB = B - eyeCenterPoint.Y;
// A partir deste ponto vamos analisar possveis inconsistncias e anota
r na lista de erros o que for encontrado
// A razo entre a altura da cabea (DD) e a altura da imagem (B) dever
ser de no mnimo 0,7 e no mximo 0,8
double DD_B_ratio = ((double)DD) / ((double)B);
if (DD_B_ratio < 0.7)
errorList.Add("A razo entre a altura da cabea (DD) e a altura da i
magem (B) menor que 0,7");
else if (DD_B_ratio > 0.8)
errorList.Add("A razo entre a altura da cabea (DD) e a altura da i
magem (B) maior que 0,8");
// A razo entre a largura da imagem (A) e a largura da cabea (CC) deve
ser de no mnimo 1,4 e no mximo 2,0
double A_CC_ratio = ((double)A) / ((double)CC);
if (A_CC_ratio < 1.4)
errorList.Add("A razo entre a largura da imagem (A) e a largura d
a cabea (CC) menor que 1,4");
else if (A_CC_ratio > 2.0)
errorList.Add("A razo entre a largura da imagem (A) e a largura d
a cabea (CC) maior que 2,0");
// Calcular a razo do ponto central dos olhos em relao a largura da ima
gem, sabendo que o ponto AA o ponto
// central da imagem
// Primeiro, calcular o ponto X mais a esquerda da imagem, sabendo q
ue AA o ponto central e a largura 420 pixels
int cropBoxPointX = AA - (A / 2);
if (cropBoxPointX < 0)
cropBoxPointX = 0;
double EyeMidPointRatio = ((double)(eyeCenterPoint.X - cropBoxPointX
)) / ((double)A);
if (EyeMidPointRatio < 0.45)
errorList.Add("A posio do ponto central entre o centro dos olhos e
m relao largura da imagem menor que 0,45");
else if (EyeMidPointRatio > 0.55)
errorList.Add("A posio do ponto central entre o centro dos olhos e
m relao largura da imagem maior que 0,55");
// Calcular a coordenada vertical do ponto mdio dos olhos para o enqu
adramento da imagem
if (FF < topHeadGap)
errorList.Add("A distncia do topo da cabea para o topo da imagem i
nferior a " + topHeadGap + " pixels");
else if (FF > topHeadGap)
FF = topHeadGap;
// Neste ponto j sabemos que o valor de FF est definido
// Determinar a posio dos olhos no eixo Y
int distanceEyesToTop = EE + FF;
int cropBoxMinY = (int) Math.Ceiling(0.3 * (double)B);
int cropBoxMaxY = (int) Math.Floor(0.5 * (double)B);
// Se os olhos estiverem muito pra cima na imagem, recalcula a distnc
ia dos olhos para o topo para abaixar a face
// Essa condio no um erro de identificao, j que a face pode ser descida
m problemas, desde que dentro da faixa definida
if (distanceEyesToTop < cropBoxMinY)
distanceEyesToTop = cropBoxMinY;
// Se os olhos estiverem muito para baixo, ajustar a posio dos olhos e
m funo do limite de 50%. Neste caso deve-se verificar
// depois se h algum espao em branco entre o topo da foto e o topo da
imagem para sinalizar caso a cabea no possa ser vista
// por completo. Do contrrio nenhum alerta ser gerado.
if (distanceEyesToTop > cropBoxMaxY)
{
distanceEyesToTop = cropBoxMaxY;
int blankSpace = distanceEyesToTop - EE;
if (blankSpace <= 0)
errorList.Add("O topo da cabea pode ter sido cortado. Verific
ar se o cidado est usando chapu ou bon");
}
int cropBoxPointY = eyeCenterPoint.Y - distanceEyesToTop;
if (cropBoxPointY < 0)
cropBoxPointY = 0;
// Em uma situao extrema, poderia acontecer de a posio dos olhos ficar a
baixo da faixa de 30% aps o reposicionamento da caixa
// de crop. Verificar se isso aconteceu e sinalizar um erro nessa si
tuao
if ((eyeCenterPoint.Y - cropBoxPointY) < cropBoxMinY)
{
string erro = "No possvel enquadrar a imagem dentro da margem mnima
de 30% em relao ao topo da imagem";
errorList.Add(erro);
}
// As coordenadas do ponto P0 j foram calculadas, gerar o ponto e ret
ornar ele junto com as mensagens de erro
Point p0 = new Point(cropBoxPointX, cropBoxPointY);
result[0] = p0;
result[1] = null;
if (errorList.Count != 0)
{
string[] finalErrorList = errorList.ToArray();
result[1] = finalErrorList;
}
return result;
}

Das könnte Ihnen auch gefallen