apeescape2.com
  • メイン
  • ツールとチュートリアル
  • 技術
  • 仕事の未来
  • 分散チーム
モバイル

OpenCVチュートリアル:iOSでMSERを使用したリアルタイムのオブジェクト検出

過去数年間で、携帯電話の平均パフォーマンスは大幅に向上しました。 CPUの処理能力やRAMの容量が非常に大きい場合でも、モバイルハードウェアで計算量の多いタスクを実行するのが簡単になりました。これらのモバイルテクノロジーは正しい方向に向かっていますが、特に拡張現実、仮想現実、人工知能の出現により、モバイルプラットフォームでやるべきことはまだたくさんあります。

コンピュータビジョンの主な課題は、画像内の関心のあるオブジェクトを検出することです。人間の目と脳は並外れた仕事をし、そして これをマシンで複製する まだ夢です。ここ数十年にわたって、マシンでこれを模倣するためのアプローチが開発され、それはますます良くなっています。

このチュートリアルでは、画像内のブロブの検出に使用されるアルゴリズムについて説明します。また、オープンソースライブラリであるOpenCVのアルゴリズムを使用して実装します プロトタイプのiPhoneアプリケーション リアカメラを使用して画像を取得し、その中のオブジェクトを検出します。



OpenCVチュートリアル

OpenCV は、主要なコンピュータビジョンと機械学習アルゴリズムの実装を提供するオープンソースライブラリです。顔、ポーカーテーブルのトランプ、または任意の画像に効果を追加するための単純なアプリケーションを検出するアプリケーションを実装する場合は、OpenCVが最適です。

OpenCVはC / C ++で記述されており、すべての主要なプラットフォーム用のラッパーライブラリがあります。これにより、特に簡単に使用できます。 iOS環境 。 Objective-C内で使用するには iOSアプリケーション 、ダウンロード 公式ウェブサイトからのOpenCViOSフレームワーク 。 iOS用OpenCVのバージョン2.4.11(この記事では使用していることを前提としています)を使用していることを確認してください。最新バージョンの3.0では、ヘッダーファイルの編成方法に互換性を損なう変更がいくつかあります。インストール方法の詳細情報は そのウェブサイトに文書化 。

MSER

MSER は、Maximally Stable Extremal Regionsの略で、画像内のブロブ検出に使用できる多くの方法の1つです。簡単に言うと、アルゴリズムは、外側の境界ピクセルの強度が内側の境界のピクセル強度よりも高い(指定されたしきい値だけ)連続したピクセルのセットを識別します。そのような領域は、さまざまな量の強度にわたってあまり変化しない場合、最大に安定していると言われます。

他の多くの ブロブ検出アルゴリズム 存在する場合、MSERが選択されたのは、実行時の複雑さがO(n log(log(n)))とかなり軽いためです。ここで、nは画像上のピクセルの総数です。このアルゴリズムは、ぼかしや拡大縮小にも堅牢であり、携帯電話のカメラなどのリアルタイムソースから取得した画像を処理する場合に有利です。

このチュートリアルの目的のために、 応用 ApeeScapeのロゴを検出します。シンボルには鋭い角があり、それはApeeScapeのロゴを検出するのにどれほど効果的な角検出アルゴリズムがあるかを考えるように導くかもしれません。結局のところ、このようなアルゴリズムは使いやすく、理解しやすいものです。コーナーベースの方法は、背景から明確に分離されたオブジェクト(白い背景上の黒いオブジェクトなど)の検出に関しては高い成功率を示す可能性がありますが、ApeeScapeのリアルタイム検出を実現することは困難です。 ロゴ アルゴリズムが常に数百のコーナーを検出する実世界の画像。

DiscordMobileでボットを作成する方法

戦略

機械学習とopencv

アプリケーションがカメラを介して取得する画像のフレームごとに、最初にグレースケールに変換されます。グレースケール画像の色のチャネルは1つだけですが、それでもロゴは表示されます。これにより、アルゴリズムが画像を処理しやすくなり、アルゴリズムが処理する必要のあるデータの量が大幅に削減され、追加のゲインがほとんどまたはまったくなくなります。

