When the user finally clicks in the middle of the window, the face recognition algorithm will begin training on all the collected faces. But it is important to make sure there have been enough faces or people collected, otherwise the program may crash. In general, this just requires making sure there is at least one face in the training set (which implies there is at least one person). But the Fisherfaces algorithm looks for comparisons between people, so if there are less than two people in the training set, it will also crash. So, we must check whether the selected face recognition algorithm is Fisherfaces. If it is, then we require at least two people with faces, otherwise we require at least one person with a face. If there isn't enough data, then the program goes back to the Collection mode so the user can add more faces before training.
To check there are at least two people with collected faces, we can make sure that when a user clicks on the Add Person button, a new person is only added if there isn't any empty person (that is, a person that was added but does not have any collected faces yet). If there are just two people, and we are using the Fisherfaces algorithm, then we must make sure an m_latestFaces reference was set for the last person during the Collection mode. Then, m_latestFaces[i] is initialized to -1 when there still haven't been any faces added to that person, and it becomes 0 or higher once faces for that person have been added. This is done as follows:
// Check if there is enough data to train from.
bool haveEnoughData = true;
if (!strcmp(facerecAlgorithm, "FaceRecognizer.Fisherfaces")) {
if ((m_numPersons < 2) ||
(m_numPersons == 2 && m_latestFaces[1] < 0) ) {
cout << "Fisherfaces needs >= 2 people!" << endl;
haveEnoughData = false;
}
}
if (m_numPersons < 1 || preprocessedFaces.size() <= 0 ||
preprocessedFaces.size() != faceLabels.size()) {
cout << "Need data before it can be learnt!" << endl;
haveEnoughData = false;
}
if (haveEnoughData) {
// Train collected faces using Eigenfaces or Fisherfaces.
model = learnCollectedFaces(preprocessedFaces, faceLabels,
facerecAlgorithm);
// Now that training is over, we can start recognizing!
m_mode = MODE_RECOGNITION;
}
else {
// Not enough training data, go back to Collection mode!
m_mode = MODE_COLLECT_FACES;
}
The training may take a fraction of a second, or it may take several seconds or even minutes, depending on how much data is collected. Once the training of collected faces is complete, the face recognition system will automatically enter the Recognition mode.