PCA Implementation for Face Recognition | Computer Vision Project Help

Examine the following code to have a better understanding of the PCA algorithm for face recognition, Use the following code. Create a Windows forms application called FaceRecogPCA. Place picture boxes, buttons and Labels as shown below. The square boxes below are picture boxes.


Output Format:



Implementation

Here code implemented in C#, you need to implement it using python. If you need to any help in python computer vision then hire realcode4you expert and get instant help with and affordable price.



using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace FaceRecogPCA
{
 /// <summary>
 /// Summary description for MyImage.
 /// </summary>
 public class MyImage : IComparable, ICloneable
 {
 public int Width { get; set; }
 public int Height { get; set; }
 public Bitmap BmpImg { get; set; }
 public string Id { get; set; } // id of image
 public string FileName { get; set; } // full path name
 public string FileNameShort { get; set; } // short file name for image
 public double ImgMean { get; set; }
 public double[] ImgVector;// linearized pixel values
 public double[] ImgVectorAdjM;// linearized pixel values minus mean image
 public double[] FSV;// Face space vector, projection onto reduced Dimension
 ImgComparison imgCompareMode;
 public ImgComparison ImgCompareMode { get; set; }
 public double CorrError { get; set; }
 public double EuclideanError { get; set; } // L2 Norm
 public MyImage()
 {
 }
 public MyImage(int width, int height, string id)
 {
 this.Id = id;
 this.ImgVector = new double[width * height];
 }
 public MyImage(string fname, string id, int width, int height, ImgFormat imf, 
ImgComparison imc)
 {
 FileInfo finfo = new FileInfo(fname);
 string dirName = finfo.Directory.Name;
 this.FileNameShort = finfo.Name;
 this.Id = id;
 this.FileName = fname;
 imgCompareMode = imc;
 ReadPic(imf, width, height); // read the picture into an 1-D array
 FindImageMean();
 this.ImgVectorAdjM = new double[width * height];
 this.FSV = new double[width * height];
 }
 private void ReadPic(ImgFormat imf, int width, int height)
 {
 try
 {
 Bitmap b = new Bitmap(this.FileName);
 this.BmpImg = new Bitmap(b, new Size(width, height));
 ImgVector = new double[width * height];
 int k = 0; int r1a, g1a, b1a, gray;
 Color c1;
 for (int i = 0; i < height; i++)
 for (int j = 0; j < width; j++)
 {
 c1 = b.GetPixel(j, i);
r1a = c1.R;
g1a = c1.G;
b1a = c1.B;
if (r1a != b1a)
 gray = (int)(.299 * r1a
+ .587 * g1a
+ .114 * b1a);
 else
 gray = b1a;
 ImgVector[k++] = gray;
 }
 }
 catch (Exception ex)
 {
 throw new Exception(ex.Message + "ImageArray Creation Error");
 }
 }
 //-------------------FindImageMean---------------------------
 void FindImageMean()
 {
 double imgSum = 0;
 for (int i = 0; i < this.ImgVector.Length; i++)
 imgSum = imgSum + this.ImgVector[i];
 this.ImgMean = imgSum / this.ImgVector.Length;
 }
 //------------------------------------------------------------------
 public int CompareTo(Object rhs) // for sorting
 {
 MyImage im = (MyImage)rhs;
 if (imgCompareMode == ImgComparison.CORRELATION)
 return im.CorrError.CompareTo(this.CorrError); // index 0 is best
 else
 return im.EuclideanError.CompareTo(this.EuclideanError); 
 }
 public object Clone() // for in memory copy
 {
 MyImage clone = (MyImage)this.MemberwiseClone();
 if (this.FSV != null)
 clone.FSV = (double[])(this.FSV.Clone());
 if (this.ImgVector != null)
 clone.ImgVector = (double[])(this.ImgVector.Clone());
 if (this.ImgVectorAdjM != null)
 clone.ImgVectorAdjM = (double[])(this.ImgVectorAdjM.Clone());
 return clone;
 }
 }
}
Add a class to the project called “MyEnums.cs” with the following code in it.