次に、OpenCVの実装アルゴリズムを使用して、すべてのMSERを抽出します。次に、各MSERは、最小の境界矩形を正方形に変換することによって正規化されます。ロゴはさまざまな角度や距離から取得される可能性があり、これにより遠近法による歪みの許容度が高まるため、この手順は重要です。

さらに、MSERごとにいくつかのプロパティが計算されます。

  • 穴の数
  • MSERの面積と凸包の面積の比率
  • MSERの面積とその最小面積の長方形の面積の比率
  • MSERの面積に対するMSERスケルトンの長さの比率
  • MSERの面積と最大等高線の面積の比率

iOSアプリケーションと機械学習

画像内のApeeScapeのロゴを検出するために、すべてのMSERのプロパティが、すでに学習されているApeeScapeのロゴプロパティと比較されます。このチュートリアルの目的のために、各プロパティの最大許容差は経験的に選択されました。

レスポンシブデザインのためのメディアクエリ

最後に、最も類似した領域が結果として選択されます。

iOSアプリケーション

iOSからOpenCVを使用するのは簡単です。まだ行っていない場合は、iOSアプリケーションを作成してOpenCVを使用するためのXcodeのセットアップに関連する手順の概要を以下に示します。

  1. 新しいプロジェクト名「SuperCoolLogoDetector」を作成します。言語として、Objective-Cを選択したままにします。

  2. 新しいプレフィックスヘッダー(.pch)ファイルを追加し、PrefixHeader.pchという名前を付けます

  3. プロジェクト「SuperCoolLogoDetector」ビルドターゲットに移動し、「ビルド設定」タブで「プレフィックスヘッダー」設定を見つけます。 LLVM言語セクションで見つけるか、検索機能を使用できます。

  4. 「PrefixHeader.pch」をプレフィックスヘッダー設定に追加します

  5. この時点で、インストールしていない場合 iOS用OpenCV 2.4.11、今それをしなさい。

  6. ダウンロードしたフレームワークをプロジェクトにドラッグアンドドロップします。ターゲット設定の「リンクされたフレームワークとライブラリ」をチェックします。 (自動的に追加する必要がありますが、安全のために追加することをお勧めします。)

  7. さらに、次のフレームワークをリンクします。

    • AVFoundation
    • AssetsLibrary
    • CoreMedia
  8. 「PrefixHeader.pch」を開き、次の3行を追加します。

    nodejsは安らかなAPIを表現します
    #ifdef __cplusplus #include #endif”
  9. 自動作成されたコードファイルの拡張子を「 .m」から「 。んん'。 OpenCVはC ++で書かれており、*。mmを使用すると、Objective-C ++を使用することになります。

  10. ViewController.hに「opencv2 / highgui / cap_ios.h」をインポートし、プロトコルCvVideoCameraDelegateに準拠するようにViewControllerを変更します。

    #import
  11. Main.storyboardを開き、UIImageViewを最初のViewControllerに配置します。

  12. 「imageView」という名前のViewController.mmへのアウトレットを作成します

  13. 変数「CvVideoCamera * camera;」を作成します。 ViewController.hまたはViewController.mmで、リアカメラへの参照を使用して初期化します。

    camera = [[CvVideoCamera alloc] initWithParentView: _imageView]; camera.defaultAVCaptureDevicePosition = AVCaptureDevicePositionBack; camera.defaultAVCaptureSessionPreset = AVCaptureSessionPreset640x480; camera.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationPortrait; camera.defaultFPS = 30; camera.grayscaleMode = NO; camera.delegate = self;
  14. 今すぐプロジェクトをビルドすると、Xcodeは、CvVideoCameraDelegateの「processImage」メソッドを実装していないことを警告します。今のところ、簡単にするために、カメラから画像を取得し、簡単なテキストでオーバーレイします。

    • 「viewDidAppear」に1行追加します。
    [camera start];
    • これで、アプリケーションを実行すると、カメラにアクセスするための許可を求められます。そして、あなたはカメラからのビデオを見るはずです。

    • 「processImage」メソッドに、次の2行を追加します。

      CFOの仕事は何ですか
    const char* str = [@'ApeeScape' cStringUsingEncoding: NSUTF8StringEncoding]; cv::putText(image, str, cv::Point(100, 100), CV_FONT_HERSHEY_PLAIN, 2.0, cv::Scalar(0, 0, 255));

