Skip to content
AMontagu edited this page Aug 17, 2015 · 20 revisions

Video

Class Overview

Video class allow the developpeur to launch a windows which stream a video flux. It can also on this stream detect the visage, smile and eyes. Some bonus functions exist likes a face tracker for know which side of the windows the bigger face is detected or an other who return sentences who saids if the face detected are smiling. All the video analyze is based on OpenCV 3.0 open source library.

Public Constructors

  • Video();

Initialize a new instance of Video with any camera found.

  • Video(int numberCam);

Initialize a new instance of Video with the number of the device what we would use.

numberCam: Id of the camera you want to use.

Public Methods

  • int start();

Start to get frame from the camera and print them in a windows. If some detection is activated start() will print the circle or the rectangle around the detected object. It need to be launched in threads.

  • void startAllDetect();

Start the detection of faces, eyes and smiles in the video stream. start() function need to be in execution.

  • void stopAllDetect();

Stop all the detection running in the video stream.

  • void startFaceDetect();

Start the detection of faces in the video stream. start() function need to be in execution.

  • void stopFaceDetect();

Stop the face detection running in the video stream.

  • void startSmileDetect();

Start the detection of smiles in the video stream. start() function need to be in execution.

  • void stopSmileDetect();

Stop the smile detection running in the video stream.

  • void startEyeDetect();

Start the detection of eyes in the video stream. start() function need to be in execution.

  • void stopEyeDetect();

Stop the Eye detection running in the video stream.

  • void startCustomDetect(cv::CascadeClassifier& cascade, int precision);

Start the detection of custom object in the video stream. start() function need to be in execution.

cascade: CascadeClassifier object of the object you want to detect on the frame.

precision: Specify how much neighbors each rectangle retain should have.If the detection is accurate there will be a lot of neighbors.

  • void stopCustomDetect();

Stop the custom object detection running in the video stream.

  • int faceDetect(cv::Mat& img);

Analize a frame and try to find a face on it. If facedetect() find a face it will store the face into a classe variable that start() function will use for print circle or rectangle around.

img: Frame in which research faces.

  • int eyeDetect(cv::Mat& img, int width, int height);

Analize a face frame and try to find eyes on it. If eyeDetect() find eyes it will store the face into a classe variable that start() function will use for print circle or rectangle around.

img: Frame in which research eyes. Best used with a face image.

width: Width position of the img parameter. Used for find the right position in the principal frame captured by the cam.

height: Height position of the img parameter. Used for find the right position in the principal frame captured by the cam.

  • int smileDetect(cv::Mat& img, int width, int height);

Analize a face frame and try to find smile on it. If eyeDetect() find a smile it will store the face into a classe variable that start() function will use for print circle or rectangle around.

img: Frame in which research smile. Best used with a face image.

width: Width position of the img parameter. Used for find the right position in the principal frame captured by the cam.

height: Height position of the img parameter. Used for find the right position in the principal frame captured by the cam.

  • int customDetect(cv::Mat& img);

Analize a frame and try to find an object like the haarcascade that the user give to compare in startCustomdetect() funtcion. If customDetect() find a face it will store the custom obbject into a classe variable that start() function will use for print circle or rectangle around.

img: Frame in which research the custom object.

  • void draw(cv::Rect rectangle, cv::Mat &img, cv::Scalar color);

Draw a circle or a rectangle at the rectangle variable position with the color variable on the img frame.

rectangle: Rect object that defines the size and the position of the draw.

img: Specify on which image we are drawing.

color: Specify the color of the draw.

  • void addLabel(std::string label, int index);

Add text in a vector and the vector index of the face associated to the text. If the vector is not empty sthe start() function will print all the label.

label: Name of the face recognized.

index: Vector index of the face recognized.

  • void clearLabel();

Remove all the text in the vector for stopping printing name.

  • int getFaceNumber();

Return the number of face detected in the current frame.

  • int getSmileNumber();

Return the number of smile detected in the current frame.

  • int getEyeNumber();

Return the number of eyes detected in the current frame.

  • int getObjectNumber();

Return the number of custom object detected in the current frame.

  • bool getDetectFaceOn();

Return true if the face detection process is running.

  • std::vectorcv::Mat getLastFacesDetected();

Return all the image of the faces detected on the last camera frame before the call of the function.

  • std::vector getVectorSmiling();

Return a booleen vector. The size of a vector is the number of detected face and the value is true is the face is smiling and false otherwise.

  • void printVectorSmilingData();

