Ejemplo n.º 1
0
bool FaceDetector::DetectFaces(const cv::Mat& cropped_img,
                               std::vector<cv::Rect>& faces_front,
                               std::vector<cv::Rect>& faces_profile) const{

    cv::Mat cascade_img;
    std::vector<cv::Rect>::iterator face_it;

    // create a copy of the image
    cropped_img.copyTo(cascade_img);

    // increase contrast of the image
    normalize(cascade_img, cascade_img, 0, 255, cv::NORM_MINMAX, CV_8UC1);



    // detect frontal faces
    classifier_front_.detectMultiScale(cascade_img,
                                            faces_front,
                                            classifier_front_scale_factor_,
                                            classifier_front_min_neighbours_,
                                            0|CV_HAAR_SCALE_IMAGE,
                                            classif_front_min_size_);

    // discard face if its not close to the top of the region, false positive
    face_it = faces_front.begin();
    for ( ; face_it != faces_front.end(); ) {
        // allowed area is the full width and three times the size of the detected face
        cv::Rect allowed_area (0, 0, cropped_img.cols, face_it->height * 3);

        // test if the rectangles intersect
        if ( !(allowed_area & *face_it).area()) {
            face_it = faces_front.erase(face_it);
        }else
            ++face_it;
    }

    // only search profile faces if the frontal face detection failed
    if (faces_front.empty())
    {
        classifier_profile_.detectMultiScale(cascade_img,
                                                  faces_profile,
                                                  classifier_profile_scale_factor_,
                                                  classifier_profile_min_neighbours_,
                                                  0|CV_HAAR_SCALE_IMAGE,
                                                  classif_profile_min_size_);

        // discard face if its not close to the top of the region, false positive
        face_it = faces_profile.begin();
        for ( ; face_it != faces_profile.end(); ) {
            // allowed area is the full width and three times the size of the detected face
            cv::Rect allowed_area (0, 0, cropped_img.cols, face_it->height * 3);

            // test if the rectangles intersect
            if ( !(allowed_area & *face_it).area()) {
                face_it = faces_profile.erase(face_it);
            }else
                ++face_it;
        }
    }


    // if debug mode is active and faces were found
    if (debug_mode_)
    {
        cv::Mat debugImg(cropped_img);

        for (uint j = 0; j < faces_front.size(); j++)
            cv::rectangle(debugImg, faces_front[j], cv::Scalar(0, 255, 0), 2, CV_AA);

        for (uint j = 0; j < faces_profile.size(); j++)
            cv::rectangle(debugImg, faces_profile[j], cv::Scalar(0, 0, 255), 2, CV_AA);


        cv::imwrite(debug_folder_ + ed::Entity::generateID().c_str() + "_face_detector.png", debugImg);
        cv::imshow("Face Detector Output", debugImg);
    }

    // return true if a face was found
    return (!faces_front.empty() || !faces_profile.empty());
}
Ejemplo n.º 2
0
static bool triangleFits(Triangle2i& triangle,SmartPointer<Texture> rgb,SmartPointer<Texture> alpha,std::set<Box2i>& queue,Color4f color)
{
	XgeDebugAssert(rgb->width==rgb->height);

	int texturedim=rgb->width;

	int w=triangle.right(); //width of the triangle (after the projection)
	int h=triangle.top();   //height of the triangle (after the projection)

	Box2i allowed_area(Vec2i(1,1),Vec2i(texturedim-2,texturedim-2),0);


	//try to fitTriangle2i
	for (std::set<Box2i>::iterator jt=queue.begin();jt!=queue.end() ;jt++)
	{
		Box2i box=*jt;



		Triangle2i candidates[4]=
		{
			triangle.scale(+1,+1).translate(  box.left(),  box.bottom()), //no mirroring
			triangle.scale(-1,+1).translate(w+box.left(),  box.bottom()), //mirror x
			triangle.scale(+1,-1).translate(  box.left(),h+box.bottom()), //mirror y
			triangle.scale(-1,-1).translate(w+box.left(),h+box.bottom())  //mirror x And mirrory
		};

		if (box.align)
		{
			//must start from the top of the area
			candidates[0]=candidates[0].translate(0,box.top()-candidates[0].top());
			candidates[1]=candidates[1].translate(0,box.top()-candidates[1].top());
			candidates[2]=candidates[2].translate(0,box.top()-candidates[2].top());
			candidates[3]=candidates[3].translate(0,box.top()-candidates[3].top());
		}

		while (candidates[0].right()<box.right())
		{
			//safety check
			XgeDebugAssert(
				   candidates[0].right()==candidates[1].right() 
				&& candidates[1].right()==candidates[2].right() 
				&& candidates[2].right()==candidates[3].right());

			for (int n=0;n<4;n++)
			{
				//first try to triangleRender
				if (triangleRender(candidates[n],rgb,alpha,color,box,false)) 
				{
					//store finally in the texture
					triangleRender(candidates[n],rgb,alpha,color,box,true);
					
					//these are the 2 other areas to find for fitting
					if (box.align)
					{
						Box2i box_right(Vec2i(candidates[n].centerx(),candidates[n].bottom()),Vec2i(box.right(),box.top()             ),1);
						Box2i box_down (Vec2i(box.left(),box.bottom())                       ,Vec2i(box.right(),candidates[n].bottom()-3),1);

						if (box_right.isValid() && allowed_area.contains(box_right)) queue.insert(box_right);
						if (box_down .isValid() && allowed_area.contains(box_down )) queue.insert(box_down );
					}
					else
					{
						Box2i box_right(Vec2i(candidates[n].centerx(),box.bottom() ) , Vec2i(box.right(),candidates[n].top()),0);
						Box2i box_up   (Vec2i(box.left(),candidates[n].top()+3   ) , Vec2i(box.right(),box.top()          ),0);

						if (box_right.isValid() && allowed_area.contains(box_right)) queue.insert(box_right);
						if (box_up   .isValid() && allowed_area.contains(box_up   )) queue.insert(box_up   );

						//special case when I do not want to waste space for the first triangle in row
						if (box.left()==1)
						{
							Box2i box_left (Vec2i(box.left(),box.bottom()),Vec2i(candidates[n].centerx(),candidates[n].top()),1);

							if (box_left.isValid() && allowed_area.contains(box_left)) queue.insert(box_left);
						}
					}

					queue.erase(jt);

					//modify the triangle and return ok
					triangle=candidates[n];
					return true;
				}
				
				//try a little more to the right (1 pixel)
				
				candidates[n]=candidates[n].translate(1,0);
			}
		}	
	} 

	//cannot fitTriangle2i in the texture, return false (the triangle has not been modified)
	return false;

}