それはほとんどそれです。これで、カメラからの画像に「ApeeScape」というテキストを描画する非常に単純なアプリケーションができました。これで、この単純なアプリケーションからターゲットロゴ検出アプリケーションを構築できます。簡潔にするために、この記事では、アプリケーションが全体的にどのように機能するかを理解するために重要な、ほんの一握りのコードセグメントについてのみ説明します。 GitHubのコードには、各セグメントの機能を説明するためのかなりの量のコメントがあります。

迅速なプロトコル指向プログラミング

アプリケーションの目的はApeeScapeのロゴを検出することだけなので、起動するとすぐに、MSERの特徴が指定されたテンプレート画像から抽出され、値がメモリに保存されます。

cv::Mat logo = [ImageUtils cvMatFromUIImage: templateImage]; //get gray image cv::Mat gray; cvtColor(logo, gray, CV_BGRA2GRAY); //mser with maximum area is std::vector maxMser = [ImageUtils maxMser: &gray]; //get 4 vertices of the maxMSER minrect cv::RotatedRect rect = cv::minAreaRect(maxMser); cv::Point2f points[4]; rect.points(points); //normalize image cv::Mat M = [GeometryUtil getPerspectiveMatrix: points toSize: rect.size]; cv::Mat normalizedImage = [GeometryUtil normalizeImage: &gray withTranformationMatrix: &M withSize: rect.size.width]; //get maxMser from normalized image std::vector normalizedMser = [ImageUtils maxMser: &normalizedImage]; //remember the template self.logoTemplate = [[MSERManager sharedInstance] extractFeature: &normalizedMser]; //store the feature [self storeTemplate];

アプリケーションには、開始/停止ボタンのある画面が1つだけあり、FPSや検出されたMSERの数など、必要なすべての情報が画像に自動的に描画されます。アプリケーションが停止していない限り、カメラ内のすべての画像フレームに対して、次のprocessImageメソッドが呼び出されます。

