FaceTrack/main.cpp

312 lines
7.6 KiB
C++

// Include header files
#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <float.h>
#include <limits.h>
#include <time.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
// Create memory for calculations
static CvMemStorage *storage = 0;
// Create a new Haar classifier
static CvHaarClassifierCascade *cascade = 0;
// Function prototype for detecting and drawing an object from an image
void detect_and_draw(IplImage *image);
// Create a string that contains the cascade name
const char *cascade_name = "haarcascade_frontalface_alt.xml";
/* "haarcascade_profileface.xml";*/
int opensocket();
void closesocket(int iSocket);
int g_iSocket = -1;
void SetSpeed()
{
printf("Medium\n");
write(g_iSocket, "v", 1);
}
void MoveUp()
{
printf("Up\n");
write(g_iSocket, "w", 1);
}
void MoveDown()
{
printf("Down\n");
write(g_iSocket, "s", 1);
}
void MoveLeft()
{
printf("Left\n");
write(g_iSocket, "a", 1);
}
void MoveRight()
{
printf("Right\n");
write(g_iSocket, "d", 1);
}
void MoveStop()
{
write(g_iSocket, "q", 1);
printf("Stop\n");
}
void MoveFire()
{
write(g_iSocket, " ", 1);
printf("Fire\n");
}
// Main function, defines the entry point for the program.
int main(int argc, char **argv)
{
// Structure for getting video from camera or avi
CvCapture *capture = 0;
// Images to capture the frame from video or camera or from file
IplImage *frame, *frame_copy = 0;
// Used for calculations
int optlen = strlen("--cascade=");
// Input file name for avi or image file.
const char *input_name;
// Check for the correct usage of the command line
if (argc > 1 && strncmp(argv[1], "--cascade=", optlen) == 0)
{
cascade_name = argv[1] + optlen;
input_name = argc > 2 ? argv[2] : 0;
}
else
{
fprintf(stderr,
"Usage: facedetect --cascade=\"<cascade_path>\" [filename|camera_index]\n");
return -1;
/*input_name = argc > 1 ? argv[1] : 0;*/
}
// try to open a socket
g_iSocket = opensocket();
if (g_iSocket < 0)
{
printf("Error connecting to turret\n");
return -1;
}
SetSpeed();
// Load the HaarClassifierCascade
cascade = (CvHaarClassifierCascade *)cvLoad(cascade_name, 0, 0, 0);
// Check whether the cascade has loaded successfully. Else report and error and quit
if (!cascade)
{
fprintf(stderr, "ERROR: Could not load classifier cascade\n");
return -1;
}
// Allocate the memory storage
storage = cvCreateMemStorage(0);
// Find whether to detect the object from file or from camera.
if (!input_name || (isdigit(input_name[0]) && input_name[1] == '\0'))
capture = cvCaptureFromCAM(!input_name ? 0 : input_name[0] - '0');
else
capture = cvCaptureFromAVI(input_name);
// Create a new named window with title: result
cvNamedWindow("result", 1);
// Find if the capture is loaded successfully or not.
// If loaded succesfully, then:
if (capture)
{
// Capture from the camera.
for (;;)
{
// Capture the frame and load it in IplImage
if (!cvGrabFrame(capture))
break;
frame = cvRetrieveFrame(capture);
/*
if (frame->origin == IPL_ORIGIN_TL)
cvCopy(frame, frame_copy, 0);
// Else flip and copy the image
else
cvFlip(frame, frame_copy, 0);
*/
// Call the function to detect and draw the face
detect_and_draw(frame);
// Wait for a while before proceeding to the next frame
if (cvWaitKey(10) >= 0)
break;
}
// Release the images, and capture memory
cvReleaseImage(&frame);
cvReleaseCapture(&capture);
}
// Destroy the window previously created with filename: "result"
cvDestroyWindow("result");
// return 0 to indicate successfull execution of the program
return 0;
}
// Function to detect and draw any faces that is present in an image
void detect_and_draw(IplImage *imgIn)
{
int scale = 1;
// Create a new image based on the input image
IplImage *temp = cvCreateImage(cvSize(320, 240), imgIn->depth, imgIn->nChannels);
IplImage *imgPrc = cvCreateImage(cvSize(320, 240), imgIn->depth, 1);
cvResize(imgIn, temp, CV_INTER_LINEAR);
cvCvtColor(temp, imgPrc, CV_RGB2GRAY);
// cvConvert(img,temp);
// Create two points to represent the face locations
CvPoint pt1, pt2;
int i;
// Clear the memory storage which was used before
cvClearMemStorage(storage);
// Find whether the cascade is loaded, to find the faces. If yes, then:
if (cascade)
{
// There can be more than one face in an image. So create a growable sequence of faces.
// Detect the objects and store them in the sequence
// CvSeq* faces = cvHaarDetectObjects(imgPrc, cascade, storage, 1.1, 2,
// CV_HAAR_DO_CANNY_PRUNING, cvSize(40, 40));
CvSeq *faces = cvHaarDetectObjects(imgPrc, cascade, storage);
// Loop the number of faces found.
for (i = 0; i < (faces ? faces->total : 0); i++)
{
// Create a new rectangle for drawing the face
CvRect *r = (CvRect *)cvGetSeqElem(faces, i);
// Find the dimensions of the face,and scale it if necessary
pt1.x = r->x * scale;
pt2.x = (r->x + r->width) * scale;
pt1.y = r->y * scale;
pt2.y = (r->y + r->height) * scale;
// Draw the rectangle in the input image
cvRectangle(imgPrc, pt1, pt2, CV_RGB(255, 0, 0), 3, 8, 0);
// move turret in face direction
if (i == 0)
{
// move x deviation
if (imgPrc->width / 2 > pt1.x && imgPrc->width / 2 < pt2.x)
{
// printf("Face in rect X Axis\n");
if (imgPrc->height / 2 > pt1.y && imgPrc->height / 2 < pt2.y)
{
// ready to fire
// printf("Face in rect Y Axis\n");
MoveFire();
}
}
// move in x direction
if (imgPrc->width / 2 < pt1.x)
{
MoveRight();
}
else if (imgPrc->width / 2 > pt2.x)
{
MoveLeft();
}
else
{
// move in y direction
if (imgPrc->height / 2 < pt1.y)
{
MoveDown();
}
else if (imgPrc->height / 2 > pt2.y)
{
MoveUp();
}
}
}
}
if (i == 0)
MoveStop();
}
// Show the image in the window named "result"
cvShowImage("result", imgPrc);
// Release the temp image created.
cvReleaseImage(&temp);
}
int opensocket()
{
int sockfd, portno;
struct sockaddr_in serv_addr;
struct hostent *server;
portno = 8088;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
printf("ERROR opening socket\n");
server = gethostbyname("localhost");
if (server == NULL)
{
fprintf(stderr, "ERROR, no such host\n");
exit(0);
}
bzero((char *)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
printf("ERROR connecting\n");
// setup speed slow
write(sockfd, "v", 1);
return sockfd;
}
void closesocket(int iSocket)
{
close(iSocket);
}