2012-02-23 46 views
8

Tôi đang cố gắng viết một thường trình lấy UIImage và trả về UIImage mới chỉ chứa khuôn mặt. Điều này có vẻ rất đơn giản, nhưng bộ não của tôi đang gặp phải các vấn đề xung quanh không gian CoreImage vs. UIImage.Phát hiện khuôn mặt UIImage

Dưới đây là những điều cơ bản:

- (UIImage *)imageFromImage:(UIImage *)image inRect:(CGRect)rect { 
    CGImageRef sourceImageRef = [image CGImage]; 
    CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, rect); 
    UIImage *newImage = [UIImage imageWithCGImage:newImageRef]; 
    CGImageRelease(newImageRef); 
    return newImage; 
} 


-(UIImage *)getFaceImage:(UIImage *)picture { 
    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace 
              context:nil 
              options:[NSDictionary dictionaryWithObject: CIDetectorAccuracyHigh forKey: CIDetectorAccuracy]]; 

    CIImage *ciImage = [CIImage imageWithCGImage: [picture CGImage]]; 
    NSArray *features = [detector featuresInImage:ciImage]; 

    // For simplicity, I'm grabbing the first one in this code sample, 
    // and we can all pretend that the photo has one face for sure. :-) 
    CIFaceFeature *faceFeature = [features objectAtIndex:0]; 

    return imageFromImage:picture inRect:faceFeature.bounds; 
} 

Hình ảnh được trả về là từ hình ảnh lộn. Tôi đã thử điều chỉnh faceFeature.bounds bằng cách sử dụng một cái gì đó như thế này:

CGAffineTransform t = CGAffineTransformMakeScale(1.0f,-1.0f); 
CGRect newRect = CGRectApplyAffineTransform(faceFeature.bounds,t); 

... nhưng điều đó mang lại cho tôi kết quả bên ngoài hình ảnh.

Tôi chắc chắn có điều gì đó đơn giản để khắc phục điều này, nhưng thiếu tính toán từ dưới xuống và sau đó tạo ra một rect mới bằng cách sử dụng đó như là X, là có một cách "thích hợp" để làm điều này?

Cảm ơn!

Trả lời

3

Vì có dường như không phải là một cách đơn giản để làm được điều này, tôi chỉ viết một số mã để làm điều đó:

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); 

Điều này làm việc hấp dẫn.

+5

Tôi đang nhìn vào cùng một điều, bạn có thể giải thích tính toán bạn đã thực hiện cho trục y không ?. Và 'largeface' là gì? –

0

Không có cách nào đơn giản để đạt được điều này, vấn đề là hình ảnh từ camera iPhone luôn ở chế độ dọc và cài đặt siêu dữ liệu được sử dụng để hiển thị chính xác. Bạn cũng sẽ nhận được độ chính xác tốt hơn trong cuộc gọi phát hiện khuôn mặt của bạn nếu bạn nói cho nó quay vòng của hình ảnh trước. Chỉ để làm cho mọi thứ trở nên phức tạp, bạn phải truyền nó theo định dạng EXIF.

May mắn thay có một dự án mẫu táo mà bao gồm tất cả những điều này được gọi là Squarecam, tôi đề nghị bạn kiểm tra xem nó để biết chi tiết

+0

Vâng, tôi đã sẵn sàng cho việc xoay vòng hình ảnh. Vấn đề của tôi liên quan đến nguồn gốc khác nhau cho UIImage và các thói quen CG. –

5

Dễ dàng hơn và ít lộn xộn hơn khi chỉ sử dụng CIContext để cắt khuôn mặt của bạn khỏi hình ảnh. Một cái gì đó như thế này:

CGImageRef cgImage = [_ciContext createCGImage:[CIImage imageWithCGImage:inputImage.CGImage] fromRect:faceFeature.bounds]; 
UIImage *croppedFace = [UIImage imageWithCGImage:cgImage]; 

đâu inputImage là đối tượng UIImage của bạn và faceFeature đối tượng là loại CIFaceFeature mà bạn nhận được từ [CIDetector featuresInImage:] phương pháp.

Các vấn đề liên quan