-(void)processImage:(cv::Mat &)image { cv::Mat gray; cvtColor(image, gray, CV_BGRA2GRAY); std::vector msers; [[MSERManager sharedInstance] detectRegions: gray intoVector: msers]; if (msers.size() == 0) { return; }; std::vector *bestMser = nil; double bestPoint = 10.0; std::for_each(msers.begin(), msers.end(), [&] (std::vector &mser) { MSERFeature *feature = [[MSERManager sharedInstance] extractFeature: &mser]; if(feature != nil) { if([[MLManager sharedInstance] isApeeScapeLogo: feature] ) { double tmp = [[MLManager sharedInstance] distance: feature ]; if ( bestPoint > tmp ) { bestPoint = tmp; bestMser = &mser; } } } }); if (bestMser) { NSLog(@'minDist: %f', bestPoint); cv::Rect bound = cv::boundingRect(*bestMser); cv::rectangle(image, bound, GREEN, 3); } else { cv::rectangle(image, cv::Rect(0, 0, W, H), RED, 3); } // Omitted debug code [FPS draw: image]; }

この方法は、本質的に、元の画像のグレースケールコピーを作成します。すべてのMSERを識別し、それらに関連する機能を抽出し、テンプレートとの類似性について各MSERをスコアリングし、最適なものを選択します。最後に、最適なMSERの周囲に緑色の境界線を描画し、画像にメタ情報をオーバーレイします。

以下は、このアプリケーションにおけるいくつかの重要なクラスの定義とそのメソッドです。それらの目的はコメント内に記述されています。

GeometryUtil.h

/* This static class provides perspective transformation function */ @interface GeometryUtil : NSObject /* Return perspective transformation matrix for given points to square with origin [0,0] and with size (size.width, size.width) */ + (cv::Mat) getPerspectiveMatrix: (cv::Point2f[]) points toSize: (cv::Size2f) size; /* Returns new perspecivly transformed image with given size */ + (cv::Mat) normalizeImage: (cv::Mat *) image withTranformationMatrix: (cv::Mat *) M withSize: (float) size; @end

MSERManager.h

/* Singelton class providing function related to msers */ @interface MSERManager : NSObject + (MSERManager *) sharedInstance; /* Extracts all msers into provided vector */ - (void) detectRegions: (cv::Mat &) gray intoVector: (std::vector &) vector; /* Extracts feature from the mser. For some MSERs feature can be NULL !!! */ - (MSERFeature *) extractFeature: (std::vector *) mser; @end

MLManager.h

/* This singleton class wraps object recognition function */ @interface MLManager : NSObject + (MLManager *) sharedInstance; /* Stores feature from the biggest MSER in the templateImage */ - (void) learn: (UIImage *) templateImage; /* Sum of the differences between logo feature and given feature */ - (double) distance: (MSERFeature *) feature; /* Returns true if the given feature is similar to the one learned from the template */ - (BOOL) isApeeScapeLogo: (MSERFeature *) feature; @end

このアプリケーションを使用すると、すべてが相互に接続された後、iOSデバイスのカメラを使用して、さまざまな角度と方向からApeeScapeのロゴを検出できるようになります。

画像(ApeeScapeロゴ)を垂直方向に検出します。

シャツの画像(ApeeScapeロゴ)を斜めに検出します。

拡張現実アプリは画像を理解することから始まります、そしてこれはあなたがそれをすることができる方法です。 つぶやき

結論

この記事では、OpenCVを使用して画像から単純なオブジェクトを検出することがいかに簡単であるかを示しました。コード全体は GitHubで入手可能 。貢献を歓迎するので、気軽にフォークしてプッシュリクエストを送信してください。

機械学習の問題に当てはまるように、このアプリケーションでのロゴ検出の成功率は、オブジェクト分類にさまざまな機能セットとさまざまな方法を使用することで向上する可能性があります。ただし、この記事が、MSERを使用したオブジェクト検出と一般的なコンピュータービジョン技術のアプリケーションを開始するのに役立つことを願っています。

参考文献

  • J. Matas、O。Chum、M。Urban、およびT.Pajdla。 「最大限に安定した極限領域からのロバストなワイドベースラインステレオ。」
  • ノイマン、ルーカス;マタス、ジリ(2011)。 「実世界の画像におけるテキストのローカリゼーションと認識のための方法」
関連: ロボットプログラミング入門チュートリアル

Reduxフォームライブラリの作成者からのフルスタック開発者向けのヒント

仕事の未来

Reduxフォームライブラリの作成者からのフルスタック開発者向けのヒント
MetaDapper:適切なツールでデータのマッピングと変換が簡単に

MetaDapper:適切なツールでデータのマッピングと変換が簡単に

データサイエンスとデータベース

人気の投稿
評価比率:財務専門家が知る必要のある主要な指標
評価比率:財務専門家が知る必要のある主要な指標
フリーランスのデザイナーとしてのリモートワーク
フリーランスのデザイナーとしてのリモートワーク
シニアフロントエンドエンジニア、スタッフポータルキャッシュチーム
シニアフロントエンドエンジニア、スタッフポータルキャッシュチーム
長年にわたるボタンデザイン:ドリブルタイムライン
長年にわたるボタンデザイン:ドリブルタイムライン
NvidiaShield-Androidゲームコンソールの別の見方
NvidiaShield-Androidゲームコンソールの別の見方
 
生成的敵対的ネットワークを使用してランダムノイズからデータを作成する
生成的敵対的ネットワークを使用してランダムノイズからデータを作成する
一度書けばどこにでも展開:いつネイティブに移行するか?
一度書けばどこにでも展開:いつネイティブに移行するか?
最適化されたソフトウェア統合:ApacheCamelチュートリアル
最適化されたソフトウェア統合:ApacheCamelチュートリアル
ページ速度101:モバイルUIデザイナーの基盤
ページ速度101:モバイルUIデザイナーの基盤
ブルータリストのWebデザイン、ミニマリストのWebデザイン、そしてWebUXの未来
ブルータリストのWebデザイン、ミニマリストのWebデザイン、そしてWebUXの未来
人気の投稿
  • ハッカーからオンラインでクレジットカードを購入する
  • Cプログラミングを学ぶための最良の方法
  • デザインとテクニックの違いは何ですか?
  • javascriptは文字列を時間に変換します
  • ノードjsでAPIを休ませます
  • cfoは会社で何を意味します
カテゴリー
データサイエンスとデータベース 仕事の未来 トレンド モバイル バックエンド 計画と予測 ブランドデザイン 革新 アジャイル ヒントとツール

© 2021 | 全著作権所有

apeescape2.com