Skip to content

Commit 5d5356a

Browse files
committed
server mod for socket communication with the client
1 parent 351a752 commit 5d5356a

File tree

6 files changed

+313
-7
lines changed

6 files changed

+313
-7
lines changed

face_recogition/detectObject.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ void detectLargestObject(const Mat &img, CascadeClassifier &cascade, Rect &large
9696
// How much the detections should be filtered out. This should depend on how bad false detections are to your system.
9797
// minNeighbors=2 means lots of good+bad detections, and minNeighbors=6 means only good detections are given but some are missed.
9898
int minNeighbors = 4;
99-
printf("scaledWidth = %d\n",scaledWidth);
99+
//printf("scaledWidth = %d\n",scaledWidth);
100100
// Perform Object or Face Detection, looking for just 1 object (the biggest in the image).
101101
vector<Rect> objects;
102102
detectObjectsCustom(img, cascade, objects, scaledWidth, flags, minFeatureSize, searchScaleFactor, minNeighbors);

face_recogition/main.cpp

+164-4
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ const bool preprocessLeftAndRightSeparately = true; // Preprocess left & right
7373
// Set to true if you want to see many windows created, showing various debug info. Set to 0 otherwise.
7474
bool m_debug = false;
7575

76-
76+
#include <signal.h>
7777
#include <stdio.h>
7878
#include <vector>
7979
#include <string>
@@ -98,9 +98,10 @@ using namespace std;
9898

9999
#if !defined VK_ESCAPE
100100
#define VK_ESCAPE 0x1B // Escape character (27)
101+
#define VK_TAB 0x9
101102
#endif
102103

103-
104+
int server_stop = 0;
104105
// Running mode for the Webcam-based interactive GUI program.
105106
enum MODES {MODE_STARTUP=0, MODE_DETECTION, MODE_COLLECT_FACES, MODE_TRAINING, MODE_RECOGNITION, MODE_DELETE_ALL, MODE_END};
106107
const char* MODE_NAMES[] = {"Startup", "Detection", "Collect Faces", "Training", "Recognition", "Delete All", "ERROR!"};
@@ -332,7 +333,7 @@ void recognizeAndTrainUsingWebcam(VideoCapture &videoCapture, CascadeClassifier
332333
// Since we have already initialized everything, lets start in Detection mode.
333334
m_mode = MODE_DETECTION;
334335
//dlx mod here First,a demo receive mat from zedboard use socket
335-
336+
/*
336337
int sockfd, newsockfd, portno;
337338
socklen_t clilen;
338339
char buffer[1024];
@@ -413,7 +414,7 @@ void recognizeAndTrainUsingWebcam(VideoCapture &videoCapture, CascadeClassifier
413414
414415
//waitKey(0);
415416
416-
417+
*/
417418
//
418419

419420
// Run forever, until the user hits Escape to "break" out of this loop.
@@ -715,14 +716,173 @@ void recognizeAndTrainUsingWebcam(VideoCapture &videoCapture, CascadeClassifier
715716
if (keypress == VK_ESCAPE) { // Escape Key
716717
// Quit the program!
717718
break;
719+
}else if(keypress == VK_TAB){
720+
//begin the server
721+
if (model.empty())
722+
{
723+
model = loadModel();
724+
//vector<int> getLabelsByString("labels");
725+
faceLabels = model->getLabelsByString("labels");
726+
}
727+
728+
729+
int sockfd, newsockfd, portno;
730+
socklen_t clilen;
731+
char buffer[1024]="welcome";
732+
char serverWelcome[10] = "welcome";
733+
char serverBye[5] = "bye";
734+
struct sockaddr_in serv_addr, cli_addr;
735+
int n;
736+
737+
//printf("sizeof int %d\n",sizeof(int));
738+
sockfd = socket(AF_INET, SOCK_STREAM, 0);
739+
if (sockfd < 0)
740+
perror("ERROR opening socket");
741+
bzero((char *) &serv_addr, sizeof(serv_addr));
742+
portno = 9001;
743+
serv_addr.sin_family = AF_INET;
744+
serv_addr.sin_addr.s_addr = INADDR_ANY;
745+
serv_addr.sin_port = htons(portno);
746+
if (bind(sockfd, (struct sockaddr *) &serv_addr,
747+
sizeof(serv_addr)) < 0)
748+
perror("ERROR on binding");
749+
750+
namedWindow( "Server", CV_WINDOW_AUTOSIZE );// Create a window for display.
751+
while(server_stop != 1)
752+
{
753+
printf("listen=====\n");
754+
listen(sockfd,5);
755+
//printf("listen=----\n");
756+
clilen = sizeof(cli_addr);
757+
//printf("accepting=====\n");
758+
newsockfd = accept(sockfd,
759+
(struct sockaddr *) &cli_addr,
760+
&clilen);
761+
printf("accepting-----\n");
762+
if (newsockfd < 0)
763+
perror("ERROR on accept");
764+
765+
n = send(newsockfd,serverWelcome,strlen(serverWelcome),0);
766+
printf("sebd n =%d\n",n);
767+
768+
bzero(buffer,1024);
769+
770+
771+
int rows = 0,cols = 0,total = 0;
772+
n = recv(newsockfd,buffer,43,0);
773+
if (n < 0) printf("ERROR reading from socket\n");
774+
//client printf("rows=%d , cols=%d , image.total()=%d \n",image.rows,image.cols,image.total());
775+
sscanf(buffer,"rows=%d , cols=%d , image.total()=%d \n",&rows,&cols,&total);
776+
printf(buffer);
777+
printf("get it,rows=%d , cols=%d , image.total()=%d \n",rows,cols,total);
778+
printf("\n");
779+
780+
Mat img = Mat::zeros( rows,cols, CV_8UC3);
781+
int imgSize = img.total()*img.elemSize();
782+
uchar sockData[imgSize];
783+
784+
for (int i = 0; i < imgSize; i += n) {
785+
if ((n = recv(newsockfd, sockData +i, imgSize - i, 0)) == -1) {
786+
perror("recv failed");
787+
}
788+
printf("rcv n =%d\n",n);
789+
if(n == 0)
790+
{
791+
waitKey(0);
792+
}
793+
}
794+
n = send(newsockfd,serverBye,strlen(serverBye),0);
795+
printf("sebd n =%d\n",n);
796+
close(newsockfd);
797+
798+
int ptr=0;
799+
for (int i = 0; i < img.rows; i++) {
800+
for (int j = 0; j < img.cols; j++) {
801+
img.at<cv::Vec3b>(i,j) = cv::Vec3b(sockData[ptr+ 0],sockData[ptr+1],sockData[ptr+2]);
802+
ptr=ptr+3;
803+
}
804+
}
805+
806+
printf("receive test ----rows =%d , cols = %d ,image.total() = %d \n",img.rows,img.cols,img.total());
807+
imshow("Server", img);
808+
//recognize the face
809+
810+
Rect faceRect; // Position of detected face.
811+
Rect searchedLeftEye, searchedRightEye; // top-left and top-right regions of the face, where eyes were searched.
812+
Point leftEye, rightEye; // Position of the detected eyes.
813+
814+
Mat preprocessedFace = getPreprocessedFaceFromClient(img, faceWidth, faceCascade, eyeCascade1, eyeCascade2, preprocessLeftAndRightSeparately, &faceRect, &leftEye, &rightEye, &searchedLeftEye, &searchedRightEye);
815+
816+
//printMatInfo(preprocessedFace,"preprocessedFace---");
817+
bool gotFaceAndEyes = false;
818+
if (preprocessedFace.data)
819+
gotFaceAndEyes = true;
820+
//std::cout << "preprocessedFaces.size()" << preprocessedFaces.size() << std::endl;
821+
//std::cout << "faceLabels.size()"<< faceLabels.size() << std::endl;
822+
std::cout << "gotFaceAndEyes" << gotFaceAndEyes << std::endl;
823+
//----recognize
824+
//if (gotFaceAndEyes && (preprocessedFaces.size() > 0) && (preprocessedFaces.size() == faceLabels.size())) {
825+
if(gotFaceAndEyes){
826+
// Generate a face approximation by back-projecting the eigenvectors & eigenvalues.
827+
Mat reconstructedFace;
828+
829+
reconstructedFace = reconstructFace(model, preprocessedFace);
830+
if (1)
831+
if (reconstructedFace.data){
832+
imshow("reconstructedFace", reconstructedFace);
833+
imshow("Server",preprocessedFace);
834+
//waitKey(0);
835+
}
836+
// Verify whether the reconstructed face looks like the preprocessed face, otherwise it is probably an unknown person.
837+
double similarity = getSimilarity(preprocessedFace, reconstructedFace);
838+
cout << ". Similarity: " << similarity << endl;
839+
string outputStr;
840+
if (similarity < UNKNOWN_PERSON_THRESHOLD) {
841+
// Identify who the person is in the preprocessed face image.
842+
std::cout << "test1" << std::endl;
843+
identity = model->predict(preprocessedFace);
844+
std::cout << "test2" << std::endl;
845+
outputStr = toString(identity);
846+
std::cout << "test3" << std::endl;
847+
}
848+
else {
849+
// Since the confidence is low, assume it is an unknown person.
850+
outputStr = "Unknown";
851+
}
852+
853+
//printf( "recong time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );
854+
855+
cout << "Identity: " << outputStr << ". Similarity: " << similarity << endl;
856+
857+
}
858+
859+
860+
//waitKey(0);
861+
//waitKey(0);
862+
}
863+
//Mat image(690,690,CV_8UC3,*buffer);
864+
//imwrite("/home/securitas/images/prova.jpg",image);
865+
866+
close(sockfd);
867+
868+
//imshow( "Server", img );
869+
//waitKey(0);
870+
//return;
718871
}
719872

873+
720874
}//end while
721875
}
722876

877+
void handle_sigtstp(int s) {//处理ctrz的
878+
printf("DLX-------REVEIVED ctrz\n");
879+
server_stop = 1;
880+
}
723881

724882
int main(int argc, char *argv[])
725883
{
884+
signal(SIGTSTP,handle_sigtstp);
885+
726886
CascadeClassifier faceCascade;
727887
CascadeClassifier eyeCascade1;
728888
CascadeClassifier eyeCascade2;

face_recogition/preprocessFace.cpp

+118
Original file line numberDiff line numberDiff line change
@@ -344,3 +344,121 @@ Mat getPreprocessedFace(Mat &srcImg, int desiredFaceWidth, CascadeClassifier &fa
344344
}
345345
return Mat();
346346
}
347+
348+
Mat getPreprocessedFaceFromClient(Mat &srcImg, int desiredFaceWidth, CascadeClassifier &faceCascade, CascadeClassifier &eyeCascade1, CascadeClassifier &eyeCascade2, bool doLeftAndRightSeparately, Rect *storeFaceRect, Point *storeLeftEye, Point *storeRightEye, Rect *searchedLeftEye, Rect *searchedRightEye)
349+
{
350+
// Use square faces.
351+
int desiredFaceHeight = desiredFaceWidth;
352+
353+
Mat faceImg = srcImg; // Get the detected face image.
354+
355+
// If the input image is not grayscale, then convert the BGR or BGRA color image to grayscale.
356+
Mat gray;
357+
if (faceImg.channels() == 3) {
358+
cvtColor(faceImg, gray, CV_BGR2GRAY);
359+
}
360+
else if (faceImg.channels() == 4) {
361+
cvtColor(faceImg, gray, CV_BGRA2GRAY);
362+
}
363+
else {
364+
// Access the input image directly, since it is already grayscale.
365+
gray = faceImg;
366+
}
367+
368+
// Search for the 2 eyes at the full resolution, since eye detection needs max resolution possible!
369+
Point leftEye, rightEye;
370+
371+
detectBothEyes(gray, eyeCascade1, eyeCascade2, leftEye, rightEye, searchedLeftEye, searchedRightEye);
372+
//printf( "eye time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );
373+
374+
375+
// Give the eye results to the caller if desired.
376+
if (storeLeftEye)
377+
*storeLeftEye = leftEye;
378+
if (storeRightEye)
379+
*storeRightEye = rightEye;
380+
std::cout << leftEye.x << rightEye.x << std::endl;
381+
// Check if both eyes were detected.
382+
if (leftEye.x >= 0 && rightEye.x >= 0) {
383+
384+
// Make the face image the same size as the training images.
385+
386+
// Since we found both eyes, lets rotate & scale & translate the face so that the 2 eyes
387+
// line up perfectly with ideal eye positions. This makes sure that eyes will be horizontal,
388+
// and not too far left or right of the face, etc.
389+
390+
// Get the center between the 2 eyes.
391+
Point2f eyesCenter = Point2f( (leftEye.x + rightEye.x) * 0.5f, (leftEye.y + rightEye.y) * 0.5f );
392+
// Get the angle between the 2 eyes.
393+
double dy = (rightEye.y - leftEye.y);
394+
double dx = (rightEye.x - leftEye.x);
395+
double len = sqrt(dx*dx + dy*dy);
396+
double angle = atan2(dy, dx) * 180.0/CV_PI; // Convert from radians to degrees.
397+
398+
// Hand measurements shown that the left eye center should ideally be at roughly (0.19, 0.14) of a scaled face image.
399+
const double DESIRED_RIGHT_EYE_X = (1.0f - DESIRED_LEFT_EYE_X);
400+
// Get the amount we need to scale the image to be the desired fixed size we want.
401+
double desiredLen = (DESIRED_RIGHT_EYE_X - DESIRED_LEFT_EYE_X) * desiredFaceWidth;
402+
double scale = desiredLen / len;
403+
// Get the transformation matrix for rotating and scaling the face to the desired angle & size.
404+
Mat rot_mat = getRotationMatrix2D(eyesCenter, angle, scale);
405+
// Shift the center of the eyes to be the desired center between the eyes.
406+
rot_mat.at<double>(0, 2) += desiredFaceWidth * 0.5f - eyesCenter.x;
407+
rot_mat.at<double>(1, 2) += desiredFaceHeight * DESIRED_LEFT_EYE_Y - eyesCenter.y;
408+
409+
// Rotate and scale and translate the image to the desired angle & size & position!
410+
// Note that we use 'w' for the height instead of 'h', because the input face has 1:1 aspect ratio.
411+
Mat warped = Mat(desiredFaceHeight, desiredFaceWidth, CV_8U, Scalar(128)); // Clear the output image to a default grey.
412+
warpAffine(gray, warped, rot_mat, warped.size());
413+
//imshow("warped", warped);
414+
415+
// Give the image a standard brightness and contrast, in case it was too dark or had low contrast.
416+
if (!doLeftAndRightSeparately) {
417+
// Do it on the whole face.
418+
equalizeHist(warped, warped);
419+
}
420+
else {
421+
// Do it seperately for the left and right sides of the face.
422+
equalizeLeftAndRightHalves(warped);
423+
}
424+
//imshow("equalized", warped);
425+
426+
// Use the "Bilateral Filter" to reduce pixel noise by smoothing the image, but keeping the sharp edges in the face.
427+
Mat filtered = Mat(warped.size(), CV_8U);
428+
bilateralFilter(warped, filtered, 0, 20.0, 2.0);
429+
//imshow("filtered", filtered);
430+
431+
// Filter out the corners of the face, since we mainly just care about the middle parts.
432+
// Draw a filled ellipse in the middle of the face-sized image.
433+
Mat mask = Mat(warped.size(), CV_8U, Scalar(0)); // Start with an empty mask.
434+
Point faceCenter = Point( desiredFaceWidth/2, cvRound(desiredFaceHeight * FACE_ELLIPSE_CY) );
435+
Size size = Size( cvRound(desiredFaceWidth * FACE_ELLIPSE_W), cvRound(desiredFaceHeight * FACE_ELLIPSE_H) );
436+
ellipse(mask, faceCenter, size, 0, 0, 360, Scalar(255), CV_FILLED);
437+
//imshow("mask", mask);
438+
439+
// Use the mask, to remove outside pixels.
440+
Mat dstImg = Mat(warped.size(), CV_8U, Scalar(128)); // Clear the output image to a default gray.
441+
/*
442+
namedWindow("filtered");
443+
imshow("filtered", filtered);
444+
namedWindow("dstImg");
445+
imshow("dstImg", dstImg);
446+
namedWindow("mask");
447+
imshow("mask", mask);
448+
*/
449+
// Apply the elliptical mask on the face.
450+
filtered.copyTo(dstImg, mask); // Copies non-masked pixels from filtered to dstImg.
451+
//imshow("dstImg", dstImg);
452+
453+
return dstImg;
454+
}
455+
/*
456+
else {
457+
// Since no eyes were found, just do a generic image resize.
458+
resize(gray, tmpImg, Size(w,h));
459+
}
460+
*/
461+
std::cout << "do not detecte eyes " << std::endl;
462+
463+
return Mat();
464+
}

face_recogition/preprocessFace.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,4 @@ void equalizeLeftAndRightHalves(Mat &faceImg);
5959
// If a face is found, it can store the rect coordinates into 'storeFaceRect' and 'storeLeftEye' & 'storeRightEye' if given,
6060
// and eye search regions into 'searchedLeftEye' & 'searchedRightEye' if given.
6161
Mat getPreprocessedFace(Mat &srcImg, int desiredFaceWidth, CascadeClassifier &faceCascade, CascadeClassifier &eyeCascade1, CascadeClassifier &eyeCascade2, bool doLeftAndRightSeparately, Rect *storeFaceRect = NULL, Point *storeLeftEye = NULL, Point *storeRightEye = NULL, Rect *searchedLeftEye = NULL, Rect *searchedRightEye = NULL);
62-
62+
Mat getPreprocessedFaceFromClient(Mat &srcImg, int desiredFaceWidth, CascadeClassifier &faceCascade, CascadeClassifier &eyeCascade1, CascadeClassifier &eyeCascade2, bool doLeftAndRightSeparately, Rect *storeFaceRect = NULL, Point *storeLeftEye = NULL, Point *storeRightEye = NULL, Rect *searchedLeftEye = NULL, Rect *searchedRightEye = NULL);

face_recogition/recognition.cpp

+28
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,38 @@ Ptr<FaceRecognizer> learnCollectedFaces(const vector<Mat> preprocessedFaces, con
5050

5151
// Do the actual training from the collected faces. Might take several seconds or minutes depending on input!
5252
model->train(preprocessedFaces, faceLabels);
53+
model->save("trainedModel.yml");
5354

5455
return model;
5556
}
57+
Ptr<FaceRecognizer> loadModel()
58+
{
59+
Ptr<FaceRecognizer> model;
60+
61+
bool haveContribModule = initModule_contrib();
62+
if (!haveContribModule) {
63+
cerr << "ERROR: The 'contrib' module is needed for FaceRecognizer but has not been loaded into OpenCV!" << endl;
64+
exit(1);
65+
}
5666

67+
model = Algorithm::create<FaceRecognizer>("FaceRecognizer.Fisherfaces");
68+
Mat labels;
69+
if (model.empty()) {
70+
cerr << "ERROR: The FaceRecognizer algorithm is not available in your version of OpenCV. Please update to OpenCV v2.4.1 or newer." << endl;
71+
exit(1);
72+
}
73+
try{
74+
model->load("trainedModel.yml");
75+
labels = model->get<Mat>("labels");
76+
}catch (cv::Exception &e){}
77+
78+
if (labels.rows <= 0){
79+
cerr << "ERROR: could not load trained data from trainedModel.yml" << endl;
80+
exit(1);
81+
}
82+
83+
return model;
84+
}
5785
// Convert the matrix row or column (float matrix) to a rectangular 8-bit image that can be displayed or saved.
5886
// Scales the values to be between 0 to 255.
5987
Mat getImageFrom1DFloatMat(const Mat matrixRow, int height)

face_recogition/recognition.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ using namespace std;
3838
// "FaceRecognizer.Fisherfaces": Fisherfaces, also referred to as LDA (Belhumeur et al, 1997).
3939
// "FaceRecognizer.LBPH": Local Binary Pattern Histograms (Ahonen et al, 2006).
4040
Ptr<FaceRecognizer> learnCollectedFaces(const vector<Mat> preprocessedFaces, const vector<int> faceLabels, const string facerecAlgorithm = "FaceRecognizer.Eigenfaces");
41-
41+
Ptr<FaceRecognizer> loadModel();
4242
// Show the internal face recognition data, to help debugging.
4343
void showTrainingDebugData(const Ptr<FaceRecognizer> model, const int faceWidth, const int faceHeight);
4444

0 commit comments

Comments
 (0)