Am trying to implement face detection using the PCA algorithm in C#,I have a button on my windows forms that is supposed to intitiate the learning process once it is clicked. It should use the images in a folder called training to compute the eigen values and eigen vectors so that it would be able to identify a similar image from the test folder. I have loaded all the 200 images in the training folder into an array list and now my problem is converting this collection of images to a one dimension vector so that i can be able to compute the co-variance matrix and eigen values for it. My code is listed below, if there is any way my code can be improved then your corrections are welcome

namespace PCA
{
    public partial class Form1 : Form
    {
        //the mapack library has been used to create new instances of the matrices
        //hold the width and height of an image in a variable
        static int height = 112;
        static int width = 92;
        //store the number of train images in a variable
        static int train_images = 200;
        //store the number of eigen values to keep in a variable
        static int eigen_values = 50;
        //initialize the matrix data
        PCALib.Matrix matrix_data = new PCALib.Matrix(train_images, width * height);
        //initialize the Target matrix data
        PCALib.Matrix T = new PCALib.Matrix(train_images,eigen_values);
        //initialize the mean of the images
        int image_mean = 0;
        //initialize the image array 
        List<Image> training = new List<Image>();
        //the path to the images
        static string path = "C:/Users/TimothyFarCry5/Documents/visual studio 2015/Projects/PCA/PCA/training";
        public Form1()
        {
            InitializeComponent();
        }
        //the method below starts the training process
        private void button1_Click(object sender, EventArgs e)
        {
            /*read all the images in the training folder into an array
            in this case the images are already in gray scale so we do not need to convert
            */
            var files = Directory.GetFiles(path);
            foreach(string r in files)
            {
                if(Regex.IsMatch(r, @"\.jpg$|\.png$|\.gif$"))
                {
                    training.Add(Image.FromFile(r));
                }
            }
            //convert the list of images to a one dimension vector

Dani AI

Generated

Short, practical checklist that fills the gap in the thread: how to turn images into numeric vectors, and a few PCA implementation tips that avoid the common memory/time traps.

First, make sure every training image is the same size and roughly aligned (same face crop/pose). Convert to grayscale, optionally apply histogram equalization or simple contrast normalization, then flatten each image into a single numeric vector. Rewriting PCA from scratch is fine for learning, but for production consider a well-tested library such as Accord.NET (or OpenCV/EmguCV) as suggested.

Example: efficient C# routine to convert a Bitmap to a normalized double array (one-dimension vector):

public static double[] BitmapToVector(Bitmap bmp)
{
    int w = bmp.Width, h = bmp.Height;
    var rect = new Rectangle(0, 0, w, h);
    var bd = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
    int stride = Math.Abs(bd.Stride);
    int bytes = stride * h;
    byte[] rgb = new byte[bytes];
    System.Runtime.InteropServices.Marshal.Copy(bd.Scan0, rgb, 0, bytes);
    bmp.UnlockBits(bd);

    double[] vec = new double[w * h];
    for (int y = 0; y < h; y++)
    {
        int row = y * stride;
        for (int x = 0; x < w; x++)
        {
            int i = row + x * 3;
            double gray = (0.299 * rgb[i + 2] + 0.587 * rgb[i + 1] + 0.114 * rgb[i]) / 255.0;
            vec[y * w + x] = gray;
        }
    }
    return vec;
}

PCA notes (practical): build a data matrix A where each column is a mean-subtracted image vector. If image dimension D is much larger than sample count N, compute eigenpairs of the N-by-N matrix A^T A, then recover the D-length eigenfaces via v = A * u / sqrt(lambda). Alternatively run SVD on A directly for numerical stability. Always subtract the mean image before eigen decomposition and normalize eigenfaces before projecting.

Debug tips: check mean-subtracted vectors visually (reconstruct an image), verify eigenfaces look face-like, use Euclidean or cosine distance on projected coefficients, and set a conservative recognition threshold. Mention to : correct the tag if needed and prefer library implementations for robust behavior; re-implementation is a good learning exercise. For PCA theory and eigenface background see Eigenface — Wikipedia and consider the Accord.NET project for ready-made routines.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.