5

I used the below code to crop a face from an image, in my face detection code. But I am not getting the proper face images and I am getting some part of the image saved and not the face. What's wrong in my code?

_faceCascade.detectMultiScale(mat, faces, 1.1, 2, kHaarOptions, cv::Size(40, 40));

And inside the displayfaces functions am cropping with this code:

CGRect cropRect = CGRectMake(faces[i].x, faces[i].y, faces[i].width, faces[i].width);
CGImageRef cropped_img = CGImageCreateWithImageInRect(self.storeImage.CGImage, cropRect);
UIImage *img = [UIImage imageWithCGImage:cropped_img];
UIImageWriteToSavedPhotosAlbum( img, self,  nil,nil);

Am getting the correct co-ordinates of faces[i]. But the problem is only with cropping and setting ROI. Can some one help me in solving it?

I tried with the below code also, again am getting the same images. (i.e., am not getting the actual face image)

cv :: Mat image_roi;
cv::Rect roi(faces[i].x, faces[i].y, faces[i].width, faces[i].height);
cv::Mat(testMat, roi).copyTo(image_roi);
UIImage *img = [CaptureViewController imageWithCVMat:image_roi ];
UIImageWriteToSavedPhotosAlbum( img, self,  nil,nil);

Note: I am detecting the face in live video stream using opencv facedetect. I can get the green rectangle around the face. But I couldn't crop the face with face parameters. I also tried setting faceroi to detect eyes, even that fails. To narrow down the issue, the problem might be in setting ROI for the image?

Updated on 11/02/13:

I have Done Cropping as below but ROI is not Set properly and the image is not cropped well:

I found the issue for my above post ( thanks @Jameo to pointing me that its because of Rotation issue.) I have Rotated the Image as below.

UIImage *rotateImage = [[UIImage alloc] initWithCGImage: image.CGImage
                               scale: 1.0
                         orientation: UIImageOrientationRight];

And Cropped the image using the below Code:

// get sub image
+ (UIImage*) getSubImageFrom: (UIImage*) img WithRect: (CGRect) rect
{
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    // translated rectangle for drawing sub image
    CGRect drawRect = CGRectMake(-rect.origin.x, -rect.origin.y, img.size.width, img.size.height);
    // clip to the bounds of the image context
    // not strictly necessary as it will get clipped anyway?
    CGContextClipToRect(context, CGRectMake(0, 0, rect.size.width, rect.size.height));
    // draw image
    [img drawInRect:drawRect];
    // grab image
    UIImage* subImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return subImage;
}

The Image is cropped but Not with actual Co-ordinates.

My observations: 1) Am cropping the image with FaceRect which is returned by Affinetransform. Will this be a reason for wrong Co-ordinates or its because of bug in my code?? 2) I couldnt set ROI for an image before setting Affine Transform, what is the reason, Is this the procedure to set ROI?

faceRect = CGRectApplyAffineTransform(faceRect, t);

But Still the cropping is not done properly The difference is shown below:

Full Image:

Full Image

Cropped Image

enter image description here

Daniel
  • 10,864
  • 22
  • 84
  • 115
2vision2
  • 4,933
  • 16
  • 83
  • 164
  • Just curious, what image is this saving? is it just a different subset of the image? If so perhaps it is your ROI. I would definitely NSLog your ROI and see what it is trying to do – Jameo Feb 07 '13 at 19:39
  • @Jameo ya its saving the subset of my image and not the face. But I can detect the face with same faces[i]? I tried setting ROI of face for eye even that fails. Could you please have a look at the note section of my post. – 2vision2 Feb 07 '13 at 19:42
  • Do a log of the roi coordinates and see if they make sense, something like NSLog(@"Coorindates: %d, %d, %d, %d, ", faces[i].x, faces[i].y,faces[i].width, faces[i].height); and post the result. This will narrow down what is going on. Its either a problem with the **coordinates** your giving it, or a problem with the **way** your cropping it, but my guess is the coordinates – Jameo Feb 07 '13 at 19:56
  • x = 45,y = 105,width = 124,height = 124. and these are the values of faces[i].x, face[i].y,faces[i].width,faces[i].height respectively. But my main doubt is if the co-ordinates are wrong how am getting a rectangle around the face? – 2vision2 Feb 07 '13 at 20:00
  • Im not sure what you mean by your last sentence. I had alot of trouble with the rotation of the image though, could this be an issue?(to test you could also output the x, y, width, and height of the input frame) Then ask yourself, do these coordinates make sense for this screen? The reason I suspect this is because your cropping looks correct – Jameo Feb 07 '13 at 20:06
  • @Jameo if it an rotation isue whay should I do? https://github.com/aptogo/FaceTracker and this is the code I used for face detect. And trying to crop the detected face. Am trying this for the whole day and couldnt get a clue. – 2vision2 Feb 07 '13 at 20:12
  • @Jameo I also tried the second answer in this post for roatation issues. Still the same part of image its getting cropped. http://stackoverflow.com/questions/2635371/how-to-crop-the-uiimage – 2vision2 Feb 07 '13 at 20:18
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/24145/discussion-between-jameo-and-2vision2) – Jameo Feb 07 '13 at 20:19
  • adjust CGRect drawRect = CGRectMake(-rect.origin.x+yourvariable, -rect.origin.y, img.size.width, img.size.height); – 9to5ios Jul 07 '13 at 18:54

2 Answers2

1

what about this?

- (UIImage *) getSubImageFrom:(UIImage *)imageToCrop WithRect:(CGRect)rect {

    CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], rect);    
    UIImage *cropped = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);

    return cropped;    
}
Duck
  • 34,902
  • 47
  • 248
  • 470
0

try this to get the face coordinates :

CGRect newBounds = CGRectMake(faceFeature.bounds.origin.x, 
                              _picture.size.height - faceFeature.bounds.origin.y - largestFace.bounds.size.height, 
                              faceFeature.bounds.size.width, 
                              faceFeature.bounds.size.height);

and then crop the image using :

CGImageRef subImage = CGImageCreateWithImageInRect(image.CGImage, newBounds);
UIImage *croppedImage = [UIImage imageWithCGImage:subImage];
UIImageView *newView = [[UIImageView alloc] initWithImage:croppedImage];