namespace FaceRecogPCA
{
 public enum ImgFormat:int
 {
 EightBit,
 TwentyFourBit
 }
 public enum ImgComparison : int
 {
 CORRELATION,
 EUCLIDEAN
 }
}
Add a class called EigenFace to the project with the following code in it.
//--------Eigenface.cs---------------
using System;
using System.Collections;
namespace FaceRecogPCA
{
public class EigenFace : ICloneable 
{ // EigenFace is one of the basis vectors after
 // dimensionality reduction
public double [] EF;
public int size;
public double []Xvar2;
public double EigenValue;
public EigenFace()
{
}
public EigenFace(int sz)
{
EF = new double[sz];
Xvar2=new Double[sz];
size = sz;
}
public object Clone() // for in memory copy
{
EigenFace copy = new EigenFace();
if (this.EF != null)
copy.EF = (double []) this.EF.Clone(); 
copy.EigenValue = this.EigenValue;
copy.size = this.size;
if (this.Xvar2 != null)
copy.Xvar2 = (double []) this.Xvar2.Clone();
return copy;
}
}
}
Add a class called EvEvec for storing the EigenValues and the EigenVectors with the following code in it.
This is done so that we can easily sort by Eigen values.

using System;
namespace FaceRecogPCA
{
 public class EvEvec : IComparable, ICloneable
 {
 public double EigenValue; // Eigen value
 public double[] EigenVec; // Eigen Vector Array
 public int size; // Size of Eigen Vector array
 public EvEvec()
 {
 }
 public EvEvec(double Ev, double[] Evc, int sz)
 {
 EigenVec = new double[sz];
 EigenValue = Ev;
 size = sz;
 for (int i = 0; i < sz; i++)
 EigenVec[i] = Evc[i];
 // EVecs are already normalized i.e., magnitude of 1 
 }
 public int CompareTo(Object rhs) // for sorting
 {
 EvEvec evv = (EvEvec)rhs; // highest to lowest sorting by Eigen value
 return evv.EigenValue.CompareTo(this.EigenValue);
 }
 public object Clone() // for making a copy of the EvEvec object
 {
 EvEvec clone = new EvEvec();
 clone.EigenValue = this.EigenValue;
 if (this.EigenVec != null)
 clone.EigenVec = (double[])this.EigenVec.Clone();
 clone.size = this.size;
 return clone;
 }
 }
}
The main PCA algorithm is encapsulated in the FaceRecogByEF class with the following code in it.
//----------------FaceRecogByEF.cs-----------------
//--- contains important functions for recognizing face by the
//--- Eigen Face technique.
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Collections;
using System.IO;
using System.Threading;
using System.Linq;
using System.Collections.Generic;

