Rect haarPatternDetection(CascadeClassifier classifier, Mat image, int imageWidthforDetection, Rect parentRect=Rect()) {
    double imageSizeScale = 1.0*image.size().width*1.0/image.size().height;
    Mat color_img = image.clone();
    Mat face_img, gray_img;
    imresize(color_img, imageWidthforDetection,face_img);
    cvtColor(face_img, gray_img, CV_BGR2GRAY);
    equalizeHist(gray_img, gray_img);
    vector<Rect> faceRectsVector;
    classifier.detectMultiScale(gray_img, faceRectsVector,1.2,3,
                                CV_HAAR_FIND_BIGGEST_OBJECT | CV_HAAR_SCALE_IMAGE );
    
    Rect faceRect(0,0,0,0);
    
    for (int i = 0; i < faceRectsVector.size(); i++) {
        drawBox(face_img, faceRectsVector[i]);
        if (faceRect.area() < faceRectsVector[i].area())
            faceRect = faceRectsVector[i];
    }
    drawBox(face_img, faceRect);
    //    imshow("rect",face_img);
    double x = 1.0*faceRect.x/(double)imageWidthforDetection;
    double y = 1.0*faceRect.y/(double)cvRound(imageWidthforDetection/imageSizeScale);
    double w = 1.0*faceRect.width/(double)imageWidthforDetection;
    double h = 1.0*faceRect.height/(double)cvRound(imageWidthforDetection/imageSizeScale);
    
    int bx = cvRound(x*image.size().width) ;;//+ parentRect.tl().x;
    int by = cvRound(y*image.size().height) ;//+ parentRect.tl().y;
    int bw = cvRound(w*image.size().width);
    int bh = cvRound(h*image.size().height);
    
    Rect biggerRect(bx,by,bw,bh);
    biggerRect += parentRect.tl();
    
    return biggerRect;
}
QRect DigikamImageFaceDelegate::largerFaceRect(const QModelIndex& index) const
{
    QRect rect = faceRect(index);

    if (rect.isNull())
    {
        return rect;
    }

    const int margin = FaceUtils::faceRectDisplayMargin();

    return rect.adjusted(-margin, -margin, margin, margin);
}
Exemple #3
0
Mat Detector::detect(string imgname){
	//cout<<"Debug: "<<debug<<endl;
	Mat resized;
	IplImage *frame = cvLoadImage(imgname.data(), 2|4);
	if (frame == NULL)
    {
      fprintf(stderr, "Cannot open image %s.Returning empty Mat...\n", imgname.data());
      return resized;
    }
	
	else if (frame->width < 100 || frame->height < 100)
    {
      fprintf(stderr, "image %s too small.Returning empty Mat...\n", imgname.data());
      cvReleaseImage(&frame);
	  return resized;
    }	
	else if (frame->width > 100000 || frame->height > 100000)
    {
      fprintf(stderr, "image %s too large.Returning empty Mat...\n", imgname.data());
      cvReleaseImage(&frame);
	  return resized;
    }
	
	// convert image to grayscale
    IplImage *frame_bw = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 1);
    cvConvertImage(frame, frame_bw);
	Mat frame_mat(frame, 1);
	// Smallest face size.
    CvSize minFeatureSize = cvSize(100, 100);
    int flags =  CV_HAAR_DO_CANNY_PRUNING;
    // How detailed should the search be.
    float search_scale_factor = 1.1f;
    CvMemStorage* storage;
    CvSeq* rects;
    int nFaces;
	
    storage = cvCreateMemStorage(0);
    cvClearMemStorage(storage);

    // Detect all the faces in the greyscale image.
   rects = cvHaarDetectObjects(frame_bw, faceCascade, storage, search_scale_factor, 2, flags, minFeatureSize);
    //rects = MBLBPDetectMultiScale(frame_bw, faceCascade, storage, 1229, 1, 50, 500);
	nFaces = rects->total;
	if (nFaces != 1){
		if (debug)
			printf("%d faces detected\n", nFaces);
		storage = cvCreateMemStorage(0);
		cvReleaseMemStorage(&storage);
		cvReleaseImage(&frame_bw);
		cvReleaseImage(&frame);	
		return resized;
	}
		
	int iface = 0;
	CvRect *r = (CvRect*)cvGetSeqElem(rects, iface);
	double* landmarks  = new double[2*fmodel->data.options.M];
	int bbox[4];
	bbox[0] = r->x;
	bbox[1] = r->y;
	bbox[2] = r->x + r->width;
	bbox[3] = r->y + r->height;
	
	// Detect landmarks
	flandmark_detect(frame_bw, bbox, fmodel, landmarks);
	
	//align faces
	double angle[3];
	angle[0] = atan((landmarks[7]-landmarks[9])/(landmarks[6]-landmarks[8]));
	angle[1] = atan((landmarks[11]-landmarks[13])/(landmarks[10]-landmarks[12]));
	angle[2] = atan((landmarks[3]-landmarks[5])/(landmarks[2]-landmarks[4]));
	//cout<<angle[0]*180<<" "<<angle[1]*180<<" "<<angle[2]*180<<endl;
	
	double angle_rotate = 0;
	if (angle[0] > angle[1]){
		if (angle[1] > angle[2])
			angle_rotate = angle[1];
		else if (angle[0] > angle[2])
			angle_rotate = angle[2];
		else
			angle_rotate = angle[0];
	}
	else{
		if (angle[1] < angle[2])
			angle_rotate = angle[1];
		else if (angle[2] < angle[0])
			angle_rotate = angle[0];
		else
			angle_rotate = angle[2];
	}
	Rect faceRect(r->x, r->y,r->width, r->height);

	//save face to tmp if debug
	if (debug){
		cvRectangle(frame, cvPoint(bbox[0], bbox[1]), cvPoint(bbox[2], bbox[3]), CV_RGB(255,0,0) );
		cvRectangle(frame, cvPoint(fmodel->bb[0], fmodel->bb[1]), cvPoint(fmodel->bb[2], fmodel->bb[3]), CV_RGB(0,0,255) );
		cvCircle(frame, cvPoint((int)landmarks[0], (int)landmarks[1]), 3, CV_RGB(0,0,255), CV_FILLED);
		cvCircle(frame, cvPoint(int(landmarks[2]), int(landmarks[3])), 3, CV_RGB(255,0,0), CV_FILLED);
		cvCircle(frame, cvPoint(int(landmarks[4]), int(landmarks[5])), 3, CV_RGB(255,0,0), CV_FILLED);
		cvCircle(frame, cvPoint(int(landmarks[6]), int(landmarks[7])), 3, CV_RGB(255,0,0), CV_FILLED);
		cvCircle(frame, cvPoint(int(landmarks[8]), int(landmarks[9])), 3, CV_RGB(255,0,0), CV_FILLED);
		cvCircle(frame, cvPoint(int(landmarks[10]), int(landmarks[11])), 3, CV_RGB(255,0,0), CV_FILLED);
		cvCircle(frame, cvPoint(int(landmarks[12]), int(landmarks[13])), 3, CV_RGB(255,0,0), CV_FILLED);
		cvCircle(frame, cvPoint(int(landmarks[14]), int(landmarks[15])), 3, CV_RGB(255,0,0), CV_FILLED);
		Mat face(frame, 0);
		Mat croppedFaceImage = face(faceRect).clone();
		Mat rotated = rotateImage(croppedFaceImage, angle_rotate * 180 / PI);
		resize(rotated, resized, Size(100, 100));
		imwrite( "./tmp/face.jpg" , resized );
	}
	delete [] landmarks;
	storage = cvCreateMemStorage(0);
	cvReleaseMemStorage(&storage);
	cvReleaseImage(&frame_bw);
	cvReleaseImage(&frame);
	
	if (faceRect.height < 50 && faceRect.width < 50){
		printf("Face too small: %d x %d\n", faceRect.height, faceRect.width);
		return resized;
	}
	Mat croppedFaceImage = frame_mat(faceRect).clone();
	Mat rotated = rotateImage(croppedFaceImage, angle_rotate * 180 / PI);
	resize(rotated, resized, Size(100, 100));
	return resized;
}