Inverted (upside down) and not centered subview


#1

I’m having two problems (I think they are two separate problems but they maybe related).
I have created a subview but it is displaying upside down and centered too the right and up from the view’s center.

// Execute the method used to markFaces in background
    [self performSelectorInBackground:@selector(markFaces:) withObject:imageView];

// much farther down in code

-(void)markFaces:(UIImageView *)facePicture
{
    // draw a CI image with the previously loaded face detection picture
    CIImage* image = [CIImage imageWithCGImage:facePicture.image.CGImage];
    // create a face detector - since speed is not an issue we'll use a high accuracy detector
    CIDetector* detector = [CIDetector detectorOfType:CIDetectorTypeFace context:nil options:[NSDictionary dictionaryWithObject:CIDetectorAccuracyHigh forKey:CIDetectorAccuracy]];
    // create an array containing all the detected faces from the detector
    NSArray* features = [detector featuresInImage:image];
    // we'll iterate through every detected face.  CIFaceFeature provides us with the width for the entire face, and the coordinates of each eye and the mouth if detected.  Also provided are BOOL's for the eye's and mouth so we can check if they already exist.
    for(CIFaceFeature* faceFeature in features)
    {
        // get the width of the face
        CGFloat faceWidth = faceFeature.bounds.size.width;
        // create a UIView using the bounds of the face
        UIView* faceView = [[UIView alloc] initWithFrame:faceFeature.bounds];
        // add a border around the newly created UIView
        faceView.layer.borderWidth = 1;
        faceView.layer.borderColor = [[UIColor redColor] CGColor];
        // add the new view to create a box around the face
        [self->imageView addSubview]; // <<<----  needs to flip the entire subview to make everything right side up
    }
}

I’ve tried rotating the subview but it remains flipped. I’ve also tried moving the bounds but it stays askew. Please any suggestion would be greatly appreciated.


#2

I tried some face detection based on the documentation “Detecting Faces in an Image”. I loaded an image first then applied the face detection to it. Almost worked… my face rectangles are offset but it’s clear they would match up if I could figure out what the problem is. For me, there were no upside down image problems, just that offset issue.
I found some sample code that may solve your problems, the author does a “setTransform” to correct for flipping the image (and the window).
maniacdev.com/2011/11/tutorial-e … -in-ios-5/

Hope that helps.


#3

Huh… the face rectangles were upside down relative to the image, so I added them as subviews to a foundFaces view and flipped that instead of flipping the UIImageView containing the image - which would end up upside down, requiring another flip of the entire window, which moved the image from the top of the window to the bottom. Not good…

This way the image stays put and the face rectangles line up.

Here’s my AppDelegate.m code:

#import "AppDelegate.h"
#import "FaceFinderViewController.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    
    FaceFinderViewController *ffvc = [[FaceFinderViewController alloc] init];
    UINavigationController *masterNav = [[UINavigationController alloc] initWithRootViewController:ffvc];    
    [[self window] setRootViewController:masterNav];
    
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

And here’s my FaceFinderViewController.m

[code]#import “FaceFinderViewController.h”
#import <CoreImage/CoreImage.h>
#import <QuartzCore/QuartzCore.h>

@interface FaceFinderViewController ()
{
UIImageView *iv;
}
@end

@implementation FaceFinderViewController

  • (id)init
    {
    self = [super initWithNibName:nil bundle:nil];
    if (self) {
    UIBarButtonItem *bbi = [[UIBarButtonItem alloc]
    initWithTitle:@“Find Faces” style:UIBarButtonItemStyleBordered target:self action:@selector(markFaces:)];
    [[self navigationItem] setRightBarButtonItem:bbi];
    }
    return self;
    }

  • (void)loadView
    {
    UIView *vw = [[UIView alloc] initWithFrame:[self findTheViewFrame]];
    iv = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@“FaceTester.png”]];
    [vw addSubview:iv];
    [self setView:vw];
    }

  • (void)markFaces:(id)sender
    {
    CIImage *myImage = [CIImage imageWithCGImage:[[iv image] CGImage]];
    NSNumber *orientation = [NSNumber numberWithInt:[[iv image] imageOrientation]+1]; // ?

    // this is (mostly) right out of the developer docs for "Detecting Faces in an Image"
    CIContext *context = [CIContext contextWithOptions:nil]; // 1
    NSDictionary *opts = [NSDictionary dictionaryWithObject:CIDetectorAccuracyHigh forKey:CIDetectorAccuracy]; // 2
    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace context:context options:opts]; // 3

    opts = [NSDictionary dictionaryWithObject:orientation forKey:CIDetectorImageOrientation]; // 4
    NSArray *features = [detector featuresInImage:myImage options:opts];

    UIView foundFaces = [[UIView alloc] initWithFrame:[iv frame]];
    for(CIFaceFeature
    faceFeature in features) {
    // get the width of the face
    //CGFloat faceWidth = faceFeature.bounds.size.width;

      // create a UIView using the bounds of the face
      UIView* faceView = [[UIView alloc] initWithFrame:faceFeature.bounds];
    
      // add a border around the newly created UIView
      faceView.layer.borderWidth = 1;
      faceView.layer.borderColor = [[UIColor redColor] CGColor];
              
      // add the new view to create a box around the face
      [foundFaces addSubview];
    

    }
    // flip image on y-axis to match coordinate system used by core image
    [foundFaces setTransform:CGAffineTransformMakeScale(1, -1)];

    [[self view] addSubview:foundFaces];
    }

// Modified by me, based on code by Martin Wermers ( https://gist.github.com/Tafkadasoh/5206130 )

  • (CGRect)findTheViewFrame
    {
    CGRect bounds = [[UIScreen mainScreen] bounds];
    if ([[UIApplication sharedApplication] isStatusBarHidden] == NO) { // using “bounds” so, subtract status bar
    CGRect statusFrame = [[UIApplication sharedApplication] statusBarFrame];
    bounds.size.height -= statusFrame.size.height;
    }
    if (self.navigationController) { // subtract space taken by navigation controller
    if (self.navigationController.navigationBarHidden == NO) {
    bounds.size.height -= self.navigationController.navigationBar.bounds.size.height;
    }
    if (self.navigationController.toolbarHidden == NO) {
    bounds.size.height -= self.navigationController.toolbar.bounds.size.height;
    }
    }
    if (self.tabBarController) { // subtract space taken by tab bar controller
    bounds.size.height -= self.tabBarController.tabBar.bounds.size.height;
    }
    return bounds;
    }

@end
[/code]