namespace FaceRecogPCA
{
 public class FaceRecogByEF
 {
 public List<MyImage> ImageList; // list of stored images 
 public MyImage AvgImage = new MyImage();
 public Matrix Cov = null; // Covariance Matrix
 public Matrix I = null; // matrix of mean adjusted images
 public double[] Evals; // Eigen Values
 public double[,] Evecs; // Eigen Vectors
 public List<EvEvec> EVList; // Eigen values and vectors
 public List<EigenFace> EigenFaceList = new List<EigenFace>();
 // list of Eigen faces
 public Matrix EigenFaceMatrix;
 public MyImage unkIm;
 private int imageWidth;
 private int imageHeight;
 public int imageNumPixels;
 private int NumEigenFaces; // significant number of EigenFaces
 //--------------------------------------------------
 public FaceRecogByEF(int imWidth, int imHeight, int imPixels, int M)
 {
 imageWidth = imWidth;
 imageHeight = imHeight;
 imageNumPixels = imPixels;
 this.NumEigenFaces = M;
 }
 //----------------------ComputeEFs()----------------
 public void ComputeEFs(ImgComparison imgComparison, string imagesFolder) // 
Euclidean or Corr
 {
 ImageList = new List<MyImage>();
 //EigenFaceList = new List<EigenFace>();
 EVList = new List<EvEvec>();
 // Scan Stored Image directory and add every jpg to 
 // ImageList
 try
 {
 //DirectoryInfo dirInfo = new DirectoryInfo(currDir + "\\" + Sto_ImDir);
 DirectoryInfo dirInfo = new DirectoryInfo(imagesFolder);
 if (!dirInfo.Exists)
 throw new DirectoryNotFoundException(imagesFolder +
 "folder does not exist,");
 foreach (FileInfo nextFile in dirInfo.GetFiles())
 {
 if (nextFile.Extension.ToUpper() == ".JPG")
 this.ImageList.Add(new MyImage(nextFile.FullName, "II", 
imageWidth, imageHeight, ImgFormat.TwentyFourBit, imgComparison)); // Euclidean or Corr
 else
 if (nextFile.Extension.ToUpper() == ".GIF")

 this.ImageList.Add(new MyImage(nextFile.FullName, "II", 
imageWidth, imageHeight, ImgFormat.EightBit, imgComparison));
 }
 }
 catch (Exception ex)
 {
 throw new Exception(ex.Message + "Error creating the ImageList..");
 }
 AdjustAllImages(); // subtract mean image from each image
 ComputeCovMatrix();
 ComputeEigenValuesEigenVectors();
 ComputeEigenFaces();
 ComputeKnownFaceSpace(); // projection of images onto reduced dim
 }
 //-------------------------------------------------
//--------------------FindAvgImageAndAdjustImages()------------
 void AdjustAllImages()
 { // finds average image, then subtracts average image from
 // each image to obtain zero mean images
 try
 {
 // find average image
 double[] sum = new double[imageWidth * imageHeight];
 for (int i = 0; i < sum.Length; i++)
 sum[i] = 0;
 for (int i = 0; i < sum.Length; i++)
 {
 foreach (MyImage img in ImageList)
 {
 sum[i] += img.ImgVector[i];
 }
 }
 this.AvgImage.ImgVector = new double[sum.Length];
 for (int i = 0; i < sum.Length; i++)
 this.AvgImage.ImgVector[i] = sum[i] / ImageList.Count;
 // subtract average image from each image
 foreach (MyImage mimg in ImageList)
 {
 SubtractAvgImage(mimg);
 }
 int numImages = ImageList.Count;
 I = new Matrix(imageWidth * imageHeight, numImages);
 int count = 0;
 // copy mean adjusted images into I matrix
 foreach (MyImage mimg in ImageList)
 {
 for (int j = 0; j < mimg.ImgVectorAdjM.Length; j++)
 I[j, count] = mimg.ImgVectorAdjM[j];
 count++;
 }
 }
 catch (Exception)
 {

 throw;
 }
 }
 //-------------------------------------------------------------
 //----------------SubtractAvgImage()---------------------
 public void SubtractAvgImage(MyImage img1)
 {
 // subtract average image from given image
 for (int i = 0; i < img1.ImgVector.Length; i++)
 {
 img1.ImgVectorAdjM[i] = img1.ImgVector[i] -
 this.AvgImage.ImgVector[i];
 }
 }
 //-------------------------------------------------
 //---------------------ComputeCovMatrix--------------------
 private void ComputeCovMatrix() // covariance matrix
 {
 Cov = (Matrix)((I.Transpose().Multiply(I)));
 }
 //-------------------------------------------------
 private void ComputeEigenValuesEigenVectors()
 {
 int i, j;
 int n = ImageList.Count;
 Evals = new double[n];
 IMatrix Evecs = new Matrix(n, n);
 IEigenvalueDecomposition eigen = Cov.GetEigenvalueDecomposition();
 Evecs = eigen.EigenvectorMatrix;
 Evals = eigen.RealEigenvalues;
 //---Copy the Eigen values and vectors in EvEvec objects
 //---for easier sorting by Eigen values.
 double[] evcTemp = new double[n];
 for (i = 0; i < n; i++)
 {
 for (j = 0; j < n; j++)
 evcTemp[j] = Evecs[j, i];
 EVList.Add(new EvEvec(Evals[i], evcTemp, n));
 }
 EVList.Sort(); // sorts, highest Eigen value in pos. 0
 }
 //----------------------------------------------------------
 //-----------ComputeEigenFaces()-------------------------
 private void ComputeEigenFaces()
 {
 int numEFs = 0;
 if (ImageList.Count < NumEigenFaces)
 numEFs = ImageList.Count;
 else
 numEFs = NumEigenFaces;
 EigenFaceMatrix = new Matrix(imageWidth * imageHeight, numEFs);
 // copy EigenVectors into a Matrix

 Matrix EV = new Matrix(ImageList.Count, NumEigenFaces);
 for (int i = 0; i < NumEigenFaces; i++)
 {
 for (int j = 0; j < ImageList.Count; j++)
 EV[j, i] = EVList[i].EigenVec[j];
 }
 EigenFaceMatrix = (Matrix)(I.Multiply(EV));
 //normalize EigenFace(it is an eigen vector of orig.covar matrix)
 for (int j = 0; j < NumEigenFaces; j++)
 {
 double rsum = 0;
 for (int i = 0; i < imageNumPixels; i++)
 {
 rsum += EigenFaceMatrix[i, j] * EigenFaceMatrix[i, j];
 }
 for (int i = 0; i < imageNumPixels; i++)
 EigenFaceMatrix[i, j] = EigenFaceMatrix[i, j] / Math.Sqrt(rsum);
 }
 // Copy Eigen Faces to a List for easier display later
 for (int i = 0; i < NumEigenFaces; i++)
 {
 EigenFace ef = new EigenFace(imageWidth * imageHeight);
 for (int j = 0; j < imageWidth * imageHeight; j++)
 ef.EF[j] = EigenFaceMatrix[j, i];
 EigenFaceList.Add(ef);
 }
 }
 //---------------------------------------------------------
 //----------ComputeKnownFaceSpace()----------------
 private void ComputeKnownFaceSpace()
 {
 Matrix projection = (Matrix)(I.Transpose().Multiply(EigenFaceMatrix));
 for (int i = 0; i < ImageList.Count; i++)
 {
 for (int j = 0; j < NumEigenFaces; j++)
 ImageList[i].FSV[j] = projection[i, j];
 }
 }
 //-------------------------------------------------
 //----------ComputeFaceSpace()---------------------
 public void ComputeFaceSpace(MyImage im)
 {
 int i, j;
 double rsum;
 for (i = 0; i < EigenFaceList.Count; i++)
 {
 rsum = 0.0;
 for (j = 0; j < imageNumPixels; j++)
 {
 EigenFace ef = (EigenFace)EigenFaceList[i];
rsum = rsum + im.ImgVectorAdjM[j] * ef.EF[j];
 }
 im.FSV[i] = rsum;
 }
 }

