/**
* @author Igor
*/
import java.util.*;
import javax.microedition.lcdui.*;
class CTonsCinza {
private int LargTotal, AltTotal,
LargImg, AltImg;
byte [][]TonsCinza;
public int Larg, Alt;
CTonsCinza(Image img){
int []raw = new int[img.getHeight()*img.getHeight()];
img.getRGB(raw, 0, img.getWidth(), 0, 0, img.getWidth(), img.getHeight());
// implementar
Larg = img.getWidth();
Alt = img.getHeight();
TonsCinza = new byte[Larg][Alt];
for (int i=0; i<Alt; i++){
for (int j=0; j<Alt; j++){
TonsCinza[i][j] = (byte)(raw[i*Larg+j]& 0x00000FF);
}
}
}
Image SaveImage() {
byte []raw = new byte[Larg*Alt];
int ponteiro=0;
for (int i=0; i<Alt; i++){
for (int j=0; j<Alt; j++){
raw[ponteiro++]=TonsCinza[i][j];
raw[ponteiro++]=TonsCinza[i][j];
raw[ponteiro++]=TonsCinza[i][j];
}
}
Image img = Image.createImage(raw, 0, raw.length);
return img;
}
};
class TPonto {
int x, y;
};
class TParamsAI {
CTonsCinza TCImgSrc;
TPonto RefTarja;
//Distância da parte de cima da tarja para uma faixa de referência de um pixel de altura,
//que é usada para ver a média da luminosidade logo acima da tarja
int DistFaixaRef;
//largura da faixa de referência
int LargFaixaRef;
//Utilizada para determinar a luminosidade máxima de um pixel para que ele seja considerado
// como um pixel do identificador. Esta luminosidade máxima é:
// Limiar=Media-ParamsAI.DifMinMediaFaixaRef, onde Media é a média de luminosidade da faixa
// de referência.
int DifMinMediaFaixaRef;
//Largura máxima em pixels do identificador. Utilizada para definir a região de busca de
// pixels de identificador
int LargIdentificador;
//Análogo à LargIdentificador
int AltIdentificador;
//deslocamento para à esquerda em pixels do início da região de busca dos pixels de identificador.
// O início da região de busca fica: xIni=ParamsAI.RefTarja.x-ParamsAI.XIniParaRefTarja
int XIniParaRefTarja;
// yIni=ParamsAI.RefTarja.y-ParamsAI.YIniParaRefTarja
int YIniParaRefTarja;
//Define o maior gap em número de pixels que pode haver para que não se considere que o
//identificador está quebrado. Se houve um gap maior que o definido, considera-se que
//o identificador acabou. Este gap é de altura de pixels, considerando que o processamento
//é de cima para baixo
int MaiorDistSemPixelsIdentificador;
//Usado para determinar o número mínimo de pixels já processados com luminosidade abaixo do limiar
//para se considerar que já foram processados pixels de identificador
int NumMinPixelsIdentificador;
//Limiar que define se um identificador tem 1 ou 2 "andares"
int LimiarAlturaIdentificador;
//Limiar que define se um identificador é inclinado ou não
int LimiarInclinacaoidentificador;
//Limiar que define a proporção entre a largura mediana da parte de cima e de baixo
//do identificador
float LimiarLargLinhasIdentificador;
//Retorno
int Alt;
float Inclinacao;
int MaiorLargLinha;
float RelacaoMedianasLargurasEncEmb;
int ValorCedula;
public TParamsAI(Image img) {
TCImgSrc = new CTonsCinza(img);
}
};
class TBordasColunas {
Vector [] Bordas;
int NumColunas;
TBordasColunas(int numColunas) {
NumColunas = numColunas;
Bordas = new Vector[NumColunas];
for (int n = 0; n < NumColunas; n++) {
Bordas[n] = new Vector();
}
}
};
class TConjuntoMeioBordas {
TConjuntoMeioBordas(int numColunas){
NumColunas = numColunas;
VectorMeioBordas = new Vector[NumColunas];
for (int n=0; n<NumColunas; n++)
VectorMeioBordas[n]=new Vector();
}
Vector VectorMeioBordas[];
int NumColunas;
};
class TVectorInt extends Vector{
TVectorInt(){
super();
}
Integer elementoEm(int indice){
return (Integer)(elementAt(indice));
}
}
class TTarja {
int X;
int UltYMeio;
int PriYEnc;
boolean Ativa(int x){
return ((x-X)==VetorAlturas.size());
}
Vector VetorAlturas;
};
class TParamsABT {
//Altura mínima que uma faixa escura pode ter para ser considerada tarja
int AltMinTarja;
//Altura máxima que uma faixa escura pode ter para ser considerada tarja
int AltMaxTarja;
//distância horizontal máxima entre faixas escuras para serem consideradas tarja
int DistMaxTarjas;
//Largura mínima de uma faixa escura para ser considerada tarja
int LargMinTarja;
//Largura mínima de uma faixa escura para ser considerada tarja
int LargMaxTarja;
//Define o desvio médio máximo para que uma faixa seja considerada a tarja.
//Este desvio é a média da diferença de altura de cada coluna da faixa para a média das alturas
double DesvioMax;
boolean AchouTarja;
TPonto RefTarja;
//Vetor com locais de bordas que são analizadas para saber se são bordas da tarja
TBordasColunas BordasColunas;
TConjuntoMeioBordas ConjuntoMeioBordas;
Vector VectorTarja;
};
class TParamsMLT{
CTonsCinza TCImgSrc;
//Menor luminosidade que um pixel acima da tarja pode ter
int ClaroMin;
//Maior luminosidade que um pixel da tarja pode assumir
byte EscuroMax;
//Fator que define a região de busca da tarja. Multiplica-se a largura da imagem por este fator
float PropYIni;
float PropXFim;
//Altura mínima em pixels da coluna de pixels claros que devem estar na região encima de uma tarja
int AltMinClaro;
//Altura mínima em pixels da coluna de pixels claros que devem estar na região dentro da tarja
int AltMinEscuro;
//Número mínimo de pixels claros acima do pixel corrente
//para se considerar que está no estado CLARO
int NumMinClaro;
//Número mínimo de pixels escuros acima do pixel corrente
//para se considerar que está no estado ESCURO
int NumMinEscuro;
//retorno
public TBordasColunas BordasColunas;
public TParamsMLT(Image img) {
TCImgSrc = new CTonsCinza(img);
}
public void setBordasColunas (int size){
BordasColunas = new TBordasColunas(size);
}
};
class TParamsRC {
TParamsMLT ParamsMLT;
TParamsABT ParamsABT;
TParamsAI ParamsAI;
public TParamsRC(Image img) {
ParamsMLT = new TParamsMLT(img);
ParamsABT = new TParamsABT();
ParamsAI = new TParamsAI(img);
}
};
class TBorda {
int Y;
int TipoBorda;
};
class TMeioBordas {
int Y1, Y2, yMeio, Altura;
void Inicializa(int y1, int y2) {
Y1 = y1;
Y2 = y2;
yMeio = (Y1 + Y2) / 2;
Altura = Y2 - Y1;
}
};
class ImageProcessor {
static final int BORDA_ESCURO_CLARO = 0,
BORDA_CLARO_ESCURO = 1;
static public TParamsRC ParamsRC;
static public void initializeImage(Image img) {
ParamsRC = new TParamsRC(img);
CarregaParamsReconheceCedula();
}
static public void CarregaParamsReconheceCedula(){
ParamsRC.ParamsMLT.ClaroMin=130;
ParamsRC.ParamsMLT.EscuroMax=95;
ParamsRC.ParamsMLT.PropYIni=300;
ParamsRC.ParamsMLT.PropXFim=600;
ParamsRC.ParamsMLT.AltMinClaro=4;
ParamsRC.ParamsMLT.AltMinEscuro=4;
ParamsRC.ParamsMLT.NumMinClaro=3;
ParamsRC.ParamsMLT.NumMinEscuro=3;
ParamsRC.ParamsABT.AltMinTarja=15;
ParamsRC.ParamsABT.AltMaxTarja=25;
ParamsRC.ParamsABT.DistMaxTarjas=1;
ParamsRC.ParamsABT.LargMinTarja=15;
ParamsRC.ParamsABT.LargMaxTarja=70;
ParamsRC.ParamsABT.DesvioMax=30;
ParamsRC.ParamsAI.DistFaixaRef=2;
ParamsRC.ParamsAI.LargFaixaRef=4;
ParamsRC.ParamsAI.DifMinMediaFaixaRef=25;
ParamsRC.ParamsAI.LargIdentificador=20;
ParamsRC.ParamsAI.AltIdentificador=32;
ParamsRC.ParamsAI.XIniParaRefTarja=2;
ParamsRC.ParamsAI.YIniParaRefTarja=3;
ParamsRC.ParamsAI.LimiarAlturaIdentificador=13;
ParamsRC.ParamsAI.LimiarInclinacaoidentificador=1;
ParamsRC.ParamsAI.MaiorDistSemPixelsIdentificador=3;
ParamsRC.ParamsAI.NumMinPixelsIdentificador=10;
ParamsRC.ParamsAI.LimiarLargLinhasIdentificador=2000;
}
//---------------------------------------------------------------------------
//Localiza e mostra a tarja.
//Executa o processamento da esquerda para direita, de cima para baixo.
//Para cada coluna, verifica nos últimos AltMinClaro pixels quantos pixels são considerados
// como pixels claros, e quantos são considerados escuros. Os pixels são comparados com ClaroMin e
//EscuroMax. Se o número de pixels claros for maior que NumMinClaro, a iteração é colocada no
//estado CLARO. Analogamente, se o número de pixels escuros for maior que NumMinEscuros, a iteração
//é colocada no estado ESCURO. Quando há transição do estado CLARO para ESCURO, este ponto é
//considerado borda superior da tarja. Quando há transição de ESCURO para CLARO, este ponto
//é considerado a parte de baixo da tarja.
static void MostraLimiteTarja(TParamsMLT ParamsMLT){
int x, y;
int yBorda;
final int NADA = 0,
CLARO = 1,
ESCURO = 2;
int estado;
byte [][]ImgSrc = ParamsMLT.TCImgSrc.TonsCinza;
int YIni=(int)(ParamsMLT.TCImgSrc.Alt*ParamsMLT.PropYIni);
int XFim=(int)(ParamsMLT.TCImgSrc.Larg*ParamsMLT.PropXFim);
int ContaClaro, ContaEscuro;
TBorda BordaTemp = new TBorda();
ParamsMLT.BordasColunas=new TBordasColunas(XFim);
for (x=0; x<XFim; x++) {
estado = NADA;
ContaClaro = ContaEscuro = 0;
//Inicialização do processamento da coluna. É executado por poucos pixels
for (y = YIni; y < YIni + ParamsMLT.AltMinClaro; y++) {
if (ImgSrc[y][x] >= ParamsMLT.ClaroMin) {
ContaClaro++;
}
if (ImgSrc[y][x] <= ParamsMLT.EscuroMax) {
ContaEscuro++;
}
}
for (y = YIni + ParamsMLT.AltMinClaro; y < ParamsMLT.TCImgSrc.Alt; y++) {
//Atualiza a quantidade de pixels claros e de escuros que estão nos últimos AltMinClaro
//pixels da coluna
if ((ImgSrc[y - ParamsMLT.AltMinClaro][x] >= ParamsMLT.ClaroMin) && ContaClaro >= 1) {
ContaClaro--;
}
if (ImgSrc[y][x] >= ParamsMLT.ClaroMin) {
ContaClaro++;
}
if ((ImgSrc[y - ParamsMLT.AltMinClaro][x] <= ParamsMLT.EscuroMax) && ContaEscuro >= 1) {
ContaEscuro--;
}
if (ImgSrc[y][x] <= ParamsMLT.EscuroMax) {
ContaEscuro++;
}
switch (estado) {
case NADA:
//se existe uma quantidade suficiente de pixels claros nos últimos pixels da coluna
// então entra no estado CLARO
if (ContaClaro >= ParamsMLT.NumMinClaro) {
estado = CLARO;
yBorda = y - ParamsMLT.NumMinEscuro;
BordaTemp.Y = yBorda;
BordaTemp.TipoBorda = BORDA_ESCURO_CLARO;
ParamsMLT.BordasColunas.Bordas[x].addElement(BordaTemp);
}
break;
case CLARO:
if (ContaEscuro >= ParamsMLT.NumMinEscuro) {
estado = ESCURO;
yBorda = y - ParamsMLT.NumMinClaro;
//Se estava no estado CLARO e está no ESCURO então foi localizada a parte de cima
// da borda desta coluna
BordaTemp.Y = yBorda;
BordaTemp.TipoBorda = ImageProcessor.BORDA_CLARO_ESCURO;
ParamsMLT.BordasColunas.Bordas[x].addElement(BordaTemp);
}
break;
case ESCURO:
if (ContaEscuro < ParamsMLT.NumMinEscuro) {
if (ContaClaro >= ParamsMLT.NumMinClaro) {
estado = CLARO;
yBorda = y - ParamsMLT.NumMinEscuro;
//Se estava no estado ESCURO e está no CLARO então foi localizada a parte de baixo
// da borda desta coluna
BordaTemp.Y = yBorda;
BordaTemp.TipoBorda = BORDA_ESCURO_CLARO;
ParamsMLT.BordasColunas.Bordas[x].addElement(BordaTemp);
} else {
estado = NADA;
}
}
break;
}
}
}
}
//---------------------------------------------------------------------------
static void PreparaSelecionaTarja(TParamsABT ParamsABT) {
int x;
int n, m;
boolean Adicionou;
TMeioBordas MeioBordasTemp;
for (x = 0; x < ParamsABT.ConjuntoMeioBordas.NumColunas; x++) {
for (m = 0; m < ParamsABT.ConjuntoMeioBordas.VectorMeioBordas[x].size(); m++) {
Adicionou = false;
MeioBordasTemp = (TMeioBordas)ParamsABT.ConjuntoMeioBordas.VectorMeioBordas[x].elementAt(m);
for (n = 0; n < ParamsABT.VectorTarja.size(); n++) {
TTarja current = (TTarja)ParamsABT.VectorTarja.elementAt(n);
if ( current.Ativa(x) ) {
if ( Math.abs(current.UltYMeio-MeioBordasTemp.yMeio) <= ParamsABT.DistMaxTarjas) {
current.VetorAlturas.addElement(new Integer(MeioBordasTemp.Altura));
current.UltYMeio = MeioBordasTemp.yMeio;
Adicionou = true;
}
}
}
if (!Adicionou) {
TTarja tempTarja = new TTarja();
tempTarja.X = x;
tempTarja.UltYMeio = MeioBordasTemp.yMeio;
tempTarja.PriYEnc = MeioBordasTemp.Y1;
tempTarja.VetorAlturas.addElement(new Integer(MeioBordasTemp.Altura));
ParamsABT.VectorTarja.addElement(tempTarja);
}
}
}
}
//---------------------------------------------------------------------------
static void SelecionaTarja(TParamsABT ParamsABT) {
int n, nMenorX, m, MenorX;
double soma, desvio, media;
PreparaSelecionaTarja(ParamsABT);
MenorX = 0xFFFFFF;
nMenorX = -1;
ParamsABT.AchouTarja = false;
for (n = 0; n < ParamsABT.VectorTarja.size(); n++) {
TTarja currentTarja = (TTarja)(ParamsABT.VectorTarja.elementAt(n));
if ((currentTarja.VetorAlturas.size() <= ParamsABT.LargMaxTarja) &&
(currentTarja.VetorAlturas.size() >= ParamsABT.LargMinTarja)) {
soma = 0;
//tira a média da altura de cada coluna da possível tarja
for (m = 0; m < currentTarja.VetorAlturas.size(); m++) {
soma += ((Integer)(currentTarja.VetorAlturas.elementAt(m))).intValue();
}
media = soma / currentTarja.VetorAlturas.size();
//tira o desvio padrão
soma = 0;
for (m = 0; m < currentTarja.VetorAlturas.size(); m++) {
soma = Math.abs(media - ((Integer)currentTarja.VetorAlturas.elementAt(m)).intValue() );
}
desvio = soma / currentTarja.VetorAlturas.size();
if (desvio < ParamsABT.DesvioMax) {
if (currentTarja.X < MenorX) {
MenorX = currentTarja.X;
nMenorX = n;
}
}
}
}
if (nMenorX != -1) {
TTarja tarja = ((TTarja)(ParamsABT.VectorTarja.elementAt(nMenorX)));
ParamsABT.RefTarja.x = tarja.X;
ParamsABT.RefTarja.y = tarja.PriYEnc;
ParamsABT.AchouTarja = true;
}
}
//---------------------------------------------------------------------------
static void AnalizaBordasTarja(TParamsABT ParamsABT) {
int x, n;
int YMedio;
int NumColunas = ParamsABT.BordasColunas.NumColunas;
ParamsABT.ConjuntoMeioBordas = new TConjuntoMeioBordas(NumColunas);
int dif;
Vector BordasTemp = new Vector();
TMeioBordas MeioBordasTemp = new TMeioBordas();
for (x = 0; x < NumColunas; x++) {
BordasTemp = ParamsABT.BordasColunas.Bordas[x];
for (n = 1; n < BordasTemp.size(); n++) {
TBorda bordaEmbaixo = (TBorda)(BordasTemp.elementAt(n)),
bordaEncima = (TBorda)(BordasTemp.elementAt(n-1));
dif = bordaEmbaixo.Y - bordaEncima.Y;
if ((bordaEmbaixo.TipoBorda == ImageProcessor.BORDA_ESCURO_CLARO) &&
(bordaEncima.TipoBorda == ImageProcessor.BORDA_CLARO_ESCURO) &&
(dif >= ParamsABT.AltMinTarja) && (dif <= ParamsABT.AltMaxTarja)) {
MeioBordasTemp.Inicializa(bordaEncima.Y, bordaEmbaixo.Y);
ParamsABT.ConjuntoMeioBordas.VectorMeioBordas[x].addElement(MeioBordasTemp);
}
}
}
SelecionaTarja(ParamsABT);
/*
if (ParamsABT.AchouTarja) {
ImgDest[ParamsABT.RefTarja.y][ParamsABT.RefTarja.x].SetMagenta();
ImgDest[ParamsABT.RefTarja.y + 1][ParamsABT.RefTarja.x].SetMagenta();
ImgDest[ParamsABT.RefTarja.y][ParamsABT.RefTarja.x + 1].SetMagenta();
ImgDest[ParamsABT.RefTarja.y + 1][ParamsABT.RefTarja.x + 1].SetMagenta();
}
*/
}
static byte MediaFaixa(TParamsAI ParamsAI) {
int x, y, xIni, xFim, soma;
byte [][]ImgSrc = ParamsAI.TCImgSrc.TonsCinza;
xIni = ParamsAI.RefTarja.x;
xFim = xIni + ParamsAI.LargFaixaRef;
y = ParamsAI.RefTarja.y - ParamsAI.DistFaixaRef;
soma = 0;
for (x = xIni; x < xFim; x++) {
soma += ImgSrc[y][x];
}
return (byte)(soma*1.0/ParamsAI.LargFaixaRef);
}
static void sort(int [] numbers){
boolean sorted = false;
while (!sorted){
sorted = true;
for (int i=0; i<(numbers.length-1); i++){
if (numbers[i]>numbers[i+1]){
sorted = false;
int temp = numbers[i];
numbers[i]=numbers[i+1];
numbers[i+1]=temp;
}
}
}
}
static float RetornaRelacaoMedianasLargurasEncEmb(int []VetorLarguras, int comeco, int fim){
int alt = fim - comeco;
int [] vetor = new int [alt+1];
int MetadeAltura = alt / 2;
int QuartoAltura = (int)(alt*1.0/4);
int Larguras[] = new int[2];
for (int n=0; n < 2; n++) {
// novo codigo -----------------------------
int j=0;
for (int i=comeco; i<MetadeAltura; i++){
vetor[j] = VetorLarguras[comeco+n*MetadeAltura+i];
j++;
}
sort(vetor);
//------------------------------------------
/* codigo original
memcpy(vetor, VetorLarguras + comeco + n * MetadeAltura, MetadeAltura * sizeof(int));
qsort(vetor, MetadeAltura, sizeof(int), ComparaInteiro);
*/
Larguras[n] = vetor[QuartoAltura];
}
return (float)(Larguras[0] * 1.0 / Larguras[1]);
}
//---------------------------------------------------------------------------
static void AnalizaIdentificador(TParamsAI ParamsAI) {
int x, y;
int xIni, xFim, yIni, yFim;
int YEnc, YEmb, LargLinha, MaiorLargLinha;
int XEsq, XDir,
UltXEnc=0, UltXEmb=0; /// Iniciados apenas para tirar o error warning
int NumLinha, UltYComLinha, NumPixelsIdentificador;
int [] VetorLarguras;
boolean AchouLinha;
byte [][]ImgSrc = ParamsAI.TCImgSrc.TonsCinza;
xIni = ParamsAI.RefTarja.x - ParamsAI.XIniParaRefTarja;
xFim = xIni + ParamsAI.LargIdentificador;
yFim = ParamsAI.RefTarja.y - ParamsAI.YIniParaRefTarja;
yIni = yFim - ParamsAI.AltIdentificador;
int TamVetLarguras = yFim - yIni + 1;
VetorLarguras = new int[TamVetLarguras];
for (int i=0; i<VetorLarguras.length; i++)
VetorLarguras[i]=0;
byte Media = MediaFaixa(ParamsAI);
byte Limiar = (byte)(Media - ParamsAI.DifMinMediaFaixaRef);
YEnc = 0;
YEmb = -1;
MaiorLargLinha = 0;
NumLinha = 0;
NumPixelsIdentificador = 0;
UltYComLinha = -1;
for (y = yFim; y > yIni; y--) {
XEsq = -1;
XDir = 0;
AchouLinha = false;
for (x = xIni; x < xFim; x++) {
if (ImgSrc[y][x] < Limiar) {
if (YEmb == -1) {
YEmb = y;
}
YEnc = y;
if (XEsq == -1) {
XEsq = x;
}
XDir = x;
//se for a primeira linha
if (NumLinha == 0) {
UltXEmb = x;
}
UltXEnc = x;
AchouLinha = true;
NumPixelsIdentificador++;
}
}
LargLinha = XDir - XEsq;
VetorLarguras[y - yIni] = LargLinha;
if (LargLinha > MaiorLargLinha) {
MaiorLargLinha = LargLinha;
}
if (AchouLinha) {
NumLinha++;
UltYComLinha = y;
} else {
if ((UltYComLinha != -1) &&
((UltYComLinha - y) >= ParamsAI.MaiorDistSemPixelsIdentificador) &&
(NumPixelsIdentificador > ParamsAI.NumMinPixelsIdentificador)) {
break;
}
}
}
ParamsAI.RelacaoMedianasLargurasEncEmb =
RetornaRelacaoMedianasLargurasEncEmb(VetorLarguras, YEnc - yIni, YEmb - yIni);
ParamsAI.Alt = YEmb - YEnc;
ParamsAI.Inclinacao = (float)((UltXEnc - UltXEmb)*1.0/ParamsAI.Alt);
ParamsAI.MaiorLargLinha = MaiorLargLinha;
Identifica(ParamsAI);
}
//---------------------------------------------------------------------------
static void ReconheceCedula(TParamsRC ParamsRC) {
MostraLimiteTarja(ParamsRC.ParamsMLT);
ParamsRC.ParamsABT.BordasColunas = ParamsRC.ParamsMLT.BordasColunas;
AnalizaBordasTarja(ParamsRC.ParamsABT);
if (ParamsRC.ParamsABT.AchouTarja) {
ParamsRC.ParamsAI.RefTarja = ParamsRC.ParamsABT.RefTarja;
ParamsRC.ParamsAI.TCImgSrc = ParamsRC.ParamsMLT.TCImgSrc;
AnalizaIdentificador(ParamsRC.ParamsAI);
}
}
public static void process(Image img){
ParamsRC.ParamsMLT.TCImgSrc = new CTonsCinza(img);
initializeImage(img);
ReconheceCedula(ParamsRC);
/* output block --------------
if (ParamsRC.ParamsABT.AchouTarja) {
Status("Reconhece Cédula: " + FormatFloat("###,##0.00", (fim - comeco) * PeriodoContador) +
" milisegundos, Cédula: R$ " + IntToStr(ParamsRC.ParamsAI.ValorCedula));
} else {
Status("Não achou tarja");
}
*/
}
static void Identifica(TParamsAI ParamsAI){
if (ParamsAI.Inclinacao>ParamsAI.LimiarInclinacaoidentificador){
ParamsAI.ValorCedula=2;
} else {
if (ParamsAI.Alt>ParamsAI.LimiarAlturaIdentificador){
if (ParamsAI.RelacaoMedianasLargurasEncEmb<ParamsAI.LimiarLargLinhasIdentificador){
ParamsAI.ValorCedula=5;
} else {
ParamsAI.ValorCedula=50;
}
} else {
ParamsAI.ValorCedula=10;
}
}
}
};