Recunoasterea Obiectelor Folosind Procesarea Imaginilor
Recunoașterea obiectelor folosind procesarea imaginilor
A. Procesarea imaginilor pentru recunoașterea amprentelor
1.Introducere
Tehnicile de prelucrare a imaginilor digitale: inceputul anilor 1920 (s-au transmis pentru prima oara imagini digitizate ale agentiilor de stiri prin cablu submarin intre New York si Londra).
Procesarea imaginilor este un domeniu al inteligentei artificiale care se ocupa cu reprezentarea, reconstituirea, clasificarea, recunoasterea si analiza imaginilor cu ajutorul calculatorului.
Majoritatea algoritmilor de viziune artificiala necesita folosirea unor algoritmi de procesare a imaginilor.
Example de metode:
imbunatatirea calitatii imaginilor (image enhancement) – prin transformarea imaginilor: punerea in evidenta a detaliilor ascunse/obscure, a trasaturilor de interes
compresia (reprezentare compacta a imginilor/secventelor pentru transmisie / stocare)
restaurarea (eliminarea elementelor de degradare cunoscute / modelabile)
extragerea de trasaturi (localizarea anumitor sabloane – ex: muchii, colturi, structuri complexe – obiecte)
Prelucrarea și analiza imaginilor s-a născut și dezvoltat datorită ideii și necesității de a înlocui observatorul uman cu un dispozitiv care să proceseze datele similar creierului uman. Procesul de prelucrare al imaginilor s-a dezvoltat datorită apariției unor soluții novatoare, ca în cazul imaginilor non-vizibile (imagini acustice, ultrasonore, radar).
Tehnologia digitală modernă a făcut posibilă prelucrarea semnalelor multidimensionale folosind sisteme care pot porni de la simple circuite digitale ajungând până la sisteme de calcul paralel avansat. Scopul acestei prelucrări poate fi împărțit în trei categorii:
• Procesarea Imaginilor: imagine intrare → imagine ieșire;
• Analiza imaginilor: imagine intrare → măsurări ieșire;
• Înterpretarea imaginilor: imagine intrare → descriere la nivel înalt ieșire
Prelucrarea imaginilor: atat intrarea cat si iesirea (rezultatul) sunt imagini. Aplicatii: sisteme de transmisie a imaginilor (cu tehnici de inlaturare a zgomotelor si compactare a datelor), imbunatatirea imaginilor subexpuse sau neclare (cu tehnici de imbunatatire a contrastului), modificarea drastica a imaginilor (schimbarea iluminarii, modificarea contururilor unor obiecte), crearea unei imagini noi dintr-un set de imagini existente (exemplu: in medicina, obtinerea reprezentarii unor organe interne din imagini cu raze x sau scintigrafice).
Recunoasterea formelor din imagini: producerea fie a unei descrieri a imaginii de intrare sau asignarea imaginii la o clasa particulara. Aplicatii: sistem de sortare a corespondentei (detecteaza si identifica cifrele codului postal de pe plic), sistem de diagnostic medical (detecteaza anumite anomalii de pe radiografii sau alte imagini medicale) etc.
2. Proiectarea aplicatiei
Se considera drept reprezentare a unei imagini un tablou bidimensional de numere intregi (pixeli). Valoarea fiecarui pixel descrie nivelul de stralucire sau culoarea acestuia. In cel mai simplu caz, al imaginilor binare, pentru reprezentarea fiecarui pixel este folosit un singur bit. In cazul imaginilor cu niveluri de gri, valoarea fiecarui pixel reprezinta stralucirea acestuia.
Cel mai comun format pentru aceste imagini are la baza reprezentarea pixelilor pe 8 biti. Astfel, gama de valori posibile este 0..255, 0 codificand culoarea negru, 255 alb, iar valorile intermediare reprezentand nuante (niveluri) de gri. In cazul imaginilor color, pot fi folosite diferite sisteme de culori (RGB, HSI, CMY etc.).
In modelarea matematică a problemei recunoașterii formelor există și abordări teoretice care eludează această ordine logică. De exemplu, abordarea cu metode matematice statistice a recunoașterii, face abstracție de incluziunea structurală a formelor în obiecte (cu forme complexe) și a obiectelor în imagini (conținand mai multe obiecte). Un exemplu semnificativ este metoda de recunoașterea statistică a imaginilor/obiectelor pe baza conținutului lor cromatic.
O amprentă este un șablon de crestături pe suprafața degetului. Fiecare individ are o amprentă unică. Unicitatea amprentei este exclusiv determinată de caracteristica crestăturilor locale. O creasta este definiat ca un singur segment de curbă și o vale este regiunea dintre două muchii adiacente.
Detalii cum ar fi tipul, orientarea și localizarea punctelor caracteristice sunt luate în considerare atunci când se efectuează extragerea punctelor caracteristice.
Amprentele digitale sunt cele mai vechi și cele mai utilizate pe scară largă sub formă de identificare biometrice.
In ciuda utilizarii pe scara larga a amprentelor digitale, nu există teorie statistică pe unicitatea punctelor caracteristice ale amprentei.
Imaginile de amprente digitale sunt rareori de calitate perfectă. Ele pot fi degradate din cauza variațiilor de boli de piele și afișări.
Identificarea amprentelor este un mecanism de identificare biometrica utilizata pe scară largă.
Recunoașterea și potrivirea amprentelor digitale a fost o problemă tipică care este foarte utila pentru a detecta identitatea. Aici instrumente de algoritm Matlab și de procesare a imaginilor sunt utilizate pentru a recunoaște și a compara cele două amprente.
Amprentele degetelor mâinii (le vom numi pe viitor simplu, „amprente”) sunt elementele cele mai comune atunci când vine vorba de identificarea umană – tuturor le este comună imaginea din filmele americane în care detectivii colectează amprentele de la scena crimei pentru a le trece ulterior printr-o bază de date. Metoda de identificare folosind amprentele degetelor mâinii (cunoscută și sub numele de dactiloscopie) chiar în aceasta constă: în prealabil, se realizează o bază de date cu subiecți pentru ca apoi să se compare datele colectate în urma unui anumit eveniment cu cele existente în respectiva bază de date, în vederea identificării unice din cadrul bazei de date a amprentei corespunzătoare și automat a identității persoanei suspectate de a fi prezentă la locul unui eveniment.
Lucrarea descrie procesul din spatele implementarii unui algoritm de recunoastere a unei amprente folosind nediud de programare Matlab. Algoritmul utilizat foloseste metoda compararii spectrelor frecventelor a doua amprente in urma unei analize spectrale. Se va construi o baza de date ce va contine o serie de amprente ce vor fi reprezentate sub forma vectoriala si normalizare astfel incat media acestora sa fie utilizata ca standard in procesul de comparatie. O data ce standardul a fost ales, se va ajusta deviatia si anume precizia cu care sistemul va reactiona ca urmare a recunoasterii amprentei.
Analiza pe Componente Principale (PCA)
De regulă, bazele de date folosite în experimentele de recunoaștere a fețelor conțin imagini de dimensiune foarte mare. O astfel de “risipă” de resurse, valabilă de altfel și în cazul semnalelor vocale sau al altor imagini naturale, conduce la o robustețe semnificativă, care permite receptarea corectă a informației transmise, chiar în condițiile în care aceasta este afecatată de zgomot, este distorsionată sau incompletă. Pe de altă parte, dimensiunile mari complică semnificativ implementarea practică a diverselor tehnici de procesare, cresc volumul de calcul și, în plus, necesită existența unui număr sporit de imagini în baza de date cu care se operează (dacă imaginile originale sunt văzute ca puncte într-un spațiu multidimensional, cu cât dimensiunea spațiului este mai mare, cu atât mai multe puncte sunt necesare pentru a asigura o “acoperire” mai bună a întregului spațiu, în vederea asigurării unei aproximări adecvate a densității reale de repartiție a tuturor punctelor reprezentând imagini valide de fețe umane). În acest context, se dovedesc utile tehnicile de compresie, folosite pentru a reduce dimensiunea datelor originale, în condițiile unor pierderi de informație (inevitabile) cât mai mici.
Una dintre cele mai cunoscute metode de compresie aparținând celei de a doua clase, denumită Analiza pe Componente Principale (Principal Component Analysis – PCA) sau transformata KarhunenLoeve.
”Materia primă” o constituie ansamblul imaginilor disponibile în baza de date, formate din matrici cu valori reale (eventual – binare). Fiecare astfel de matrice, presupusă de dimensiune (MxN), este mai întâi transformată într-un vector de aceeași lungime, prin concatenarea coloanelor corespunzătoare. Algoritmul de procesare presupune parcurgerea următorilor pasi:
f) Clasificarea imaginilor test presupune mai întâi determinarea „semnăturii” fiecărei imagini în raport cu subpațiul determinat anterior (și care depinde exclusiv de imaginile din setul de antrenare!) și găsirea acelei imagini din baza de date de antrenare a cărei semnătură este cea mai apropiată de semnătura imaginii de test. Aprecierea similitudinii dintre astfel de perechi de imagini se realizează folosind o metrică convenabil aleasă. Opțiunea uzuală este distanța Euclideană (L2), însă se pot utiliza și alte măsuri precum funcția de autocorelație, cosinusul unghiului dintre 2 vectori sau distanța Mahalanobis. Definițiile acestora se prezintă mai jos:
Principalul avantaj al metodei PCA constă în simplitatea sa. Există posibilitatea de a calcula vectorii proprii principali nu numai în variantă off-line prin procedura algebrică descrisă anterior ci și on-line, folosind anumite rețele neurale artificiale pentru a ajusta în mod iterativ valorile acestora, pe măsură ce se aplică date noi la intrare.
În cazul aplicării metodei PCA la recunoașterea fețelor, trebuie menționate și o serie de dezavantaje, care limitează performanțele sistemelor bazate pe acest instrument de analiză: – principalul dezavantaj constă în faptul că ignorarea componentelor care contribuie puțin la energia imaginilor originale nu conduce automat și la îmbunătățirea separării (discriminării) dintre diversele subclase de imagini aparținând unor persoane diferite (altfel spus, minimizarea erorii de reprezentare nu înseamnă neapărat îmbunătățirea performanțelor de clasificare!). Un exemplu intuitiv este prezentat în Fig. 1.8, care indică faptul că cele două clase pot fi separate comod efectuând proiecția pe componenta principală mai puțin semnificativă. – un alt dezavantaj al tehnicii PCA îl reprezintă caracterul global al acesteia, în sensul că matricea de convarianță (deci și valorile și vectorii proprii) este dedusă luând în considerare toate imaginile disponibile,
care pot să conțină o foarte mare variabilitate din punct de vedere al nivelului de iluminare, orientării, fundalului. Acest dezavantaj poate fi compensat pațial utilizând arhitecturi modulare, în care tehnica PCA se aplică pe subseturi de imagini care au caracteristici comune (de exemplu, se calculează seturi de vectori proprii distincți pentru clasa imaginilor reprezentând vederi frontale, respectiv vederi înclinate la ±30°, ±40°). De asemenea, se pot utiliza arhitecturi în care fiecare modul este “specializat” să recunoască numai imaginile reprezentând o aceeași persoană. – în cazul particular al analizei imaginilor reprezentând fețe, metoda PCA s-a dovedit extrem de sensibilă în raport cu normalizarea poziției acestora: translații pe orizontală/verticală cu numai câțiva pixeli, mici rotații sau variații de scală pot altera semnificativ „semnăturile” extrase și, în consecință, pot degrada performanțele de recunoaștere/autentificare. Ca urmare, este necesară o etapă (manuală sau automată) de normalizare a aspectului imaginilor, care să preceadă aplicarea propriu-zisă a PCA. Alternativ, au fost propuse variante ale metodei standard, care încearcă să compenseze acest dezavantaj prin filtrarea adecvată a imaginilor originale. În particular, uneori se preferă ignorarea proiecției de-a lungul primului vector propriu semnificativ, deoarece de regulă acesta este sensibil la nivelul global de iluminare al imaginilor.
IMPLEMENTARE
-Display.java
import java.awt.*;
import java.awt.image.PixelGrabber;
import java.awt.image.ImageObserver;
import java.awt.image.BufferedImage;
import java.util.Vector;
public class display {
/*
* Convert a pixel of array into a buffer image
*Accepts a vector of integer arrays as its elements
*Convert each of vector element to an Image object and
*stores it in an Image array and returns that array .
* w , h are width and heights of an image.
*/
public Image[] drawBehind(Vector v,int w,int h) {
Image[] temp = new Image[v.size()];
for (int a = 0; a < v.size(); a++)
temp[a] = arrayToImage((int[]) v.elementAt(a), w, h);
return temp;
}
public static Image arrayToImage(int[] a,int w,int h) {
BufferedImage b = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
b.setRGB(x, y,a[x + w * y]);
// b.setRGB(x, y,a[x + y * w]);
}
}
return toImage(b);
}
//Create an image from buffered image
/**
* Convert Buffered image to a normal image
*
* @param bufferedImage
* @return Normal Image
*/
public static Image toImage(BufferedImage bufferedImage) {
return Toolkit.getDefaultToolkit().createImage(bufferedImage.getSource());
}
}
-image.java
import java.awt.*;
import java.awt.event.*;
import java.awt.image.PixelGrabber;
import java.awt.image.ImageObserver;
import java.awt.image.BufferedImage;
import javax.swing.*;
import java.util.Vector;
import java.io.*;
import cern.colt.matrix.*;
import cern.colt.matrix.impl.DenseDoubleMatrix2D;
import cern.colt.matrix.linalg.Algebra;
import cern.colt.matrix.linalg.EigenvalueDecomposition;
public class image {
//image.java
static File[] imageFiles; // of all images we will be loading
int[] averageImage; // averageImage[i]=average value of i'th pixel over all images = sum[i]/NumOfImages
static int NumOfImages,w,h; //NumberOfImages,width and height
static Vector TrainingImageVector; //All images will be stored in this vector
static DoubleMatrix2D eigenVectCovMatrix;//EigenVector for the Covariance Matrix of diffImageMatrix
static DoubleMatrix2D diffImageMatrix; //Matrix representation of difference images [each column rep. 1 image]
static DoubleMatrix2D weightMatrix; // projection of (original images-averageImage) onto eigenfaces
static Vector diffImageVector; // Each vector element is an array of difference pixels.
static Vector EigenVector;
static Component component;
static double twoNorm[]; //TwoNorm of the projected image onto the weight matrix.
Image[] ImgA; //All actual images are stored in this array.
int smallestTwoNorm;
//WriteToFile writer;
/* Constructor of image class
String dr specifies the directory where all the images are stored
Component component is the frame on which all the images will be displayed
*/
public image(String dr,Component component)
{
File f = new File(dr);
imageFiles = f.listFiles();
this.component = component;
NumOfImages = imageFiles.length; // number of images in that directory
System.out.println("Total number of training images : "+NumOfImages);
diffImageVector = new Vector();
TrainingImageVector = loadImgsIntoVector();
averageImage = findAverageImage(TrainingImageVector);
// writer = new WriteToFile();
for (int a = 0; a < NumOfImages; a++)
diffImageVector.addElement(findDeviated((int[])TrainingImageVector.elementAt(a)));
diffImageMatrix = ConvertVectorIntoMatrix(diffImageVector);
// eigenVectCovMatrix = ConvertVectorIntoMatrix(EigenVector);
eigenVectCovMatrix = findEigenVector(diffImageMatrix);
EigenVector = ConvertMatrixIntoVector(eigenVectCovMatrix); //need in display class
normalizeColumns(eigenVectCovMatrix);
System.out.println("Normalized EigenvectorCovMatrix=\n");
printPartOfDoubleMatrix2D(eigenVectCovMatrix,10,3);
// END CHANGE
weightMatrix = project(diffImageMatrix);
// classify(ImgA[testImg-1]); //we are not using testImg number
// writer.writeEigenMatrix(weightMatrix);
}
public image(Component component){this.component=component;}
// Normalize (2-norm=1) all columns in m
private void normalizeColumns(DoubleMatrix2D m){
// for each column
// normalize the column, that is
// find the norm of the column
// divide column by the norm
for(int c=0;c<m.columns();c++){
double norm=0;
for(int r=0;r<m.rows();r++)norm=norm+(m.get(r,c)*m.get(r,c));
norm=Math.sqrt(norm);
for(int r=0;r<m.rows();r++)m.set(r,c,m.get(r,c)/norm);
}
}
public void detectImage(String fileName){
classify(loadImageFromFile(fileName));
}
/**
* Place each image into an integer array and stores that array in vector and returns that vector
* Also stores raw images in array ImgA
*/
public Vector loadImgsIntoVector() {
Vector imageVec = new Vector();
ImgA = new Image[NumOfImages];
for (int i = 0; i < imageFiles.length; i++) {
//Get all the images in an array
ImgA[i] = loadImageFromFile(imageFiles[i].getAbsolutePath());
imageVec.addElement(grabPixels(ImgA[i]));
System.out.println(imageVec.size());
System.out.println(imageFiles.length);
}
return imageVec;
}
/**
* Load the image specified by filename
*
* @param fileName Description of the Parameter
* @return Description of the Return Value
*/
public Image loadImageFromFile(String fileName) {
Image img = Toolkit.getDefaultToolkit().getImage(fileName);
try {
MediaTracker tracker = new MediaTracker(component);
tracker.addImage(img, 0);
tracker.waitForID(0);
} catch (Exception e) {
System.out.println("Cant load image file " + fileName);
System.exit(0);
}
System.out.println(fileName);
System.out.println("w=" + img.getWidth(null) + "h=" + h);
return img;
}
/*
* Return an array of the pixels from image i
* pixel x,y gets stored in the width*y+x position of the array
*/
public static int[] grabPixels(Image i) {
w = i.getWidth(null);
h = i.getHeight(null);
System.out.println("w=" + w + "h=" + h);
int[] pixels = new int[w * h];
PixelGrabber pg = new PixelGrabber(i, 0, 0, w, h, pixels, 0, w);
try {
pg.grabPixels();
} catch (InterruptedException e) {
System.err.println("interrupted waiting for pixels!");
System.exit(0);
}
if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
System.err.println("image fetch aborted or errored");
System.exit(0);
}
return pixels;
}
/*
* @param v a vector of integer arrays, each with the same length
* @return an array a such that a[i]'s the average of the i'th integer in all arrays in v
*/
public int [] findAverageImage(Vector v){
if(v.size()==0)return null;
int [] temp=(int [])v.elementAt(0);
int [] avg=new int[temp.length];
for(int i=0;i<v.size();i++){
temp=(int [])v.elementAt(i);
// Add i'th array to avg
for(int j=0;j<temp.length;j++)avg[j]+=temp[j];
}
// So far avg[i] is the sum of all the i entries in each array in v
for(int i=0;i<avg.length;i++)avg[i]=avg[i]/v.size() ;
int temp1[] = (int[])v.elementAt(1);
for(int i =0;i<10;i++)System.out.println(temp1[i]);
return avg;
}
/* Converts a single dimension array to a matrix with 1 column*/
public DoubleMatrix2D ConvertArrayToMatrix(int[] temp) {
DoubleMatrix2D tempMtrx;
tempMtrx = new DenseDoubleMatrix2D(w * h, 1);
for (int row = 0; row < temp.length; row++) {
tempMtrx.set(row, 0, temp[row]);
}
return tempMtrx;
}
/**
* For each integer representation of an image in all, we compute the difference
* between the representation and the integer representation of the average image.
* that difference array is then returned.
*/
public int[] findDeviated(int[] img) {
int[] temp = new int[img.length];
for (int x = 0; x < temp.length; x++) {
temp[x] = img[x] – averageImage[x]; //deviated value of the pixel
}
return temp;
}
/*Vector vec stores array as its elements
*This method convert each element into a column of the matrix*/
public DoubleMatrix2D ConvertVectorIntoMatrix(Vector vec) {
// System.out.println(rows);
int rows = ((int[])vec.elementAt(0)).length;
DoubleMatrix2D temp = new DenseDoubleMatrix2D(rows, vec.size());
// Store i'th diff entry as i'th column of A
for (int column = 0; column < vec.size(); column++) {
int[] diffTmp = (int[]) vec.get(column);
for (int row = 0; row < diffTmp.length; row++) {
temp.set(row, column, (double) diffTmp[row]);
}
}
return temp;
}
/**
* Description of the Method
*
* @param Mtrx Description of the Parameter
* @return Description of the Return Value
*/
public Vector ConvertMatrixIntoVector(DoubleMatrix2D Mtrx) {
Vector tempVec = new Vector();
int[] temp = new int[w * h];
for (int col = 0; col < Mtrx.columns(); col++) {
for (int row = 0; row < Mtrx.rows(); row++) {
temp[row] = (int) Mtrx.get(row, col);
}
tempVec.addElement(temp);
}
return tempVec;
}
/*
* Find all what places them where
*/
// CHANGE ARNOLD
// public Vector findEigenVector(DoubleMatrix2D diffImageMatrix) {
public DoubleMatrix2D findEigenVector(DoubleMatrix2D diffImageMatrix) {
// END CHANGE
/*
* We find the eigenvectors and eigenvalues of
* diffImageMatrix^T * diffImageMatrix
* we then find the corresponding eigenvalues and eigenvectors for the covarience matrix
* diffImageMatrix * diffImageMatrix^T
* We do this as follows…
*/
// Atranspose_mult_A = new DenseDoubleMatrix2D(NumOfImages, NumOfImages);
// CHANGE ARNOLD
// Vector Eigen;
// END CHANGE
DoubleMatrix2D eigenVectReducedSystem;
DoubleMatrix2D transposed;
DoubleMatrix2D Atranspose_mult_A;
EigenvalueDecomposition EigenObject;
Algebra Algebric_Functions = new Algebra();
transposed = Algebric_Functions.transpose(diffImageMatrix);
Atranspose_mult_A = Algebric_Functions.mult(transposed, diffImageMatrix);
System.out.println("A^T*A=");
System.out.println(Atranspose_mult_A);
EigenObject = new EigenvalueDecomposition(Atranspose_mult_A);
eigenVectReducedSystem = EigenObject.getV();
System.out.println("Eigenvectors for A^T*A=");
System.out.println(eigenVectReducedSystem);
System.out.println("Eigenvalues for A^T*A=");
System.out.println(EigenObject.getD());
eigenVectCovMatrix = Algebric_Functions.mult(diffImageMatrix,eigenVectReducedSystem);
printPartOfDoubleMatrix2D(eigenVectCovMatrix,10,3);
// CHANGE ARNOLD
// Eigen = ConvertMatrixIntoVector(eigenVectCovMatrix); // ARNOLD
// System.out.println(Eigen.size()); // ARNOLD
// return Eigen; // ARNOLD
return eigenVectCovMatrix;
// END CHANGE
}
public void printPartOfDoubleMatrix2D(DoubleMatrix2D m, int numRows, int numColumns){
int r = m.rows();
int c = m.columns();
System.out.println("Rows = " + r + " ; Columns= " + c);
for(int i=0;i<numRows;i++){
for(int j=0;j<numColumns;j++){
System.out.print(m.get(i,j)+"\t");
}
System.out.println();
}
}
/**
* @param differenceImageMatrix the i'th column of this matrix holds
* the image-averageImage
*/
public DoubleMatrix2D project(DoubleMatrix2D differenceImageMatrix) {
/* Compute the projection of all training images onto all eigenFaces
* that is, we compute
* eigenVectCovMatrix^T* diffImageMatrix
* As a result, the i'th column of the above matrix is the projection of the i'th
* image onto all eigenvectors.
*/
Algebra algebra = new Algebra();
DoubleMatrix2D tr = algebra.transpose(eigenVectCovMatrix);
System.out.println("Transposed");
DoubleMatrix2D projection=algebra.mult(algebra.transpose(eigenVectCovMatrix), differenceImageMatrix);
System.out.println("Weights=\n"+ projection);
return projection;
}
public void classify(Image img){
/*
* Convert image into a matrix im
* signature=projection(im-averageImageMatrix)
* Find the distance between the signature and the signatures of the training images
* for each column of weightMatrix
* find the 2-norm of signature-column
* end for
* return the index of the closest image as well as the distance
*/
DoubleMatrix2D testProjectionMatrix;
DoubleMatrix2D temp;
Algebra algebra = new Algebra();
twoNorm = new double[NumOfImages];
testProjectionMatrix = project(ConvertArrayToMatrix(findDeviated(grabPixels(img))));
twoNorm = find2Norm(weightMatrix,testProjectionMatrix);
//System.out.println(" WeightRows : "+weightMatrix.rows()+" Cols :"+weightMatrix.columns());
smallestTwoNorm = findNearestImage(twoNorm);
}
/* For each column of setImgsMatrix
find the 2-norm of signature-column for testImg */
public double[] find2Norm(DoubleMatrix2D setImgs,DoubleMatrix2D testImg){
DoubleMatrix2D temp2=new DenseDoubleMatrix2D(setImgs.rows(), 1);
Algebra algebra = new Algebra();
double[] tempTwoNorm = new double[NumOfImages];
System.out.println("Rows = "+setImgs.rows()+" Columns = "+setImgs.columns());
for(int c=0;c<setImgs.columns();c++){
for(int r=0;r<setImgs.rows();r++)
temp2.set(r,0,setImgs.get(r,c));
tempTwoNorm[c] = algebra.norm2(cern.colt.matrix.doublealgo.Transform.minus(temp2,testImg));
System.out.println(tempTwoNorm[c]);
}
return tempTwoNorm;
}
/* This method finds the smallest element in an array and returns that element*/
public int findNearestImage(double[] temp)
{
double smallest = temp[0];
int j=0;
for(int i=0;i<temp.length;i++){
if(temp[i] < smallest){
smallest = temp[i];
j=i;
}
}
System.out.println("Image -> "+j);
return j;
}
}
-PCA amprente.java
package pca.amprente;
import javax.swing.*;
import cern.colt.matrix.*;
import java.awt.*;
import java.awt.event.*;
public class PcaAmprente extends JFrame {
static image test ;
static String testImage;
static Image[] trainingImages;
static display draw;
double twoNorm[];
int smallest;
/* This is an another approach . Without using eigen faces .
counter := 0
while (counter<NumOfTrainingImages) do
distanceMatrix = ConvertInToMatrix(GrabColumnOfTrainingImageMatrix(counter))-testImageMatrix TwoNormArray[counter] = Find2Norm(distanceMatrix)
counter := counter+1
End While
*/
public PcaAmprente(String path,int testImgNum){
test = new image(path,this);
testImage="testImages/101_1.gif";
DoubleMatrix2D trainingMatrix = test.ConvertVectorIntoMatrix(test.TrainingImageVector);
DoubleMatrix2D testMatrix = test.ConvertArrayToMatrix(test.grabPixels(test.loadImageFromFile(testImage)));
twoNorm=test.find2Norm(trainingMatrix,testMatrix);
smallest=test.findNearestImage(twoNorm);
}
public static void main(String s[]) {
PcaAmprente alt = new PcaAmprente("TrainingPics",2);
draw = new display();
trainingImages = draw.drawBehind(test.TrainingImageVector,test.w,test.h);
alt.addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
alt.setSize(new Dimension(1030,750));
alt.setVisible(true);
alt.repaint();
}
/**
* Draws everything on the frame
*
* @param g Graphics context of frame
*/
public void paint(Graphics g) {
g.drawImage(test.loadImageFromFile(testImage),0,0,this);
g.drawImage(trainingImages[smallest], 270, 0, this);
}
}
B. Recunoașterea fețelor folosind PCA
Identitatea unei persoane este reprezentată nu de actele oficiale pe care le deține, ci de un set extins, complex, variabil în timp și nu întotdeauna ușor de definit de trăsături personalizate, de natură anatomică, fiziologică sau comportamentală. Unele dintre aceste trăsături (considerate izolat sau sub forma unor combinații) pot fi folosite, împreună cu tehnici automate de procesare a semnalelor, pentru implementarea așa-numitelor sisteme biometrice, capabile să recunoască sau să valideze autenticitatea identității unor persoane. Drept informații biometrice se utilizează în mod curent amprentele, vocea, fața, irisul, forma geometrică a mâinii.
Recunoașterea fețelor
Fața joacă un rol esențial în relațiile sociale, în comunicarea identității și a emoțiilor. Capacitatea umana de a recunoaște fețele este remarcabilă: putem recunoaște mii de figuri învățate de-a lungul vieții și identifica fețele familiare dintr-o singură privire chiar după ani de zile. Această capacitate este destul de robustă, în ciuda schimbărilor mari în stimulul vizual datorate condițiilor de vizualizare, expresiei, îmbătrânirii și altor factori perturbatori precum prezența ochelarilor, a bărbii sau schimbări ale coafurii.
Deși atractivă deoarece nu presupune contact direct între subiect și senzor (se spune că este o tehnică neinvazivă), recunoașterea feței este o sarcină dificilă datorită surselor numeroase de variabilitate în condiții reale. Acestea includ printre altele: orientarea feței în raport cu aparatul de fotografiat sau camera de filmat, nivelul de iluminare, expresia feței, timpul scurs între momentele prelevării unor imagini distincte, precum și aspectele demografice (rasa, vârsta, sexul).
Ce reprezintă o față?
Dacă transformăm o imagine de dimensiuni NxN pixeli într-un vector de dimensiune N2 , acesta poate fi privit ca un punct într-un spațiu N2 – dimensional. Imaginile reprezentând fețe umane ocupă doar un mic subspațiu al acestui spațiu multidimensional, cu caracteristici specifice. Se poate arăta că modificările obișnuite precum translația, rotația, sau schimbarea nivelului de iluminare, atunci când au amplitudine mică, definesc simple subregiuni compacte din “subspațiul fețelor”.
Care este cea mai distinctivă informație?
Există 2 strategii majore implicate în obținerea "semnăturii" feței, anume:
a) tehnica geometrică, bazată pe extracția pozițiilor relative și a altor parametri dependenți de puncte particulare precum ochii, colțurile gurii, nasul și bărbia
b) tehnica bazată pe modele (templates), în care matricele reprezentând valorile de intensitate luminoasă a pixelilor care alcătuiesc fața de test și, respectiv, cea de referință sunt procesate convenabil, urmând ca rezultatele să fie comparate utilizând un anumit tip de măsură a similitudinii (câteodată sunt folosite mai multe modele pentru fiecare față).
Alegerea procedeului specific de extragere a "semnăturii" este dictată de capacitatea distinctivă a informației rezultate. Din moment ce imaginile feței sunt reprezentate în mod obișnuit printr-o matrice de dimensiuni considerabile, se folosesc diverse metode de compresie, liniare sau neliniare, precum Analiza pe Componente Principale (Principal Components Analysis – PCA) pentru obținerea unei reprezentări de dimensiuni mult reduse a imaginii originale, fără o pierdere semnificativă a calității. Mai mult, Analiza Discriminatorie Liniară (Linear Discriminant Analysis – LDA) este adesea aleasă pentru a identifica direcțiile din “spațiul fețelor” de-a lungul cărora separarea „semnăturilor” este maximă.
În literatură au fost propuse numeroase tehnici de recunoaștere/autentificare a fețelor, cu grade de complexitate, constrângeri, performanțe și arii de aplicabilitate foarte diverse. În mod special, identificarea, extragerea și ierarhizarea setului de trăsături semnificative care va constitui „semnătura” fiecărei fețe supuse analizei continuă să reprezinte un subiect de larg interes.
Algoritmul de procesare presupune parcurgerea următorilor pași:
Se calculează valoarea medie a imaginilor care formează setul de antrenare (presupus a avea K fotografii):
și se „centrează” imaginile originale (se aduc la valoare medie nulă):
Se calculează așa-numita scatter matrix, care reprezintă aproximarea matricii de covarianță a imaginilor din baza de date (aproximarea este cu atât mai bună cu cât avem mai multe imagini la dispoziție):
unde matricea A are pe coloane câte o fotografie centrată:
Matricea S este simetrică și are dimensiuni (M*N)x(M*N).
Se calculează valorile și vectorii proprii ai matricii S (vectorii proprii ai matricii S în cazul lucrului cu imagini reprezentând fețe poartă denumirea Eigenfaces).
Observații:
a) se poate utiliza un artificiu care reduce volumul de calcul: se calculează valorile și vectorii proprii ai matricii A AT și apoi se folosește relația dintre aceștia din urmă și vectorii proprii ai matricii S.
b) valorile proprii ale matricii S sunt întotdeauna pozitive deoarece S este reală și simetrică.
d) Se ordonează valorile proprii ale matricii S în sens descrescător. Se trasează un grafic care exprimă pierderea de informație în raport cu factorul de compresie. Astfel, dacă notăm cu λi , i MN = × 1…( ), valorile proprii sortate ale matricii S, graficul anterior se referă la raportul (pe abscisă avem j MN = × 1…( ) ):
Graficul anterior permite estimarea numărului de valori și vectori proprii considerați semnificativi (adică aceia care păstrează cea mai mare parte din energia imaginilor originale).
Se proiecteză imaginile (centrate) originale pe spațiul descris de vectorii proprii reprezentativi (tipic aceștia sunt în număr de 5-10% din numărul total). Proiecția constă de fapt în efectuarea produsului scalar dintre fiecare imagine originală și o matrice având drept coloane numai vectorii proprii semnificativi. Pentru fiecare imagine (centrată) centrat j I se obține proiecția pe baza relației:
unde Nmax este numărul maxim de vectori proprii reținuți, Ej sunt vectorii proprii semnificativi, iar vectorii Wj au dimensiunea ( 1) Nmax × și pot fi priviți ca „semnăturile” asociate imaginilor originale.
Clasificarea imaginilor test presupune mai întâi determinarea „semnăturii” fiecărei imagini în raport cu subpațiul determinat anterior (și care depinde exclusiv de imaginile din setul de antrenare!) și găsirea acelei imagini din baza de date de antrenare a cărei semnătură este cea mai apropiată de semnătura imaginii de test. Aprecierea similitudinii dintre astfel de perechi de imagini se realizează folosind o metrică convenabil aleasă. Opțiunea uzuală este distanța Euclideană :
Descrierea algoritmului de recunoastere a fetelor
Etapa 1
Date de intrare: 5 imagini
Date de test: 2 imaginoi noi, diferite de cele 5
Se vor afisa cele doua imagini, imaginea de test, din cele 2 si imaginea cu care se potriveste cel mai mult, din cele 5. Se va afisa si procentul de corect recunoastere.
Etapa 2
Date de intrare: 7 imagini
Date de test: 3 imaginoi noi, diferite de cele 7
Se vor afisa cele doua imagini, imaginea de test, din cele 3 si imaginea cu care se potriveste cel mai mult, din cele 7. Se va afisa si procentul de corect recunoastere.
Se observa o crestere a procentului.
CreateDatabase.m
function I = CreateDatabase(TrainDatabasePath)
TrainFiles = dir(TrainDatabasePath);
Train_Number = 0;
for i = 1:size(TrainFiles,1)
if not(strcmp(TrainFiles(i).name,'.')|strcmp(TrainFiles(i).name,'..')|strcmp(TrainFiles(i).name,'Thumbs.db'))
Train_Number = Train_Number + 1; % Number of all images in the training database
end
end
%%%%%%%%%%%%%%%%%%%%%%%% Construction of 2D matrix from 1D image vectors
I = [];
for i = 1 : Train_Number
% I have chosen the name of each image in databases as a corresponding
% number. However, it is not mandatory!
str = int2str(i);
str = strcat('\',str,'.jpg');
str = strcat(TrainDatabasePath,str);
img = imread(str);
img = rgb2gray(img);
[irow icol] = size(img);
temp = reshape(img',irow*icol,1); % Reshaping 2D images into 1D image vectors
I = [I temp]; % 'I' grows after each turn
end
EigenfaceCore.m
function [m, A, Eigenfaces] = EigenfaceCore(I)
%%%%%%%%%%%%%%%%%%%%%%%% Calculating the mean image
m = mean(I,2); % Computing the average face image m = (1/K)*sum(Ij's) (j = 1 : K) (1.10)
Train_Number = size(I,2);
%%%%%%%%%%%%%%%%%%%%%%%% Calculating the deviation of each image from mean image
A = [];
for i = 1 : Train_Number
temp = double(I(:,i)) – m; % Computing the difference image for each image in the training set Ai = Ii – m (1.11)
A = [A temp]; % Merging all centered images
end
%%%%%%%%%%%%%%%%%%%%%%%% Snapshot method of Eigenface methos
% We know from linear algebra theory that for a PxQ matrix, the maximum
% number of non-zero eigenvalues that the matrix can have is min(P-1,Q-1).
% Since the number of training images (K) is usually less than the number
% of pixels (M*N), the most non-zero eigenvalues that can be found are equal
% to K-1. So we can calculate eigenvalues of A'*A (a KxK matrix) instead of
% A*A' (a M*NxM*N matrix). It is clear that the dimensions of A*A' is much
% larger that A'*A. So the dimensionality will decrease.
L = A'*A; % L is the surrogate of covariance matrix C=A*A'.
[V D] = eig(L); % Diagonal elements of D are the eigenvalues for both L=A'*A and C=A*A'.
%%%%%%%%%%%%%%%%%%%%%%%% Sorting and eliminating eigenvalues
% All eigenvalues of matrix L are sorted and those who are less than a
% specified threshold, are eliminated. So the number of non-zero
% eigenvectors may be less than (K-1).
L_eig_vec = [];
for i = 1 : size(V,2)
if( D(i,i)>1 )
L_eig_vec = [L_eig_vec V(:,i)];
end
end
%%%%%%%%%%%%%%%%%%%%%%%% Calculating the eigenvectors of covariance matrix 'C'
% Eigenvectors of covariance matrix C (or so-called "Eigenfaces")
% can be recovered from L's eiegnvectors.
Eigenfaces = A * L_eig_vec; % A: centered image vectors (1.15)
Recognition.m
function OutputName = Recognition(TestImage, m, A, Eigenfaces)
%%%%%%%%%%%%%%%%%%%%%%%% Projecting centered image vectors into facespace
% All centered images are projected into facespace by multiplying in
% Eigenface basis's. Projected vector of each face will be its corresponding
% feature vector.
ProjectedImages = [];
Train_Number = size(Eigenfaces,2);
for i = 1 : Train_Number
temp = Eigenfaces'*A(:,i); % Projection of centered images into facespace
ProjectedImages = [ProjectedImages temp];
end
%%%%%%%%%%%%%%%%%%%%%%%% Extracting the PCA features from test image
InputImage = imread(TestImage);
temp = InputImage(:,:,1);
[irow icol] = size(temp);
InImage = reshape(temp',irow*icol,1);
Difference = double(InImage)-m; % Centered test image
ProjectedTestImage = Eigenfaces'*Difference; % Test image feature vector
%%%%%%%%%%%%%%%%%%%%%%%% Calculating Euclidean distances
% Euclidean distances between the projected test image and the projection
% of all centered training images are calculated. Test image is
% supposed to have minimum distance with its corresponding image in the
% training database.
Euc_dist = [];
for i = 1 : Train_Number
q = ProjectedImages(:,i);
temp = ( norm( ProjectedTestImage – q ) )^2;
Euc_dist = [Euc_dist temp];
end
[Euc_dist_min , Recognized_index] = min(Euc_dist);
OutputName = strcat(int2str(Recognized_index),'.jpg');
Example.m
clear all
clc
close all
% You can customize and fix initial directory paths
TrainDatabasePath = uigetdir('C:\Users\Geoboss\Desktop', 'Select training database path' );
TestDatabasePath = uigetdir('C:\Users\Geoboss\Desktop', 'Select test database path');
prompt = {'Enter test image name: '};
dlg_title = 'Input of PCA-Based Face Recognition System';
num_lines= 1;
def = {'0'};
TestImage = inputdlg(prompt,dlg_title,num_lines,def);
TestImage = strcat(TestDatabasePath,'\',char(TestImage),'.jpg');
im = imread(TestImage);
I = CreateDatabase(TrainDatabasePath);
[m, A, Eigenfaces] = EigenfaceCore(I);
OutputName = Recognition(TestImage, m, A, Eigenfaces);
SelectedImage = strcat(TrainDatabasePath,'\',OutputName);
SelectedImage = imread(SelectedImage);
imshow(im)
title('Test Image');
figure,imshow(SelectedImage);
title('Equivalent Image');
str = strcat('Matched image is : ',OutputName);
disp(str)
procent=size(Eigenfaces,2)/size(I,2)*100;
C. Recunoasterea textului
Recunoașterea textelor scrise este unul din multele subdomenii ale recunoașterii formelor. Metodele de recunoaștere se bazează pe antrenarea cu un număr foarte mare de simboluri. Aceste imagini de simboluri sunt grupate în baze de date care au în marea lor majoritate prețuri foarte mari.
Pentru a detecta un simbol este necesară detecția celulei în care se află. Deși pare simplu, într-un final se ajunge la rezolvarea unei probleme de recunoaștere a formelor pentru obținerea datelor de antrenare necesare unei alte probleme similare, cea a recunoașterii caracterelor. Din fericire, noua problemă este mai simplă și poate fi abordată și utilizînd metode deterministe.
Metode de procesare a imaginilor:
1) Filtrarea culorilor.
În acest paragraf vor fi expuse succint metode de transformare a imaginilor digitale din format RGB în tonuri de gri sau în format alb-negru. Pentru transformarea intensitătii codificată în format RGB în nivele de gri se pot folosi următoarele formule:
– media aritmetică;
– norma culorii.
După obtinerea imaginii în tonuri (nivele) de gri se poate face transformarea următoare spre imagine alb-negru. Și aici există mai multe metode ce diferă între ele prin modalitatea de stabilire a nivelului de prag între alb și negru, din care vor fi prezentate trei.
• Prima, cea simplă, constă în stabilirea unei valori de prag fixe la mijlocul intervalului. Evident această abordare simplistă poate duce la rezultate total inadecvate.
• A doua, mai complicată, stabilește nivelul intensitătii de prag dintre alb și negru prin analiza locală a imaginii și stabilirea în functie de histograma intensitătilor a nivelului de prag.
• A treia metodă folosește un filtru coplanar ce exploatează coplanaritatea nivelelor de gri ale pixelilor învecinati. Avantajele metodei rezidă în înlăturarea zgomotului, netezirea zonală a imaginii și păstrarea muchiilor ascutite.
2) Gradient.
Gradientul se folosește pentru detectarea muchiilor dintr-o imagine. Gradientul are semnificatie intrinsecă; privind intuitiv, gradientul arată directia celei mai abrupte pante ce trece prin punctul curent.
În cazul imaginilor digitale, definitia gradientului se modifică în sensul că se lucrează cu diferente finite, astfel operatiile se efectuează într-o fereastră de dimensiuni reduse, de exemplu 3×3 pixeli sau chiar 2×2 pixeli. Există diverse metode de calcul al gradientului, unele dintre acestea depărtându-se destul de mult de definitia matematică riguroasă a acestuia. Referitor la dimensiunea ferestrei de calcul a gradientului, se observă că pentru dimensiuni pare ale laturilor acesteia valoarea gradientului nu se mai obtine în coordonatele initiale ale imaginii, ci între acestea.
3) Transformata Fourier (TF) .
Transformata Fourier a fost inventată de Jean Baptiste Joseph, Baron de Fourier în anul 1807. Utilitatea ei este dată de proprietatea de a obtine noi caracteristici ale unui semnal prin transformarea acestuia din spatiul în care se află în domeniul (spatiul) parametric al frecventelor. Transformata poate fi folosită pentru orice fel de semnal periodic sau nu, analog sau digital, existând diverse variante ale transformării pentru fiecare caz în parte. Astfel, transformata Fourier obtine spectrul de frecvente al unui semnal, iar transformata Fourier inversă generează semnalul din spectrul de frecvente.
În urma aplicării TF asupra unui semnal, se obtin amplitudinile pentru frecventele spectrului semnalului. Frecventele sunt date de functii sinus și cosinus (sau, în forma exponentială, de exponentiale imaginare). Pentru semnale pare, spectrul este format doar din functii cosinus, iar pentru semnale impare, spectrul contine doar functii sinus.
Revenind la utilitatea transformatei, se poate observa că aceasta poate fi folosită pentru filtrarea semnalelor în general și a imaginilor digitale în particular, pentru extragerea de caracteristici ce pot fi folosite la intrarea altor algoritmi de analiză și clasificare.
În domeniul recunoașterii scrisului, transformata Fourier poate fi folosită pentru segmentarea imaginii în rânduri și cuvinte.
4) Transformata Hough.
Transformata Hough se folosește la detectarea liniilor dintr-o imagine. Fiind dată o multime de puncte într-un spatiu euclidian bidimensional prin coordonatele (x ,y ), se cere să se determine care din aceste puncte sunt coliniare și care nu. Pentru aceasta, se aplică o transformare a spatiului euclidian la spatiul coordonatelor polare.
Deoarece pentru fiecare punct (x, y) există o infinitate de perechi (r,θ) în spatiul parametric, trebuie găsită o modalitate de reducere a dimensionalitătii problemei pentru aplicarea practică. Pentru aceasta, se discretizează problema prin discretizarea valorilor parametrilor. Astfel, dacă imaginea initială, în formă discretă, avea N × M pixeli putem discretiza spatiul parametrilor alegând, de exemplu, dθ =1°și dr =1pixel . Discretizarea se face în functie de problemă.
Pasul următor rezidă în construirea unei matrici H, unde linia reprezintă distanta și coloana reprezintă unghiul. N și M sunt dimensiunile imaginii. Elementele matricei au initial valoarea 0. Pentru toate valorile discrete posibile ale lui r și θ , se construiesc dreptele corespunzătoare și se numără prin câte din punctele imaginii trec. Acest număr reprezintă valoarea celulei respective.
Folosind acest algoritm, la sfârșit, în matrice se vor afla numere întregi care reprezintă numărul de puncte prin care trece fiecare dreaptă. Dacă există celule cu valori mai mari sau egale cu trei, înseamnă că s-au găsit puncte coliniare în imaginea initială. Utilizând această metodă, se poate detecta orientarea rândurilor dintr-o imagine.
5)Segmentarea
Segmentarea reprezintă un pas foarte important al procesului de recunoaștere de care depinde succesul sau insuccesul acestuia. Se realizează la mai multe niveluri și anume: segmentarea imaginii în blocuri de text, grafice și alte artefacte, segmentarea blocurilor de text în rânduri, a rândurilor în cuvinte și, cel mai important, a cuvintelor în litere. Trebuie mentionat că segmentarea, pe lângă procedeele uzuale de împărtire a unui simbol grafic în părti componente, trebuie să și reconstruiască simboluri din aceste părti componente, simboluri ce trebuie să contină pe cât posibil toate părtile ce le apartin și nici una din părtile ce nu le apartin, adică să separe fiecare literă de literele adiacente cu ea.
Deoarece procedeul este foarte complex, se folosesc o sumedenie de metode matematice pentru realizarea sa. Dintre acestea, putem aminti următoarele:
• geometrie analitică pentru transformarea simbolurilor din formă de tip bitmap în formă vectorială
• statistică și probabilităti – practic, sunt indispensabile în aproape toate fazele procesului de recunoaștere
• retele neuronale artificiale (RNA)
• retele BBN (Bayesian Belief Networks)– este prezentată utilizarea unor astfel de retele în procesul de segmentare și avantajele acestora fată de clasificatorii bayesieni simpli: scăderea timpului de antrenare cu un factor de 55% și obtinerea unei rate de succes de 86% în identificarea limitelor segmentelor
• metrici – acestea sunt folosite pentru extragerea segmentelor constituente ale caracterelor chinezești
Aplicatie pentru recunoasterea textului
text_recognition.m
% Text Recognition
% PROGRAMUL PRINCIPAL
% Citirea imagini
imagen=imread('TEST_4.jpg');
% Afisarea imagini
imshow(imagen);pause(1)
% Conversie la noante de gri
if size(imagen,3)==3 % imagine RGB
imagen=rgb2gray(imagen);
end
% Conversie la alb-negru
threshold = graythresh(imagen);
imagen =~im2bw(imagen,threshold);
% Inlaturarea tututor obiecteler ce contin mai putin de 30 de pixeli
imagen = bwareaopen(imagen,30);
%Matricea de stocare a cuvintelor din imagine.
word=[ ];
re=imagen;
%Deschidem fisierul text.txt pentru scriere.
fid = fopen('text.txt', 'wt');
% Incarcam sabloanele
load templates
global templates
% Calculam numarul de litere din sablon
num_letras=size(templates,2);
while 1
%Functia 'lines' separa liniile in text
[fl re]=lines(re);
imgn=fl;
% Etichetarea si numarararea componentelor conectate.
[L Ne] = bwlabel(imgn);
for n=1:Ne
[r,c] = find(L==n);
% Extragerea literei
n1=imgn(min(r):max(r),min(c):max(c));
% Redimensionarea literei la dimensiunea sablonului
img_r=imresize(n1,[42 24]);
%Afisarea literelor una cate una
imshow(img_r);pause(0.2)
% Functia pentru conversia imaginei in text
letter=read_letter(img_r,num_letras);
% Concatenarea literelor
word=[word letter];
end
%Scrierea in fisier
fprintf(fid,'%s\n',word);%Write 'word' in text file (upper)
word=[ ];
if isempty(re)
break
end
end
fclose(fid);
%Deschidem fisierul text.txt
winopen('text.txt')
clear all
create_templates.m
%CREATE TEMPLATES
%Letter
A=imread('letters_numbers\A.bmp');B=imread('letters_numbers\B.bmp');
C=imread('letters_numbers\C.bmp');D=imread('letters_numbers\D.bmp');
E=imread('letters_numbers\E.bmp');F=imread('letters_numbers\F.bmp');
G=imread('letters_numbers\G.bmp');H=imread('letters_numbers\H.bmp');
I=imread('letters_numbers\I.bmp');J=imread('letters_numbers\J.bmp');
K=imread('letters_numbers\K.bmp');L=imread('letters_numbers\L.bmp');
M=imread('letters_numbers\M.bmp');N=imread('letters_numbers\N.bmp');
O=imread('letters_numbers\O.bmp');P=imread('letters_numbers\P.bmp');
Q=imread('letters_numbers\Q.bmp');R=imread('letters_numbers\R.bmp');
S=imread('letters_numbers\S.bmp');T=imread('letters_numbers\T.bmp');
U=imread('letters_numbers\U.bmp');V=imread('letters_numbers\V.bmp');
W=imread('letters_numbers\W.bmp');X=imread('letters_numbers\X.bmp');
Y=imread('letters_numbers\Y.bmp');Z=imread('letters_numbers\Z.bmp');
%Number
one=imread('letters_numbers\1.bmp'); two=imread('letters_numbers\2.bmp');
three=imread('letters_numbers\3.bmp');four=imread('letters_numbers\4.bmp');
five=imread('letters_numbers\5.bmp'); six=imread('letters_numbers\6.bmp');
seven=imread('letters_numbers\7.bmp');eight=imread('letters_numbers\8.bmp');
nine=imread('letters_numbers\9.bmp'); zero=imread('letters_numbers\0.bmp');
letter=[A B C D E F G H I J K L M…
N O P Q R S T U V W X Y Z];
number=[one two three four five…
six seven eight nine zero];
character=[letter number];
templates=mat2cell(character,42,[24 24 24 24 24 24 24 …
24 24 24 24 24 24 24 …
24 24 24 24 24 24 24 …
24 24 24 24 24 24 24 …
24 24 24 24 24 24 24 24]);
save ('templates','templates')
clear all
lines.m
function [fl re]=lines(im_texto)
% Divizarea textului in linii
im_texto=clip(im_texto);
num_filas=size(im_texto,1);
for s=1:num_filas
if sum(im_texto(s,:))==0
nm=im_texto(1:s-1, :); % Prima linie din matrice
rm=im_texto(s:end, :);
fl = clip(nm);
re=clip(rm);
break
else
fl=im_texto;
re=[ ];
end
end
function img_out=clip(img_in)
[f c]=find(img_in);
img_out=img_in(min(f):max(f),min(c):max(c));%Croparea imagini
read_letter.m
function letter=read_letter(imagn,num_letras)
% Calculeaza corelatia dintre sablon si imaginea de intrare.
% si rezultatul e un sir caractere
global templates
comp=[ ];
for n=1:num_letras
sem=corr2(templates{1,n},imagn);
comp=[comp sem];
end
vd=find(comp==max(comp));
if vd==1
letter='A';
elseif vd==2
letter='B';
elseif vd==3
letter='C';
elseif vd==4
letter='D';
elseif vd==5
letter='E';
elseif vd==6
letter='F';
elseif vd==7
letter='G';
elseif vd==8
letter='H';
elseif vd==9
letter='I';
elseif vd==10
letter='J';
elseif vd==11
letter='K';
elseif vd==12
letter='L';
elseif vd==13
letter='M';
elseif vd==14
letter='N';
elseif vd==15
letter='O';
elseif vd==16
letter='P';
elseif vd==17
letter='Q';
elseif vd==18
letter='R';
elseif vd==19
letter='S';
elseif vd==20
letter='T';
elseif vd==21
letter='U';
elseif vd==22
letter='V';
elseif vd==23
letter='W';
elseif vd==24
letter='X';
elseif vd==25
letter='Y';
elseif vd==26
letter='Z';
%*-*-*-*-*
elseif vd==27
letter='1';
elseif vd==28
letter='2';
elseif vd==29
letter='3';
elseif vd==30
letter='4';
elseif vd==31
letter='5';
elseif vd==32
letter='6';
elseif vd==33
letter='7';
elseif vd==34
letter='8';
elseif vd==35
letter='9';
else
letter='0';
end
Pentru imaginea.
Rezulta:
Pentru imaginea:
Rezulta:
Pentru imaginea:
Rezulta:
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Recunoasterea Obiectelor Folosind Procesarea Imaginilor (ID: 150362)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