 //-------------------------------------------------
//-------------------NormalizeEigenFaces()-----------
 void NormalizeEigenFaces()
 {
 // normalize the EigenFace to 0-255 range
 foreach (EigenFace ef in EigenFaceList)
 {
 double max1 = (from n in ef.EF select n).Max();
 double min = (from n in ef.EF select n).Min();
 double diff = max1 - min;
 for (int i = 0; i < ef.EF.Length; i++)
 {
 ef.EF[i] = ef.EF[i] - min;
 ef.EF[i] = ef.EF[i] / diff * 255;
if (ef.EF[i] < 0)
 ef.EF[i] = 0;
 if (ef.EF[i] > 255)
 ef.EF[i] = 255;
 }
 }
 }
 //---------------------------------------------------
 //--------------GetReconstructedFaceSpaceImage(MyImage img)------------
 public MyImage GetMatchedAndReconstructedImages(MyImage inputImg,
 ref double selfReconstError, ref MatchResult[] bestMatches)
 {
 // assumes data is in Imagevector
 MyImage recImage = new MyImage();
 recImage.ImgVectorAdjM = new double[inputImg.ImgVectorAdjM.Length];
 // subtract mean image from input image
 SubtractAvgImage(inputImg);
 //-------FSV for input image-----------------
 ComputeFaceSpace(inputImg);
 double[] fsvData = inputImg.FSV;
 // Reconstruct the input image
 double[] recData = new double[inputImg.ImgVectorAdjM.Length];
 for (int j = 0; j < inputImg.ImgVectorAdjM.Length; j++)
 {
 recData[j] = 0;
 for (int i = 0; i < NumEigenFaces; i++)
 {
 recData[j] += fsvData[i] * ((EigenFace)EigenFaceList[i]).EF[j];
 }
 }
 // normalize the reconstructed image to 255 range
 double max1 = (from n in recData select n).Max();
 double min = (from n in recData select n).Min();
 double diff = max1 - min;
 for (int i = 0; i < inputImg.ImgVectorAdjM.Length; i++)
 {
 recData[i] = recData[i] - min;

 recData[i] = (recData[i] / diff) * 255;
 recData[i] = recData[i];
 if (recData[i] < 0)
 recData[i] = 0;
 if (recData[i] > 255)
 recData[i] = 255;
 }
 // add mean image
 for (int i = 0; i < recData.Length; i++)
 recImage.ImgVectorAdjM[i] = recData[i] + this.AvgImage.ImgVector[i];
 // readjust the reconstructed image to 0-255 range
 max1 = (from n in recImage.ImgVectorAdjM select n).Max();
 min = (from n in recImage.ImgVectorAdjM select n).Min();
 diff = max1 - min;
 for (int i = 0; i < recImage.ImgVectorAdjM.Length; i++)
 {
 recImage.ImgVectorAdjM[i] = recImage.ImgVectorAdjM[i] - min;
 recImage.ImgVectorAdjM[i] = (recImage.ImgVectorAdjM[i] / diff) * 255;
 if (recImage.ImgVectorAdjM[i] < 0)
 recImage.ImgVectorAdjM[i] = 0;
 if (recImage.ImgVectorAdjM[i] > 255)
 recImage.ImgVectorAdjM[i] = 255;
 }
 selfReconstError = 0;
 for (int i = 0; i < inputImg.ImgVectorAdjM.Length; i++)
 selfReconstError = selfReconstError + (inputImg.ImgVector[i] -
 recImage.ImgVectorAdjM[i]) * (inputImg.ImgVector[i] -
recImage.ImgVectorAdjM[i]);
 selfReconstError = Math.Sqrt(selfReconstError);
 //-----------find best match----------------------------
 MatchResult[] MR = new MatchResult[ImageList.Count];
 for (int i = 0; i < ImageList.Count; i++)
 {
 MR[i] = new MatchResult(i, 0, (MyImage)((MyImage)ImageList[i]).Clone());
 double dist = 0;
 for (int j = 0; j < NumEigenFaces; j++)
 dist += ((MR[i].mImage.FSV[j] - inputImg.FSV[j]) *
 (MR[i].mImage.FSV[j] - inputImg.FSV[j]));
 MR[i].EucledianDist = Math.Sqrt(dist);
 }
 //--------------find correlation--------------------
 double[] corr = FindCorrelation(inputImg);
 for (int i = 0; i < ImageList.Count; i++)
 MR[i].Correlation = corr[i];
 Array.Sort(MR);
 bestMatches = MR;
 return recImage;
 }

