﻿ ESSAY SAUCE

Essay:

Essay details:

• Subject area(s): Engineering
• Published on: 7th September 2019
• File format: Text
• Number of pages: 2

Text preview of this essay:

This page is a preview - download the full version of this essay above.

119 Hemenway Street

Boston, MA 02115

April 21, 2016

Director Hertz

National Espionage Unit

263 Snell Engineering Center Boston, MA 02115

Dear Director Hertz:

The attached report documents how I was able to create the integrated code which relied on both C++ and MATLAB to function. The algorithm for this mission was to create a code that would match information in a database, such as the text files provided to us by Dr. Hertz. C++ would create output files after which MATLAB would analyze. For the calculative side of things, C++ performs the functions then MATLAB uses that data to create plots of the data.

Regards,

Introduction:

We were assigned the task of creating a facial recognition program, which will aid areas with high security needs such as airports. This program intertwines both C++ and MATLAB. The C++ part relies on the program analyzing data from given text files, and then outputs the results into a file which is used in the MATLAB code afterwards.

First Part C++:

In order to successfully identify the person of interest, we first collect the data into arrays so that operations can be performed on the data. First we use the facedata.txt to read all the faces data. Each face is described with 5 points each. The file contains information about 25 faces. We organize this data into two different arrays, so that each array has a size of 25 X 5. First array contains the X coordinate values of the Points of Interest and the second one contains the Y coordinates of those points. We name these arrays facesX and facesY. After this step we write both these arrays to files namely facesX.txt and facesY.txt.

After that we ask the user to select a suspect they wish to match. There are currently only 3 suspects in our database. After the user selects a suspect, we obtain the face data for that suspect by reading the file suspect1.txt, suspect2.txt or suspect3.txt depending upon the choice of the user. We process this text file as we did before and create 2 1X5 arrays to hold the x and y coordinate data of the Points of Interest in Suspect’s face. We name these arrays suspectX and suspectY. After that we write both arrays to files and name those files suspectX.txt and suspectY.txt.

Now we compute the distances between the Points of interests in a person’s face by calculating the distance between two points by using the formula:

We calculate the distance between point 1 to 2, 2 to 3, 3 to 4, 4 to 5 and 5 to 1 for each face using the aforementioned formula.

We store the distances information in the array called facialDistances that has the size 25 X 5.

Similarly we repeat the above procedure for the suspect as well and store the distances in an array called suspectDistances that has a size 1X5.

After we have correctly calculated these distances we compute the Sum of Squared Distances that will also us to find the best match for the face under examination.

We calculate the ssd by using the formula:

We find the ssd of the suspect image with all the 25 faces and store this information in an array called ssd that has a size of 1X25.

Finally we write this array to a file as well and name that file ssd.txt.

C++ Psuedocode:

Initiate/declare variables

Open coordinates file

Use function to sort data

Create x coordinate array

Create y coordinate array

Ask user for input for suspect (Either suspect 1, 2, or 3)

Store the suspect data into array of 1 by 5

Have previous function loop calculations for distance between points

Create a 1 by 25 array to store data (two dimensional array)

Loop previous function to calculate score

Output values to be saved in a file

Second Part Matlab:

The next stage of our mission is performed using Matlab.

Matlab provides excellent methods to manipulate images and create plots.

First we load all the text files we created including the names.txt file that contains the names of the Persons of Interest into Matlab matrices.

After we have loaded the data successfully, we find out the index where the ssd matrix has the smallest value. The lowest value will mean that that face has the least difference from the face under examination.

We use this index to plot the corresponding face’s Points of interest with a + marker and the Points of Interest of the suspect with o markers. This plot shows us the most similar person’s Points of Interest. The title of the Plot displays the value of ssd for that face along with the name of that person.

MATLAB Psuedocode:

Open and read the ‘names’ text file

Create char array

Load the 5 data files created by C++ previously

Decide on smallest element in ssd array

Choose data points from the x and y coordinates

Plot data points, providing name of the person of interest and the ssd in title

Mission Result:

Result 1:

Result 2:

Result 3:

Conclusion:

We used simple face metrics to identify a person using only 5 points of interest on a person’s face. Advanced systems would use greater number of points of Interest to identify a face which will increase its reliability but will be slower than the simplistic version. We were able to find matches for all three test subjects.

Appendix - C++ Code:

#include <iostream>

#include <conio.h>

#include <fstream>

#include <sstream>

#include <string>

#include <vector>

