.03 2013

CloudAR API βを使ってみる(5)

Tasakiです。


これまで、数回に渡ってお送りしてきたCloudAR APIのアプリでの使い方もいよいよ大詰めです。
APIのレスポンスデータの取り扱い方に触れてみたいと思います。
前回、通信結果のイベントを取得するところまで実装していました。
今回はそこで得た結果を解析し、求めるデータを抽出するまでを解説したいと思います。
追加分のソースを以下に記載します。

@interface CATMainViewController ()

@property (nonatomic, strong) AVCaptureVideoPreviewLayer *captureVideoPreviewLayer;
@property (nonatomic, strong) AVCaptureSession *captureSession;

@property (strong) UIImage *capturedImage;


- (void) initCaptureSession;
- (void) startCaptureSession;
- (void) stopCaptureSession;

- (void) cameraPreviewTouched:(UIGestureRecognizer *) sender;

- (void) respondWithData:(NSData *) data;

@end

@implementation CATMainViewController

- (void) respondWithData:(NSData *) data {
NSError *error = nil;
// 正常データはJSON解析を行う
NSDictionary *responseJson = [NSJSONSerialization JSONObjectWithData: data
options: 0
error: &error];
if (responseJson != nil) {
NSDictionary *result = responseJson[@"cloudarApi"];
CFBooleanRef succeeded = (__bridge CFBooleanRef) result[@"success"];
if (succeeded == kCFBooleanTrue) {
NSArray *matchedInfoArray = result[@"detectInfo"];
if (matchedInfoArray.count > 0) {
// 最も一致した可能性の高い画像に紐づくデータを表示
NSDictionary *matchedInfo = matchedInfoArray[0];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle: @"認識成功"
message: matchedInfo[@"value"]
delegate: nil
cancelButtonTitle: @"OK"
otherButtonTitles: nil];
[alertView show];
} else {
// 画像認識失敗
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle: @"認識失敗"
message: nil
delegate: nil
cancelButtonTitle: @"OK"
otherButtonTitles: nil];
[alertView show];
}
} else {
// エラー
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle: @"エラー"
message: result[@"errorMessage"]
delegate: nil
cancelButtonTitle: @"OK"
otherButtonTitles: nil];
[alertView show];
}
}
}

- (void) cameraPreviewTouched:(UIGestureRecognizer *) sender {
if (self.capturedImage != nil) {
// リクエストパラメータ作成
NSData *capturedImagePNGData = UIImagePNGRepresentation(self.capturedImage);
NSCharacterSet *abCharacterSet = [NSCharacterSet alphanumericCharacterSet];
NSString *base64ImageData = [[capturedImagePNGData base64EncodedStringWithOptions: 0] stringByAddingPercentEncodingWithAllowedCharacters: abCharacterSet];
NSString *requestBodyString = [NSString stringWithFormat: @"apiKey=%@&binData=%@",
CloudARAPIKey, base64ImageData];
NSData *requestBodyData = [requestBodyString dataUsingEncoding: NSUTF8StringEncoding];

// URLリクエスト作成
NSURL *apiURL = [NSURL URLWithString: @"http://api.ns-cloudar.com/api/marker/v1/imageSearch.json"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: apiURL];
[request setHTTPMethod: @"POST"];
[request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)requestBodyData.length]
forHTTPHeaderField: @"Content-Length"];
[request setHTTPBody: requestBodyData];

// 通信開始
[NSURLConnection sendAsynchronousRequest: request
queue:[NSOperationQueue mainQueue]
completionHandler: ^(NSURLResponse *response, NSData *data, NSError *error) {
// サーバ応答対応
if ([response isKindOfClass:[NSHTTPURLResponse class]] &&
data != nil && error == nil) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
if (httpResponse.statusCode == 200 ||
httpResponse.statusCode == 403) {
[self respondWithData: data];
} else {
NSString *title = [NSString stringWithFormat: @"HTTP status %ld", (long) httpResponse.statusCode];
NSString *dataString = [[NSString alloc] initWithData: data
encoding: NSUTF8StringEncoding];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle: title
message: dataString
delegate: nil
cancelButtonTitle: @"OK"
otherButtonTitles: nil];
[alertView show];
}
}
}];
}
}


@end



見てもらえばすぐに分かると思いますが、成功または失敗時の結果をアラートで表示するだけのシンプルな作りです。

まず、NSURLConnectionのsendAsynchronousRequest:queue:completionHandler:の結果を受け取るブロックcompletionHandler:内にてresponseというパラメータがありますので、このオブジェクトからHTTPステータスを取り出して、200か403なら結果がJSON(またはXML)で返ってきているので、自前の解析用のメソッドrespondWithData:にdataを渡します。
それ以外であれば、それ以外のデータ(主にHTML)が返っているのでステータスコードとボディをそのまま表示するようにしています。

で、肝心のrespondWithData:の内容についてですが、データ構造はこちらのレスポンスフィールド(正常系)と(異常系)を参考にします。

これによると管理ページで登録した文字列は、正常系データにおいてcloudarApi>detectInfo>valueというキーに保持されていることが分かります。

そこで、まず正常系か異常系かを判断するためにsuccessというキーの値を使います。
これが真なら正常系、偽なら異常系ということですね。
1つ注意しておくべきことは、画像認識に成功した場合も失敗した場合もこのsuccessの値は真になっているということです。
認識に成功したかどうかは次のdetectInfoを使用します。

正常系であった場合はdetectInfoというキーを見ます。
この値は配列になっていて、確度の高い画像の順に並んでいます。
全く該当しない場合(=認識失敗)の場合、この配列は空になっています。
上記の例では、確度の一番高いマーカー(=配列の先頭)のデータをアラートビューに表示しようとしています。

さて、これで「CloudAR APIβを利用して、カメラの映像にマーカーが映っていたら何かしらのアクションをする」という機能が実装できました。

実際にカメラをかざして認識率の精度を確かめてみて下さい。
関連記事
スポンサーサイト



Comment

-
このコメントは管理者の承認待ちです
2014.07.14 16:25
-
このコメントは管理者の承認待ちです
2014.07.16 15:21
-
このコメントは管理者の承認待ちです
2014.07.16 16:26
-
このコメントは管理者の承認待ちです
2014.07.18 18:13
-
このコメントは管理者の承認待ちです
2014.07.22 02:20
-
このコメントは管理者の承認待ちです
2014.07.28 19:17
-
このコメントは管理者の承認待ちです
2014.07.30 14:53

Post comment

  • comment
  • secret
  • 管理者にだけ表示を許可する

Trackback

trackbackURL:http://appteam.blog114.fc2.com/tb.php/282-f4a13bf6

ブログ内検索

関連リンク

製品情報

最新記事

カテゴリ

プロフィール

neoxneo



NEXT-SYSTEM iOS Developers Blog


  • UTO:
    カナダ版iPhone4Sは、マナーモードでシャッター音がならない…


  • Ehara:
    ...


  • Hayate:
    ...


  • Tasaki:
    Developer登録完了...したのはいいけど


  • Ueda:
    ...



リンク