 public double[] FindCorrelation(MyImage unkIm)
 {
 //----------------correlation ---------------
 // m |
 // S(Xi-X')*(Yi-Y') |--> rtop
 // i=0 |
 // Correlation = --------------------
 // m m |
 // S(Xi-X')² * S(Yi-Y')² |--> rbot1 ^ rbot2
 // i=0 i=0 |
 //------------------------------------------- 
 int i, j, k;
 double rsum = 0; double avgunk;
 double[] avgi = new double[ImageList.Count];
 //---------Calculates the unknown face space average---------//
 //------------------ Y' ---------------------------------//
 for (k = 0; k < EigenFaceList.Count; k++)
 {
 rsum = rsum + unkIm.FSV[k];
 }
 avgunk = rsum / EigenFaceList.Count;
 //---------Calculates the known face space average---------//
 //------------------ X' ---------------------------------//
 for (i = 0; i < ImageList.Count; i++)
 {
 rsum = 0.0;
 MyImage im = (MyImage)ImageList[i];
 for (k = 0; k < EigenFaceList.Count; k++)//review
 {
 rsum = rsum + im.FSV[k];
 }
 avgi[i] = rsum / EigenFaceList.Count;
 }
 //----Calculate the Numerator of the Correlation Equation----//
 double[] rtop = new double[ImageList.Count];
 for (i = 0; i < ImageList.Count; i++)
 {
 rtop[i] = 0.0;
 for (j = 0; j < EigenFaceList.Count; j++)
 {
 MyImage im = (MyImage)ImageList[i];
rtop[i] = rtop[i] + (im.FSV[j] - avgi[i]) *
 (unkIm.FSV[j] - avgunk);
 }
 }
 //---Calculate the Denominator of the Correlation Equation----//
 double[] rbot1 = new Double[ImageList.Count];
 double[] rbot2 = new Double[ImageList.Count];
 for (i = 0; i < ImageList.Count; i++)
 {
 rbot1[i] = 0.0; rbot2[i] = 0.0;
 for (j = 0; j < EigenFaceList.Count; j++)
 {
 MyImage im = (MyImage)ImageList[i];
rbot1[i] = rbot1[i] + (im.FSV[j] - avgi[i]) * (im.FSV[j] - avgi[i]);
 rbot2[i] = rbot2[i] + (unkIm.FSV[j] - avgunk) * (unkIm.FSV[j] -
avgunk);
 }
 }
 //----Calculate the final Correlation Equation----//
 double[] corr = new double[ImageList.Count];
 for (i = 0; i < ImageList.Count; i++)
 corr[i] = rtop[i] / Math.Sqrt(rbot1