- 私は
imageView.image
(写真)から始めます。 imageView.image
処理のためにリモート サービス (マイクロソフトの顔検出)に送信 (POST)します。- リモート サービスは
CGRect
、画像上で検出された顔ごとに の JSON を返します。 - JSON を UIView にフィードして、四角形を描画します。のフレームで UIView を開始し
{0, 0, imageView.image.size.width, imageView.image.size.height}
ます。<--私の考えでは、のサイズに相当するフレームimageView.image
self.imageView
ORのサブビューとしてUIViewを追加しますself.view
(両方を試しました)
最終結果:
長方形は描画されますが、 では正しく表示されませんimageView.image
。つまり、顔ごとに生成された CGRects は、リモート サービスによって返されるように、画像の座標空間に対して相対的であると想定されていますが、カスタム ビューを追加すると表示されなくなります。
CGRects / 2の各値を(テストとして)除算すると、近似値を取得できますが、それでもオフになるため、何らかのスケーリングの問題があると思います。Microsoft のドキュメントでは、検出された顔は、画像内の顔の位置を Pixelsで示す四角形で返されると記載されています。しかし、パスを描くときに点として扱われていませんか?
imageView.image
また、ビューが送信された画像と同じ座標空間に一致するように 、のフレームに相当するフレームでビューを開始するべきではありませんか?
これは、各 CGRect を 2 で割って縮小しようとした場合のスクリーンショットの例です。
私は iOS が初めてで、本から離れて自己演習としてこれに取り組みました。必要に応じてより多くのコードを提供できます。あなたの洞察を前もってありがとう!
編集1
次のメソッドを介して各面の長方形を含む面属性の配列を反復処理するときに、各長方形のサブビューを追加します。(void)viewDidAppear:(BOOL)animated
- (void)buildFaceRects {
// build an array of CGRect dicts off of JSON returned from analized image
NSMutableArray *array = [self analizeImage:self.imageView.image];
// enumerate over array using block - each obj in array represents one face
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
// build dictionary of rects and attributes for the face
NSDictionary *json = [NSDictionary dictionaryWithObjectsAndKeys:obj[@"attributes"], @"attributes", obj[@"faceId"], @"faceId", obj[@"faceRectangle"], @"faceRectangle", nil];
// initiate face model object with dictionary
ZGCFace *face = [[ZGCFace alloc] initWithJSON:json];
NSLog(@"%@", face.faceId);
NSLog(@"%d", face.age);
NSLog(@"%@", face.gender);
NSLog(@"%f", face.faceRect.origin.x);
NSLog(@"%f", face.faceRect.origin.y);
NSLog(@"%f", face.faceRect.size.height);
NSLog(@"%f", face.faceRect.size.width);
// define frame for subview containing face rectangle
CGRect imageRect = CGRectMake(0, 0, self.imageView.image.size.width, self.imageView.image.size.height);
// initiate rectange subview with face info
ZGCFaceRectView *faceRect = [[ZGCFaceRectView alloc] initWithFace:face frame:imageRect];
// add view as subview of imageview (?)
[self.imageView addSubview:faceRect];
}];
}
編集2:
/* Image info */
UIImageView *iv = self.imageView;
UIImage *img = iv.image;
CGImageRef CGimg = img.CGImage;
// Bitmap dimensions [pixels]
NSUInteger imgWidth = CGImageGetWidth(CGimg);
NSUInteger imgHeight = CGImageGetHeight(CGimg);
NSLog(@"Image dimensions: %lux%lu", imgWidth, imgHeight);
// Image size pixels (size * scale)
CGSize imgSizeInPixels = CGSizeMake(img.size.width * img.scale, img.size.height * img.scale);
NSLog(@"image size in Pixels: %fx%f", imgSizeInPixels.width, imgSizeInPixels.height);
// Image size points
CGSize imgSizeInPoints = img.size;
NSLog(@"image size in Points: %fx%f", imgSizeInPoints.width, imgSizeInPoints.height);
// Calculate Image frame (within imgview) with a contentMode of UIViewContentModeScaleAspectFit
CGFloat imgScale = fminf(CGRectGetWidth(iv.bounds)/imgSizeInPoints.width, CGRectGetHeight(iv.bounds)/imgSizeInPoints.height);
CGSize scaledImgSize = CGSizeMake(imgSizeInPoints.width * imgScale, imgSizeInPoints.height * imgScale);
CGRect imgFrame = CGRectMake(roundf(0.5f*(CGRectGetWidth(iv.bounds)-scaledImgSize.width)), roundf(0.5f*(CGRectGetHeight(iv.bounds)-scaledImgSize.height)), roundf(scaledImgSize.width), roundf(scaledImgSize.height));
// initiate rectange subview with face info
ZGCFaceRectView *faceRect = [[ZGCFaceRectView alloc] initWithFace:face frame:imgFrame];
// add view as subview of image view
[iv addSubview:faceRect];
}];