Print to the console whiche face are smiling or not.

  • int faceTracking(cv::Rect faceToTrack, cv::Mat& frame);

Return 1 if the face is on the right side of the windows, 2 if it is on the left and 0 if it is on the cente.

faceToTrack: Position and size of the face you want to track.

frame: The frame in which there is the face to track.

  • int getTracking();

Get the value returned by faceTracking.

  • void setImgToPrint(cv::Mat img);

Set an image in _imgToPrint variable for display her in the video threads. Allow the user to see which face is detected to know if the recognition is good and if he need to add the image to the database.

img: Give the image to display in a other openCv windows.

  • cv::Mat getImgToPrint();

Get the image displayed in parallele of the video stream.

Sample

This is the basic sample for Video class. Uncomment line for the experiment "bonus" functions :

#include "Video.h"
#include "Voice.h"
#include <thread>

/*###############################################################################################################################
#																																#
#												Sample for video detection  													#
#																																#
#################################################################################################################################*/


int main(int argc, const char** argv)
{
	std::thread t[1];
	// Video is the class for use video and detection
	Video myVideo(0); //0 is the defaut camera, use -1 for any cammera or a number between 1 to 99

	bool done = false;
	time_t timer;
	time(&timer); //set timer to the current date in ms in

	//CascadeClassifier customCascade;
	//customCascade.load("../../../data/haarcascades/haarcascade_frontalface_alt.xml"); //for test Custom detect use with face haar

	//Launch video in a thread
	t[0] = std::thread([&] {myVideo.start(); });

	while (true)
	{
		//We wait two seconds before to use the detection (the programs will wait the time that te detection begin) 
		if (abs(time(NULL) - timer) > 2 && !done)
		{
			//For use the detection program uncomment the follows Line.
			//Smile and Eye detect works only with face Detect
			//All detect is face + smile + eye
			myVideo.startAllDetect();
			//myVideo.startFaceDetect();
			//myVideo.startEyeDetect();
			//myVideo.startSmileDetect();
			//myVideo.startCustomDetect(customCascade,3);
			done = true;
		}
		//Show the number of the spcified object
		//cout << "nombre de visage detecter : " << myVideo.getFaceNumber() << endl;

		//Says how many faces are detected and if they are smiling or not
		//myVideo.printVectorSmilingData();

		//Says where the bigger face detected is
		//if (myVideo.getTracking() == 1)
		//{
			//cout << "the face is on the right" << endl;
		//}
		//else if (myVideo.getTracking() == 2)
		//{
			//cout << "the face is on the left" << endl;
		//}
		//else
		//{
			//cout << "the face is on the center" << endl;
		//}

		cv::waitKey(1);
	}

	return 0;
}

How To Personnalize

You can change the draw refresh frequency. Thus change will affect the user perception. If you raise it the user will think that the program is slow but more specific. If you decreases it the drawing will change quickly so they are more chance that some error come but the drawing will follow the detected object very quickly.

For change this settings is here : if ((double)cvGetTickCount() - time > 400000)

400000 = 400ms = 0,4s is for me the best choice and the correct values are for me 0,2s to 0,6s


In Video::start() functions you can change the color of the drawing : draw(*r, frame, CV_RGB(0, 255, 255));

Change 0, 255, 255 with the color of your choice.


For each detect function there is a function that is called detectMultiScale(). This is the function who returns the rect where the detected object is. For example : _faceCascade.detectMultiScale(smallImg, _averageFacesRect, 1.1, 3, 1, cv::Size(30, 30), cv::Size(400, 400));

The parameters of this function are very important and if you have a problem with the precision of the detection is here that you need to manage. For more informations : http://stackoverflow.com/questions/20801015/recommended-values-for-opencv-detectmultiscale-parameters


You can also, for raise the accuracy, only add detected object in a logical area. For exemple for smile I print them only if they are below the half of the face. the code for find it quickly :

for (std::vector<cv::Rect>::iterator r = averageSmilesRectTemp.begin(); r != averageSmilesRectTemp.end(); r++, smileNumberTemp++)
{
	if (r->y > img.size().height / 2 && r->x + r->width / 2 > img.size().width / 2 - 25 && r->x + r->width / 2 < img.size().width / 2 + 25 && _averageSmilesRect.empty())
	{
		r->x += width;
		r->y += height;
		_averageSmilesRect.push_back(*r);
	}
}
Clone this wiki locally