#include <math.h>

#include <cstdlib>

using namespace std;

#define LENGTH_OF_ARRAY 74

string lines[LENGTH_OF_ARRAY];

double getLengthOfLineSegment(float x1, float y1, float x2, float y2)

{

double dx = x1 - x2;

double dy = y1 - y2;

double abX = abs(dx);

double abY = abs(dy);

double sqX = pow(abX, 2);

double sqY = pow(abY, 2);

double distance = sqrt(abs(sqX - sqY));

return distance;

}

double computeSSD(double suspectDistances, double persons)

{

double ssd = pow((suspectDistances - persons), 2)

+ pow((suspectDistances - persons), 2)

+ pow((suspectDistances - persons), 2)

+ pow((suspectDistances - persons), 2)

+ pow((suspectDistances - persons), 2);

return ssd;

}

int main()

{

// read file facedata.txt

float facesX;

float facesY;

double facialDistances;

double suspectDistances;

double ssd;

float suspectX;

float suspectY;

/*

- Open the file “facedata.txt”. This file contains the data for 25 persons of interest.

The first line contains the x-coordinates of the five points for the first person and

the second line contains the y-coordinates of the five points for the first person.

These two lines are then repeated for the remaining 24 people. Read and store this

data as a 2D, 25 x 5 array of x-coordinates and a 2D, 25 x 5 array of y-coordinates.

Save these arrays to two new files.

*/

int count = 0, xCount = 0, yCount = 0;

bool gettingX = true, gettingY = false;

string line;

vector<float> tokens;

// get the x and y coordinates of 25 faces 5 values each

{

{

lines[count] = line;

count++;

// cout << line << '\\n';

istringstream iss(line);

string token;

while (getline(iss, token, '\\t'))   // but we can specify a different one

{

tokens.push_back(stof(token));

}

for (int i = 0; i < tokens.size(); i++)

{

if (gettingX)

{

facesX[xCount][i] = tokens.at(i);

}

else if (gettingY)

{

facesY[yCount][i] = tokens.at(i);

}

else if (!gettingX && !gettingY)

{

// ignore, free space

}

}

if (gettingX)

{

xCount += 1;

gettingX = false;

gettingY = true;

}

else if (gettingY)

{

yCount += 1;

gettingY = false;

}

else

{

gettingX = true;

}

tokens.clear();

}

}

else

{

cout << "Unable to open file";

}

///////////////////////////////////////////// save them in seperate files ///////////////////////////////////

//////////////////////////////////////////// X coordinate write to file //////////////////////////////////////

ofstream fileWriterX("facesX.txt");

if (fileWriterX.is_open())

{

for (int i = 0; i < 25; i++)

{

string toWrite = "";

for (int j = 0; j < 5; j++)

{

stringstream ss(stringstream::in | stringstream::out);

ss << facesX[i][j];

string test = ss.str();

toWrite += test;

if (j != 4)

{

toWrite += '\\t';

}

else

{

toWrite += '\\n';

}

}

fileWriterX << toWrite;

}

fileWriterX.close();

}

else

{

cout << "Unable to open file";

}

//////////////////////////////////////////// Y coordinate write to file /////////////////////////////////////////

ofstream fileWriterY("facesY.txt");

if (fileWriterY.is_open())

{

for (int x = 0; x < 25; x++)

{

string toWriteY = "";

for (int y = 0; y < 5; y++)

{

stringstream st(stringstream::in | stringstream::out);

st << facesY[x][y];

string stringVal = st.str();

toWriteY += stringVal;

if (y != 4)

{

toWriteY += '\\t';

}

else

{

toWriteY += '\\n';

}

}

fileWriterY << toWriteY;

}

fileWriterY.close();

}

else

{

cout << "Unable to open file";

_getch();

return -1;

}

////////////////////////////////////////// match with an unknown entity //////////////////////////////////

int userChoice = -1;

bool valid = false;

while (!valid)

{

cout << "Which suspect would you like to Match?\\n";

cout << "1.Suspect 1\\n2.Suspect 2\\n3.Suspect 3\\n";

cin >> userChoice;

if (userChoice < 1 || userChoice > 3)

{

cout << "Invalid Choice...Please re-enter\\n";

}

else

{

valid = true;

}

}

/////////////////////////////////////// Read the suspect file //////////////////////////////////////////////

string suspectFileName = "suspect" + to_string(userChoice) + ".txt";

// get the x and y coordinates of 25 faces 5 values each

gettingX = true;

gettingY = false;

{

{

istringstream iss(line);

string token;

while (getline(iss, token, '\\t'))   // but we can specify a different one

{

tokens.push_back(stof(token));

}

for (int i = 0; i < tokens.size(); i++)

{

if (gettingX)

{

suspectX[i] = tokens.at(i);

}

else if (gettingY)

{

suspectY[i] = tokens.at(i);

}

else if (!gettingX && !gettingY)

{

// ignore, free space

}

}

if (gettingX)

{

gettingX = false;

gettingY = true;

}

else if (gettingY)

{

gettingY = false;

}

else

{

gettingX = true;

}

tokens.clear();

}

}

else

{

cout << "Unable to open file";

}

// suspect file read successfully

// save both arrays to new files

ofstream suspectWriterX("suspectX.txt");

if (suspectWriterX.is_open())

{

string toWriteX = "";

for (int x = 0; x < 5; x++)

{

stringstream st(stringstream::in | stringstream::out);

st << suspectX[x];

string stringVal = st.str();

toWriteX += stringVal;

if (x != 4)

{

toWriteX += '\\t';

}

else

{

toWriteX += '\\n';

}

}

suspectWriterX << toWriteX;

suspectWriterX.close();

}

else

{

cout << "Unable to open file";

_getch();

return -1;

}

ofstream suspectWriterY("suspectY.txt");

if (suspectWriterY.is_open())

{

string toWriteY = "";

for (int y = 0; y < 5; y++)

{

stringstream st(stringstream::in | stringstream::out);

st << suspectY[y];

string stringVal = st.str();

toWriteY += stringVal;

if (y != 4)

{

toWriteY += '\\t';

}

else

{

toWriteY += '\\n';

}

}

suspectWriterY << toWriteY;

suspectWriterY.close();

}

else

{

cout << "Unable to open file";

_getch();

return -1;

}

// suspects x y write to file successfull

/////////////////////////////////////////////// CALCULATE FACIAL DISTANCES ////////////////////////////////////////

int c = 0;

double distance = 0;

for (int s = 0; s < 25; s++)

{

c = 0;

for (int v = 0; v < 5; v++)

{

distance = 0;

if (v != 4)

{

distance = getLengthOfLineSegment(facesX[s][v], facesY[s][v], facesX[s][v + 1], facesY[s][v + 1]);

}

else

{

distance = getLengthOfLineSegment(facesX[s][v], facesY[s][v], facesX[s], facesY[s]);

}

facialDistances[s][c] = distance;

c++;

}

}

/////////////////////////////////////////  GET FACIAL DISTANCE FOR SUSPECTS //////////////////////////////////

for (int s = 0; s < 5; s++)

{

distance = 0;

if (s != 4)

{

distance = getLengthOfLineSegment(suspectX[s], suspectY[s], suspectX[s + 1], suspectY[s + 1]);

}

else

{

distance = getLengthOfLineSegment(suspectX[s], suspectY[s], suspectX, suspectY);

}

suspectDistances[s] = distance;

}

//////////////////////////////////////// CALCULATE SSD ///////////////////////////////////////////

ofstream ssdWriter("ssd.txt");

if (ssdWriter.is_open())

{

string ssWrite = "";

for (int count = 0; count < 25; count++)

{

stringstream st(stringstream::in | stringstream::out);

ssd[count] = computeSSD(suspectDistances, facialDistances[count]);

st << ssd[count];

string stringVal = st.str();

ssWrite += stringVal;

ssWrite += '\\n';

}

ssdWriter << ssWrite;

ssdWriter.close();

}

else

{

cout << "Unable to open file";

_getch();

return -1;

}

// provide results

cout << "All Files created Successfully!\\n";

_getch();

return 0;

}

Appendix - MATLAB Code:

clc;clear all;close all;

[firsts , lasts] = textread('names.txt', '%s %s');

names = char(strcat(firsts,{' ' },lasts));

[minSSDValue,index]=min(ssd);

figure

hold on

%plot(facesX(index),facesY(index),'*')

%plot(suspectX,suspectY,'-')

for i=1:5

plot(facesX(index,i),facesY(index,i),'+','Color','k')

plot(suspectX(i),suspectY(i),'o','Color','r')

end

s = strcat(firsts(index),{' '},lasts(index));

s = strcat(s,{' , ssd : '},num2str(ssd(index)));

title(s);

...(download the rest of the essay above)