2.4.7からOpenCVをビルドしなくてもOpenCLが利用できるようになっている。
以前のバージョンで試していないのでわからないが、2.4.7では、OCLのソースをターゲットの環境に合わせて実行時にコンパイルが行われバイナリファイルが作成される
このバイナリファイルは、ディスクにキャッシュされ、次回プログラムを実行するときはこのバイナリファイルが使用されるとのこと
ファイル名は、モジュール名+OpenCLデバイス名+.clbの形式である。
Visual Studioから実行すると、ソースファイルが格納されているフォルダーにバイナリファイルが格納され、プログラム単体で実行すると、実行したフォルダーに作成される
下記は、ocl::hogを利用するプログラムを実行させた場合にできるファイルである。
以上
OpenCV、機械学習、はやりのDeep learningの環境構築の方法、サンプルの動かし方、APIの使い方、Tipsなどをすぐに忘れてしまうので、備忘録として記録している。記憶がなくなるスピードが、早いのでメモしておかないと再現できなくなる確率が高まっている。 最近、再度HDDを飛ばしてしまい、過去の自分のページに再度助けられた。 また、DNNモジュールを触る機会が増えているので、C++からPyhonへと鞍替え中。 内容を気にいっていただければ、twitterで紹介願います。
2013年11月29日金曜日
2013年11月28日木曜日
OpenCVでBOWで辞書作成ではまった
BOWの辞書作成プログラムを作ろうとしているが、試験的に作成したプログラムが作成した辞書と
リファクタリングしたプログラムで作成した辞書の値が異なり悩んでしまった。
乱数を使用しているか思ったが、同じプログラムでは、ソースを変更しても結果は同じとなるため
原因がつかめなかった。
そこで、同一プログラム内で
cv::BOWKMeansTrainer bowTrainer1(DIC_SIZE, tc, 1, cv::KMEANS_PP_CENTERS); //BOW_kmeans設定
cv::BOWKMeansTrainer bowTrainer2(DIC_SIZE, tc, 1, cv::KMEANS_PP_CENTERS); //BOW_kmeans設定
int size = mLstMat.size();
for (int i = 0 ; i < size ;i++) {
bowTrainer1.add(mLstMat.at(i));
bowTrainer2.add(mLstMat.at(i));
}
cv::Mat f1 = bowTrainer1.cluster();
std::cout << f1 << std::endl << std::endl;
cv::Mat f2 = bowTrainer2.cluster();
std::cout << f2 << std::endl << std::endl;
のようのBOWKMeansTrainerのインスタンスを2つ作成し、同一データで辞書を作成したところ、値が異なることがわかった
再度ドキュメントのBOWKMeansTrainerのコンストラクタの説明をみると
パラメータは、kmeans()をみとろのこと
kmeans()の説明では、flagパラメータのKMEANS_PP_CENTERSは、 kmeans++の初期化を使用とのこと
wikiのK-means++法の説明をみると、
「まず始めにデータ点をランダムに選び1つ目のクラスタ中心とし」
と記載されている
同じプログラムを使用しないと、辞書が異なる可能性が大きい
同じプログラムでも実行マシンを変えるとどうなるのだろうか
リファクタリングしたプログラムで作成した辞書の値が異なり悩んでしまった。
乱数を使用しているか思ったが、同じプログラムでは、ソースを変更しても結果は同じとなるため
原因がつかめなかった。
そこで、同一プログラム内で
cv::BOWKMeansTrainer bowTrainer1(DIC_SIZE, tc, 1, cv::KMEANS_PP_CENTERS); //BOW_kmeans設定
cv::BOWKMeansTrainer bowTrainer2(DIC_SIZE, tc, 1, cv::KMEANS_PP_CENTERS); //BOW_kmeans設定
int size = mLstMat.size();
for (int i = 0 ; i < size ;i++) {
bowTrainer1.add(mLstMat.at(i));
bowTrainer2.add(mLstMat.at(i));
}
cv::Mat f1 = bowTrainer1.cluster();
std::cout << f1 << std::endl << std::endl;
cv::Mat f2 = bowTrainer2.cluster();
std::cout << f2 << std::endl << std::endl;
のようのBOWKMeansTrainerのインスタンスを2つ作成し、同一データで辞書を作成したところ、値が異なることがわかった
再度ドキュメントのBOWKMeansTrainerのコンストラクタの説明をみると
パラメータは、kmeans()をみとろのこと
kmeans()の説明では、flagパラメータのKMEANS_PP_CENTERSは、 kmeans++の初期化を使用とのこと
wikiのK-means++法の説明をみると、
「まず始めにデータ点をランダムに選び1つ目のクラスタ中心とし」
と記載されている
同じプログラムを使用しないと、辞書が異なる可能性が大きい
同じプログラムでも実行マシンを変えるとどうなるのだろうか
OpenCVの特徴点検出で使用するAPIに関して 2
正確なバージョンは調べないといけないが、2.4以降、OpenCVのドキュメントの特徴量の取得のためのAPIは、複数のアルゴリズムの切り替えを簡単にするために、共通インタフェースを使用する形式となっている。
インスタンスの生成は、
Ptr<DescriptorExtractor> DescriptorExtractor::create(const string& descriptorExtractorType)
を使用し、descriptorExtractorTypeにアルゴリズム名を指定する形となっている。
SIFTを使用する場合、"SIFT"を代入することになる。
このAPIでは、各アルゴリズム特有の初期設定ができないため、SIFTの角度の計算を行わないようにするなどの設定ができなくなってしまう。
また、このAPIでは、SURFとSIFTを使用するためには、
OpenCV 2.4.2でSURFを使うために
に書いたような注意が必要となる。
2.4.7でも
cv::SiftDescriptorExtractor extractor;
は使用できる
Visual studio のインテリセンスでSiftDescriptorExtractorのコンストラクターの引数をみることができるが、2.4.7では、
extractor(cv::SIFT::DescriptorParams::GET_DEFAULT_MAGNIFICATION(), true, false);
のような引数の並びではなくなっている。
インスタンスの生成は、
Ptr<DescriptorExtractor> DescriptorExtractor::create(const string& descriptorExtractorType)
を使用し、descriptorExtractorTypeにアルゴリズム名を指定する形となっている。
SIFTを使用する場合、"SIFT"を代入することになる。
このAPIでは、各アルゴリズム特有の初期設定ができないため、SIFTの角度の計算を行わないようにするなどの設定ができなくなってしまう。
また、このAPIでは、SURFとSIFTを使用するためには、
OpenCV 2.4.2でSURFを使うために
に書いたような注意が必要となる。
2.4.7でも
cv::SiftDescriptorExtractor extractor;
は使用できる
Visual studio のインテリセンスでSiftDescriptorExtractorのコンストラクターの引数をみることができるが、2.4.7では、
extractor(cv::SIFT::DescriptorParams::GET_DEFAULT_MAGNIFICATION(), true, false);
のような引数の並びではなくなっている。
OpenCV 2.4.7でOpenCLを試してみた 5
2.4.7からOpenCVをビルドしなくてもOpenCLが利用できるようになっている。
カラー、白黒変換のAPIで処理時間を計測してみた。
処理内容
0 VGAサイズのカラー画像を読み込む
1 matのcloneでデータのコピー
2 cvtColorで白黒に変換
3 matのcloneでデータのコピー
4 表示
5 キー入力待ち
while()で1-5の処理の繰り返す
時間の計測は、1,2,3の前後でcv::getTickCount()を呼び、その差から計算している
CPU版
リリースモードでビルドしているが、Visual Studio から実行しているので、若干オーバヘッドが含まれている
1回目のcvtColorに時間がかかっているが、あとはほぼ一定の時間と思われる
1,3でのデータ転送量の比(3:1)が、そのまま処理時間の比と同じである
OCL版
処理内容は同じであるが使用する関数とMatがOCL対応になる
1回目は、カーネルのコンパイル時間が含まれており、5秒近くの処理時間がかかっている
2回目以降の処理時間は安定しているが、1,3での処理時間が変わらない結果となっている
1,2の処理時間も約4倍となっており、当方の環境では、VGAサイズの画像に対して簡単な処理をOCL化することは、まったく速くならないことが確認された。
特徴点やObject検出など計算量が多い場合には、処理時間の短縮が見込めるかも知れない
メモ
ocl版resizeでは、フィルターtタイプに、INTER NEAREST or INTER LINEARしか使えない
他の値では、落ちる
カラー、白黒変換のAPIで処理時間を計測してみた。
処理内容
0 VGAサイズのカラー画像を読み込む
1 matのcloneでデータのコピー
2 cvtColorで白黒に変換
3 matのcloneでデータのコピー
4 表示
5 キー入力待ち
while()で1-5の処理の繰り返す
時間の計測は、1,2,3の前後でcv::getTickCount()を呼び、その差から計算している
CPU版
リリースモードでビルドしているが、Visual Studio から実行しているので、若干オーバヘッドが含まれている
1回目のcvtColorに時間がかかっているが、あとはほぼ一定の時間と思われる
1,3でのデータ転送量の比(3:1)が、そのまま処理時間の比と同じである
OCL版
処理内容は同じであるが使用する関数とMatがOCL対応になる
1回目は、カーネルのコンパイル時間が含まれており、5秒近くの処理時間がかかっている
2回目以降の処理時間は安定しているが、1,3での処理時間が変わらない結果となっている
1,2の処理時間も約4倍となっており、当方の環境では、VGAサイズの画像に対して簡単な処理をOCL化することは、まったく速くならないことが確認された。
特徴点やObject検出など計算量が多い場合には、処理時間の短縮が見込めるかも知れない
メモ
ocl版resizeでは、フィルターtタイプに、INTER NEAREST or INTER LINEARしか使えない
他の値では、落ちる
2013年11月27日水曜日
OpenCVの特徴点検出で使用するAPIに関して
前回のメモ
OpenCVでBOWを使用して認識を行うための調査をした
の中で、参考Webページ
OpenCV で SIFT 記述子を Dense Sampling する
のサンプルコードは、2.3.1を対象として書かれている
そのソースを2.4.7の環境で使用すると、記事下部の
cv::SIFT::DescriptorParams::GET_DEFAULT_MAGNIFICATION()
のところでDescriptorParamsがみつからないとエラーとなる
特徴点の検出用 API および、特徴量の取得用 APIに関してOpenCVのサンプルやチュートリアルでもばらつきが生じており、使用を推奨されないAPIも多数あるというこまった状態である。
チュートリアルの、2次元特徴点の検出のチュートリアルのサンプルでは、SurfFeatureDetector が使用されているが、Sift同様にドキュメントの検索でAPIの説明はみつからない
同じく、特徴量取得のチュートリアルのサンプルでは、特徴量の取得に、SurfDescriptorExtractor が使用されているが、SurfFeatureDetector 同様にドキュメントの検索でAPIの説明はみつからない
ということで、sample内のソースを覗いてみることにする。
OpenCVでBOWを使用して認識を行うための調査をした
の中で、参考Webページ
OpenCV で SIFT 記述子を Dense Sampling する
のサンプルコードは、2.3.1を対象として書かれている
そのソースを2.4.7の環境で使用すると、記事下部の
cv::SIFT::DescriptorParams::GET_DEFAULT_MAGNIFICATION()
のところでDescriptorParamsがみつからないとエラーとなる
特徴点の検出用 API および、特徴量の取得用 APIに関してOpenCVのサンプルやチュートリアルでもばらつきが生じており、使用を推奨されないAPIも多数あるというこまった状態である。
チュートリアルの、2次元特徴点の検出のチュートリアルのサンプルでは、SurfFeatureDetector が使用されているが、Sift同様にドキュメントの検索でAPIの説明はみつからない
同じく、特徴量取得のチュートリアルのサンプルでは、特徴量の取得に、SurfDescriptorExtractor が使用されているが、SurfFeatureDetector 同様にドキュメントの検索でAPIの説明はみつからない
ということで、sample内のソースを覗いてみることにする。
OpenCVでBOWを使用して認識を行うための調査をした
BOW Bag of visual keyword
ほかに、
BOK Bag of keypoints
BOF Bag of features
などと呼ばれている
特徴量を指しているのでこれだけでは認識できない。SVMと組み合わせて使用する
ベースとなる考え方なので、性能向上のためにさまざまな派生の方法が考案されている。
また、実際に使用するに当たっては、さまざまな文書化されていないノウハウが必要である。
サンプルプログラムは
sources\samples\cpp\bagofwords_classification.cpp
に格納されている
ファイルサイズが、114kもあり、それなりのボリュームなのでソースを見ても全体の流れが把握しにくい
google先生に尋ねてみるといくつかの資料が見つかった
以下調査中なので個人的メモ
以上
ほかに、
BOK Bag of keypoints
BOF Bag of features
などと呼ばれている
特徴量を指しているのでこれだけでは認識できない。SVMと組み合わせて使用する
ベースとなる考え方なので、性能向上のためにさまざまな派生の方法が考案されている。
また、実際に使用するに当たっては、さまざまな文書化されていないノウハウが必要である。
サンプルプログラムは
sources\samples\cpp\bagofwords_classification.cpp
に格納されている
ファイルサイズが、114kもあり、それなりのボリュームなのでソースを見ても全体の流れが把握しにくい
google先生に尋ねてみるといくつかの資料が見つかった
以下調査中なので個人的メモ
以上
2013年11月21日木曜日
2013年11月20日水曜日
Windows7 64bit版にOpenCV 2.4.7の開発環境を構築した
検索などでこのページを訪れる人が、数は少ないけど、コンスタントにいる。
ちょうどこの上にあるG+1のボタンを押してもらうと、Goolgeの検索に見つかりやすくなるので、ご協力いただきたい。
Windows版は、OpenGL、OpenNI、CUDAを使用しなければ、ダウンロードしたファイルを展開して設定すれば使用できるので、30分もかからず環境ができる。
(ダウンロード時間や、Visual Studio 2010 Express Editionのインストールを除く)
2.4.4からVisual Studio 2012がサポートされるようになったが、以下は、Windows7 64bit版上で、Visual Studio 2010 Express Editionでプログラムを開発するためのものである
(Windows7 32bit版でも同じ手順でできる)
また、2.4.7からは、2008がサポートされなくなったので注意
1 ここからWindows版をダウンロードする
2 OpenCV-2.4.7.0.exeを実行しインストールディレクトリc:\を指定する
3 展開後、ディレクトリ名をopencvからopencv247に変更する
4 OSの環境変数の設定(要管理者権限)
コントロールパネル、システムとセキュリティ、システムを開き
システムの詳細設定の環境変数ボタンを押し
システム環境変数のPathの編集
末尾に";C:\opencv247\build\x86\vc10\bin"を追加
(この作業後、一度ログオフし、再度ログインする)
注意 64bitの開発を行う場合は、x64を選択すること Visual Studio 2010 Express Editionでは、64bit開発できないので32bitを用いている
5 Visual C++ 2010 Expressのパスの設定を行う
この記事を参考に
6 手持ちのサンプルをビルドし動作確認する
以上
ちょうどこの上にあるG+1のボタンを押してもらうと、Goolgeの検索に見つかりやすくなるので、ご協力いただきたい。
Windows版は、OpenGL、OpenNI、CUDAを使用しなければ、ダウンロードしたファイルを展開して設定すれば使用できるので、30分もかからず環境ができる。
(ダウンロード時間や、Visual Studio 2010 Express Editionのインストールを除く)
2.4.4からVisual Studio 2012がサポートされるようになったが、以下は、Windows7 64bit版上で、Visual Studio 2010 Express Editionでプログラムを開発するためのものである
(Windows7 32bit版でも同じ手順でできる)
また、2.4.7からは、2008がサポートされなくなったので注意
1 ここからWindows版をダウンロードする
2 OpenCV-2.4.7.0.exeを実行しインストールディレクトリc:\を指定する
3 展開後、ディレクトリ名をopencvからopencv247に変更する
4 OSの環境変数の設定(要管理者権限)
コントロールパネル、システムとセキュリティ、システムを開き
システムの詳細設定の環境変数ボタンを押し
システム環境変数のPathの編集
末尾に";C:\opencv247\build\x86\vc10\bin"を追加
(この作業後、一度ログオフし、再度ログインする)
注意 64bitの開発を行う場合は、x64を選択すること Visual Studio 2010 Express Editionでは、64bit開発できないので32bitを用いている
5 Visual C++ 2010 Expressのパスの設定を行う
この記事を参考に
6 手持ちのサンプルをビルドし動作確認する
以上
Visual C++ 2010 ExpressにOpenCVのディレクトリを設定した 修正版
毎回プロジェクトにincludeパスを設定したり、ソースのパスを修正するのも手間がかかるのでVisual C++ 2010 ExpressにOpenCVのディレクトリを設定した。
前回は手動で設定ファイルを編集したが、Visual C++ 2010 Expressのメニューから編集できる
1 プロジェクトを作成、あるいは、読み込み、メニューの表示のプロパティーマネージャを選択
2 Microsoft.Cpp.Win32.userを編集
3 共通プロパティのC++、全般を選択
4 追加のインクルードディレクトリを選択
5 追加のインクルードディレクトリにOpenCVのインクルード用のフォルダーを設定
6 Microsoft.Cpp.Win32.userを保存
注意
・Debug,Relese双方編集する必要あり
・Microsoft.Cpp.Win32.userを編集するとすべてのプロジェクトが影響を受ける
以上
前回は手動で設定ファイルを編集したが、Visual C++ 2010 Expressのメニューから編集できる
1 プロジェクトを作成、あるいは、読み込み、メニューの表示のプロパティーマネージャを選択
2 Microsoft.Cpp.Win32.userを編集
3 共通プロパティのC++、全般を選択
4 追加のインクルードディレクトリを選択
5 追加のインクルードディレクトリにOpenCVのインクルード用のフォルダーを設定
6 Microsoft.Cpp.Win32.userを保存
注意
・Debug,Relese双方編集する必要あり
・Microsoft.Cpp.Win32.userを編集するとすべてのプロジェクトが影響を受ける
以上
2013年11月19日火曜日
OpenCVでHOG特徴量+SVMで人物検出を行う 1
以前サンプルを動かしてみたが、独自の辞書作成のためにOpenCVのHOGを調査している。
(現在2.4.7になっており内容が異なっているので、2.4.6限定の話である。
また、調査した時期も数カ月前なのでoclを考慮していない)
OpenCV2.4.6のHOGのソースは、
modules\objdetect\src\hog.cpp
であり、CPU版のサンプルは、
samples\cpp\peopledetect.cpp
GPU版のサンプルは、
samples\gpu\hog.cpp
である。
OCL版も準備されているが、OCLの環境がないため無視する。
CPU版のソースをみると計算される特徴量は、
INRIA Object Detection and Localization Toolkit
(http://pascal.inrialpes.fr/soft/olt/)
と互換性があるとのことだが、オリジナルが英語なので現在未読である。
サンプルプログラムの内容
CPU版のサンプルプログラムで、HOG関連をひらっていくと
インスタンスの作成
Line48で、HOGDescriptor hog;
辞書の設定
Line49で、hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
検出処理
Line79で、hog.detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2);
検出結果は、cv::vector<Rect> foundに格納される
検出した領域の重複検査を行い、重複がない場合のみ、cv::vector<Rect> found_filteredに格納されている。(Line 83-91)
また、オリジナルの辞書は、人の周りの余白が多いため、表示の時に検出された領域を縮小している。(Line 92-102)
以上のような処理を行っている。
HOG関数
なぜか、CPU版のドキュメントは準備されていない。Webで検索するとGPU版の説明のみHitする。
HOGDescriptorには、各種パラメータが設定できるようになっているが、コードの実装は固定値を使用しており、自由に変更できない
CELLサイズ 8x8のみサポート
BLOCKサイズ 16x16のみサポート
BINサイズ 9bins
BLOCK移動量 CELLサイズの整数倍
また、入力画像にガンマ補正処理のフラグがあり、デフォルトではtrueとなっている
Line49 API名は、setSVMDetectorとなっているが、HOGDescriptor::getDefaultPeopleDetector()の戻り値は、static std::vector<float>であり、
実際の処理は検出用の辞書データを設定している。
CPU版のソースでgetDefaultPeopleDetectorをみてみると
vector<float> HOGDescriptor::getDefaultPeopleDetector()
{
static const float detector[] = {
以下 辞書データをそのままfloatの配列に書き込んでいる
一見、辞書の差し替えができる構造に見えるが、辞書作成用のHOG + SVMのツールは、提供されていないので、INRIA Object Detection and Localization Toolkitで
自力で作成する必要がある。
あとドキュメント化されていないようだが、getDefaultPeopleDetectorの辞書に登録されている画像データのサイズは64x128画素であり、
この大きさより、小さい人物を検出したい場合は、対象の画像を拡大しないといけない。
拡大すると、検出精度が低下するため、別途48x96画素の辞書データが準備されている
その場合、HOGDescriptor::getDaimlerPeopleDetector()を使用しないといけない
HOG関数内での基本処理
ガンマ補正
縦、横の3x3のsobelフィルター
角度と長さの計算
blockのヒストグラム計算
ヒストグラムの正規化
SVMの計算
マルチスケールで各スケール画像で領域を検出した後、領域を統合する必要がある
計算コストの関係で、meansiftが使用されるとのこと
ソース内部でも
if ( useMeanshiftGrouping )
{
groupRectangles_meanshift(foundLocations, foundWeights, foundScales, finalThreshold, winSize);
}
else
{
groupRectangles(foundLocations, (int)finalThreshold, 0.2);
のように使用されている
groupRectangles_meanshiftは、cascadedetect.cppで定義されており、自作プログラムからは、cv::groupRectangles_meanshiftで呼び出すことが可能である。
しかし、ドキュメントには説明はないので、なくなる可能性もある
//new grouping function with using meanshift
static void groupRectangles_meanshift(vector<Rect>& rectList, double detectThreshold, vector<double>* foundWeights,
vector<double>& scales, Size winDetSize)
関数内部では、MeanshiftGroupingクラスが使用されており、計算はこのクラスで行っているようだ。
関連ドキュメント
(現在2.4.7になっており内容が異なっているので、2.4.6限定の話である。
また、調査した時期も数カ月前なのでoclを考慮していない)
OpenCV2.4.6のHOGのソースは、
modules\objdetect\src\hog.cpp
であり、CPU版のサンプルは、
samples\cpp\peopledetect.cpp
GPU版のサンプルは、
samples\gpu\hog.cpp
である。
OCL版も準備されているが、OCLの環境がないため無視する。
CPU版のソースをみると計算される特徴量は、
INRIA Object Detection and Localization Toolkit
(http://pascal.inrialpes.fr/soft/olt/)
と互換性があるとのことだが、オリジナルが英語なので現在未読である。
サンプルプログラムの内容
CPU版のサンプルプログラムで、HOG関連をひらっていくと
インスタンスの作成
Line48で、HOGDescriptor hog;
辞書の設定
Line49で、hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
検出処理
Line79で、hog.detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2);
検出結果は、cv::vector<Rect> foundに格納される
検出した領域の重複検査を行い、重複がない場合のみ、cv::vector<Rect> found_filteredに格納されている。(Line 83-91)
また、オリジナルの辞書は、人の周りの余白が多いため、表示の時に検出された領域を縮小している。(Line 92-102)
以上のような処理を行っている。
HOG関数
なぜか、CPU版のドキュメントは準備されていない。Webで検索するとGPU版の説明のみHitする。
HOGDescriptorには、各種パラメータが設定できるようになっているが、コードの実装は固定値を使用しており、自由に変更できない
CELLサイズ 8x8のみサポート
BLOCKサイズ 16x16のみサポート
BINサイズ 9bins
BLOCK移動量 CELLサイズの整数倍
また、入力画像にガンマ補正処理のフラグがあり、デフォルトではtrueとなっている
Line49 API名は、setSVMDetectorとなっているが、HOGDescriptor::getDefaultPeopleDetector()の戻り値は、static std::vector<float>であり、
実際の処理は検出用の辞書データを設定している。
CPU版のソースでgetDefaultPeopleDetectorをみてみると
vector<float> HOGDescriptor::getDefaultPeopleDetector()
{
static const float detector[] = {
以下 辞書データをそのままfloatの配列に書き込んでいる
一見、辞書の差し替えができる構造に見えるが、辞書作成用のHOG + SVMのツールは、提供されていないので、INRIA Object Detection and Localization Toolkitで
自力で作成する必要がある。
あとドキュメント化されていないようだが、getDefaultPeopleDetectorの辞書に登録されている画像データのサイズは64x128画素であり、
この大きさより、小さい人物を検出したい場合は、対象の画像を拡大しないといけない。
拡大すると、検出精度が低下するため、別途48x96画素の辞書データが準備されている
その場合、HOGDescriptor::getDaimlerPeopleDetector()を使用しないといけない
HOG関数内での基本処理
ガンマ補正
縦、横の3x3のsobelフィルター
角度と長さの計算
blockのヒストグラム計算
ヒストグラムの正規化
SVMの計算
マルチスケールで各スケール画像で領域を検出した後、領域を統合する必要がある
計算コストの関係で、meansiftが使用されるとのこと
ソース内部でも
if ( useMeanshiftGrouping )
{
groupRectangles_meanshift(foundLocations, foundWeights, foundScales, finalThreshold, winSize);
}
else
{
groupRectangles(foundLocations, (int)finalThreshold, 0.2);
のように使用されている
groupRectangles_meanshiftは、cascadedetect.cppで定義されており、自作プログラムからは、cv::groupRectangles_meanshiftで呼び出すことが可能である。
しかし、ドキュメントには説明はないので、なくなる可能性もある
//new grouping function with using meanshift
static void groupRectangles_meanshift(vector<Rect>& rectList, double detectThreshold, vector<double>* foundWeights,
vector<double>& scales, Size winDetSize)
関数内部では、MeanshiftGroupingクラスが使用されており、計算はこのクラスで行っているようだ。
関連ドキュメント
- fastHOG - a real-time GPU implementation of HOG
- Computer Vision on GPU with OpenCV
- GPU & CPU Cooperative Accelerated Pedestrian and Vehicle Detection
- OpenCV on a GPU
- 統計的学習手法による人検出
- 局所特徴量と統計学習手法による物体検出
OpenVXがリリースされた
OpenCV 2.4.7でOpenCLを試してみた 4
OpenCVのOpenCL モジュール紹介を訳してみた
当方OpenCLのまったくの初心者なので、誤った解釈をしていたり意味不明な点も多いあるが、OpenCVのOpenCL モジュール紹介を訳してみた。
将来すべてのOpenCLデバイスで実現したいが、現在対応しているのはGPUデバイスのみである
GPUデバイスは、NVidia, AMDの単体GPUデバイスだけでなく、AMD APU, Intel HDのような統合チップも含んでいる
パフォーマンスはデバイスに依存するが、精度はCPUと同じであることをすべてのGPUと環境(Windows, Linux)で確認している
OpenCV OCL モジュールは、OpenCLの知識なしで使用できるようにデザインされている
OpenCV OCL モジュールは、GPUデバイスの可能性を得るアクセラレータとみなすこともできるが、ユーザ自身のカーネルを作成するための取り掛かりとみなすこともできる
OpenCLの知識があれば手助けになるが、カーネルのソースは、OpenCLの勉強に役立つと望んでいる。
カーネルの知識は、既存のOpenCLのカーネルチューニングだけでなく、機能追加に必須である
正しくOpenCLのモジュールを動作させるためには、デバイスベンダーのランタイムが必要である
OCLを使用するには、CMakeで、WITH_OPENCL=ONにしてOpenCVを作成する必要がある(2.4.7のWindows版は、対応しているので不要である)
フラグがオンで、かつ、SDKがインストールされている場合は、OCLモジュールが作成される
AMD’S FFT や BLAS のライブラリがーあれば、WITH_OPENCLAMDFFT=ON, WITH_OPENCLAMDBLAS=ON.を使用できる
OCLのモジュールは、modulesに格納されている
C++のラッパークラスのソースコードは、modules/ocl/srcに、カーネル自身は、modules/ocl/src/openclに格納されている
サンプルは、samples/oclに、精度のテストは、modules/ocl/testに、パフォーマンスは、module/ocl/perfに格納されている
環境変数 OPENCV_OPENCL_DEVICE で使用するOpenCLデバイスを指定できる
(指定方法は略)
あるいは、cv::ocl::setDeviceで指定することもできる。この関数により、OpenCLのランタイムを初期化し、指定のデバイスを計算デバイスとして設定する。
現在、すべてのスレッドは同じコンテキストを共有しており、マルチデバイスには対応していないが、すぐに対応する予定である
4chをサポートすれば、3chもサポートしないといけない。oclMatでは、3chのRGBイメージは、4chを意味しており、3chの場合
4ch目は使用されていない。OpenCVのMatとoclMatとの互換性のためである
開発者ノート
CPUと単体GPU間でのデータ転送のコストは大きいので、アルゴリズムのパイプラインの最初と最後のみデータ転送すべきである
将来すべてのOpenCLデバイスで実現したいが、現在対応しているのはGPUデバイスのみである
GPUデバイスは、NVidia, AMDの単体GPUデバイスだけでなく、AMD APU, Intel HDのような統合チップも含んでいる
パフォーマンスはデバイスに依存するが、精度はCPUと同じであることをすべてのGPUと環境(Windows, Linux)で確認している
OpenCV OCL モジュールは、OpenCLの知識なしで使用できるようにデザインされている
OpenCV OCL モジュールは、GPUデバイスの可能性を得るアクセラレータとみなすこともできるが、ユーザ自身のカーネルを作成するための取り掛かりとみなすこともできる
OpenCLの知識があれば手助けになるが、カーネルのソースは、OpenCLの勉強に役立つと望んでいる。
カーネルの知識は、既存のOpenCLのカーネルチューニングだけでなく、機能追加に必須である
正しくOpenCLのモジュールを動作させるためには、デバイスベンダーのランタイムが必要である
OCLを使用するには、CMakeで、WITH_OPENCL=ONにしてOpenCVを作成する必要がある(2.4.7のWindows版は、対応しているので不要である)
フラグがオンで、かつ、SDKがインストールされている場合は、OCLモジュールが作成される
AMD’S FFT や BLAS のライブラリがーあれば、WITH_OPENCLAMDFFT=ON, WITH_OPENCLAMDBLAS=ON.を使用できる
OCLのモジュールは、modulesに格納されている
C++のラッパークラスのソースコードは、modules/ocl/srcに、カーネル自身は、modules/ocl/src/openclに格納されている
サンプルは、samples/oclに、精度のテストは、modules/ocl/testに、パフォーマンスは、module/ocl/perfに格納されている
環境変数 OPENCV_OPENCL_DEVICE で使用するOpenCLデバイスを指定できる
(指定方法は略)
あるいは、cv::ocl::setDeviceで指定することもできる。この関数により、OpenCLのランタイムを初期化し、指定のデバイスを計算デバイスとして設定する。
現在、すべてのスレッドは同じコンテキストを共有しており、マルチデバイスには対応していないが、すぐに対応する予定である
4chをサポートすれば、3chもサポートしないといけない。oclMatでは、3chのRGBイメージは、4chを意味しており、3chの場合
4ch目は使用されていない。OpenCVのMatとoclMatとの互換性のためである
開発者ノート
CPUと単体GPU間でのデータ転送のコストは大きいので、アルゴリズムのパイプラインの最初と最後のみデータ転送すべきである
- FULL ProfileサポートのOpenCL1.1以降が必要
- 現在、OpenCLのコンテキストとコマンドキューは1つある。マルチデバイスとマルチキューを将来サポートしたい
- 可能な場合、多くのカーネルは、256のワークグループを使用しているので、デバイスの最大ワークグループ数は256以上必要である。すべてのGPUデバイスは、対応しているが、それ以外のデバイスは対応していない
- もしデバイスが、倍精度をサポートしていない場合は、エラーとなる
- oclMatは、イメージオブジェクトではなく、バッファオブジェクトを使用している
- oclMatでは、3chのRGBイメージは、4chを意味しており、3chの場合4ch目は使用されていない。OpenCVのMatとoclMatとの互換性のためである
- oclMatでは、列方向に配置される。(now the alignment factor for step is 32+ byte) means, m.cols * m.elemSize() <= m.step.となる
- ・Mat and oclMat間でのデータ転送 もし、Matが列方向に配置されていると転送は速い。そうでない場合は、アライメントを保証するために、clEnqueueRead/WriteBufferRectを使用する。3chの場合例外で、デバイスに転送される場合に4chに変換される(CPUへの転送は逆になる)
- Mat and oclMat間ではROIの扱いが異なる。oclMatでは、ROIが扱えないので、すべての画像がデバイスにいったん転送される。
- カーネルのソースは、modules/ocl/src/opencl/の拡張子、.clである。 opencl_kernels.cppで、カーネルは変換され、拡張子のないファイル名がソースのファイル名になる
2013年11月18日月曜日
OpenCV 2.4.7でOpenCLを試してみた 3
2.4.7からOpenCVをビルドしなくてもOpenCLが利用できるようになっている。
OpenCLに関しては、"これからの並列計算のためのGPGPU連載講座(VI)" を参考にさせていただいた
本来なら、前処理など複雑な手順が必要であるが、OpenCVでは、これらの作業が隠避されており、素人に対しての障壁が低くなっている。
OpenCVのOpenCL用の関数のソースが、sources\modules\ocl\srcに格納されているので、気になる人は覗いてみると面白いかもしれない。
ソースの中を覗いているとコマンドキューにコマンドを送る関数 openCLExecuteKernel がメインとなっており、多くのクラスは、ラッパーとなっている。
また、sources\modules\ocl\src\openclにカーネルのソースが格納されており、sources\modules\ocl\src\cl_runtimeにランタイム関連のソースが含まれている
このあたりを参考にすれば、原理的には自前の関数をOCL対応でき、OpenCVから呼び出すことが可能かと考えられるが、当方スキル不足なので実現は無理である。
OpenCLに関しては、"これからの並列計算のためのGPGPU連載講座(VI)" を参考にさせていただいた
本来なら、前処理など複雑な手順が必要であるが、OpenCVでは、これらの作業が隠避されており、素人に対しての障壁が低くなっている。
OpenCVのOpenCL用の関数のソースが、sources\modules\ocl\srcに格納されているので、気になる人は覗いてみると面白いかもしれない。
ソースの中を覗いているとコマンドキューにコマンドを送る関数 openCLExecuteKernel がメインとなっており、多くのクラスは、ラッパーとなっている。
また、sources\modules\ocl\src\openclにカーネルのソースが格納されており、sources\modules\ocl\src\cl_runtimeにランタイム関連のソースが含まれている
このあたりを参考にすれば、原理的には自前の関数をOCL対応でき、OpenCVから呼び出すことが可能かと考えられるが、当方スキル不足なので実現は無理である。
OpenCV 2.4.7でOpenCLを試してみた 2
2.4.7からOpenCVをビルドしなくてもOpenCLが利用できるようになっている。
使用している開発マシンのOpenCLデバイス情報を調べてみた。
デバイス情報は、cv::ocl::getOpenCLDevicesを用いて、cv::ocl::DevicesInfoを取得することで得られる。
最初、deviceTypeを指定しないと、DevicesInfoのsizeが0になり焦ったが、deviceTypeにCVCL_DEVICE_TYPE_CPUを指定することでデータを取得できた。
本来ならコンソールに各情報を取得するプログラムを書きたかったが、手抜きでデバッガーで変数を表示させている
気になる値
local Memory size 個々のWorkGroup用のローカルメモリーは32kである
Max memory allocation size ?は、約511Mである
使用している開発マシンのOpenCLデバイス情報を調べてみた。
デバイス情報は、cv::ocl::getOpenCLDevicesを用いて、cv::ocl::DevicesInfoを取得することで得られる。
最初、deviceTypeを指定しないと、DevicesInfoのsizeが0になり焦ったが、deviceTypeにCVCL_DEVICE_TYPE_CPUを指定することでデータを取得できた。
本来ならコンソールに各情報を取得するプログラムを書きたかったが、手抜きでデバッガーで変数を表示させている
気になる値
local Memory size 個々のWorkGroup用のローカルメモリーは32kである
Max memory allocation size ?は、約511Mである
2013年11月15日金曜日
OpenCV 2.4.7でOpenCLを試してみた 1
2.4.7からOpenCVをビルドしなくてもOpenCLが利用できるようになっている。
1 準備
最初に自分の環境あったデバイスのOpenCL SDKをインストールしておく
GPUを所持していないので、Intel版で試す。
IntelのSDKは、ここからダウンロードする。
注意
Visual studio 2010 Express Editionを使用しているとき、インストール途中のVisual studio 2010のチェックをはずすこと
2 動作テスト
sources\samples\oclにサンプルのコードがあるが、テストプログラムを作成
OCL関連のヘッダーとライブラリを加える
#include <opencv2/ocl/ocl.hpp>
#pragma comment(lib,"opencv_ocl247d.lib")
ソース(コアのみ)
int main(int argc, char** argv)
{
cv::Mat matIn = cv::imread("c:\\hoge.png"), matDisp;
cv::imshow("Color", matIn);
cv::ocl::oclMat oclIn(matIn), oclOut;
cv::ocl::cvtColor(oclIn, oclOut, cv::COLOR_BGR2GRAY);
oclOut.download(matDisp);
cv::imshow("Gray",matDisp);
cv::waitKey(0);
return 0;
}
テストプログラムでは、白黒に変換している。
起動すると、絵が表示されるまでに10秒近く時間がかかる。
注意
追加11/15 17:50 未確認
当方の環境 OpenCL対応デバイスが、Intel CPUのみなので初期化が不要であったが、グラフィックスボードを追加し、ボードに対応したOpenCL SDKをインストールした場合には、ocl::setDeviceを呼ぶ必要があるかもしれない
関連ドキュメント
1 準備
最初に自分の環境あったデバイスのOpenCL SDKをインストールしておく
GPUを所持していないので、Intel版で試す。
IntelのSDKは、ここからダウンロードする。
注意
Visual studio 2010 Express Editionを使用しているとき、インストール途中のVisual studio 2010のチェックをはずすこと
2 動作テスト
sources\samples\oclにサンプルのコードがあるが、テストプログラムを作成
OCL関連のヘッダーとライブラリを加える
#include <opencv2/ocl/ocl.hpp>
#pragma comment(lib,"opencv_ocl247d.lib")
ソース(コアのみ)
int main(int argc, char** argv)
{
cv::Mat matIn = cv::imread("c:\\hoge.png"), matDisp;
cv::imshow("Color", matIn);
cv::ocl::oclMat oclIn(matIn), oclOut;
cv::ocl::cvtColor(oclIn, oclOut, cv::COLOR_BGR2GRAY);
oclOut.download(matDisp);
cv::imshow("Gray",matDisp);
cv::waitKey(0);
return 0;
}
テストプログラムでは、白黒に変換している。
起動すると、絵が表示されるまでに10秒近く時間がかかる。
注意
- OCLは、実行時に環境にあわせたカーネルソースがバイナリにコンパイルされるため、オーバヘッドが大きいので、よく使用する関数は、起動時にダミーを呼んでおくのがよいそうだ。
- メモリーと対象デバイス間の転送時間がかかるため、サイズの大きい画像でないとメリットはない
- ネットには事前に、ocl::getDeviseを呼ぶようにとかかれたものがあるが、2.4.7では必要ないし、そのような関数はなくなっている
追加11/15 17:50 未確認
当方の環境 OpenCL対応デバイスが、Intel CPUのみなので初期化が不要であったが、グラフィックスボードを追加し、ボードに対応したOpenCL SDKをインストールした場合には、ocl::setDeviceを呼ぶ必要があるかもしれない
関連ドキュメント
OpenCV関連のkindle本が安い
11/15での価格 改定される可能性あり
Mastering OpenCV With Practical Computer Vision Projects
ペーパ 4661円 kindle 1853円
Android Application Programming with Opencv
ペーパ 3629円 kindle 1447円
amazonにこんなマニアックなカテゴリが
Artificial Intelligence Machine Vision の ベストセラー
Mastering OpenCV With Practical Computer Vision Projects
ペーパ 4661円 kindle 1853円
Android Application Programming with Opencv
ペーパ 3629円 kindle 1447円
amazonにこんなマニアックなカテゴリが
Artificial Intelligence Machine Vision の ベストセラー
2013年11月14日木曜日
OpenCV 2.4.7の Build情報を表示させてみた
cv::getBuildInformation()を使用し、windows版のOpenCV2.4.7のビルド条件を表示させてみた。
2.4.7から、OpenCLがデフォルトでONとなっている
また、FFMPEGのバージョンが更新されている
2.4.6はこちら
2.4.7から、OpenCLがデフォルトでONとなっている
また、FFMPEGのバージョンが更新されている
2.4.6はこちら
2013年11月13日水曜日
OpenCV2.4.7のサンプルを見てみた
sources\sample\cppの内容を2.4.6と比較してみた
tutorialは調べていない
変更点
空白行削除
bgfg_gmg.cpp
calibration_artificial.cpp
dft.cpp
houghlines.cpp
opencv_version.cpp
phase_corr.cpp
retinaDemo.cpp
stereo_calib.cpp
stitching.cpp
stitching_detailed.cpp
コンパイルオプションの追加
hybridtrackingsample.cpp
後処理追加
latentsvm_multidetect.cpp
名前の変更
新 OpenEXRimages_HDR_Retina_toneMapping.cpp
旧 OpenEXRimages_HighDynamicRange_Retina_toneMapping.cpp
名前の変更+コンパイルオプションの追加
新 OpenEXRimages_HDR_Retina_toneMapping_video.cpp
旧 OpenEXRimages_HighDynamicRange_Retina_toneMapping_video.cpp
以上
tutorialは調べていない
変更点
空白行削除
bgfg_gmg.cpp
calibration_artificial.cpp
dft.cpp
houghlines.cpp
opencv_version.cpp
phase_corr.cpp
retinaDemo.cpp
stereo_calib.cpp
stitching.cpp
stitching_detailed.cpp
コンパイルオプションの追加
hybridtrackingsample.cpp
後処理追加
latentsvm_multidetect.cpp
名前の変更
新 OpenEXRimages_HDR_Retina_toneMapping.cpp
旧 OpenEXRimages_HighDynamicRange_Retina_toneMapping.cpp
名前の変更+コンパイルオプションの追加
新 OpenEXRimages_HDR_Retina_toneMapping_video.cpp
旧 OpenEXRimages_HighDynamicRange_Retina_toneMapping_video.cpp
以上
2013年11月12日火曜日
OpenCVのリンクするライブラリのバージョンを変更する
ソースに以下用に記述するすると変更が簡単で間違いも少なくなる
#ifdef _DEBUG
//Debugモードの場合
#define CV_VER "247d"
#else
//Releaseモードの場合
#define CV_VER "247"
#endif
#pragma comment(lib, "opencv_core"CV_VER".lib")
#pragma comment(lib, "opencv_imgproc"CV_VER".lib")
#pragma comment(lib, "opencv_highgui"CV_VER".lib")
#pragma comment(lib, "opencv_video"CV_VER".lib")
#pragma comment(lib,"opencv_objdetect"CV_VER".lib")
#ifdef _DEBUG
//Debugモードの場合
#define CV_VER "247d"
#else
//Releaseモードの場合
#define CV_VER "247"
#endif
#pragma comment(lib, "opencv_core"CV_VER".lib")
#pragma comment(lib, "opencv_imgproc"CV_VER".lib")
#pragma comment(lib, "opencv_highgui"CV_VER".lib")
#pragma comment(lib, "opencv_video"CV_VER".lib")
#pragma comment(lib,"opencv_objdetect"CV_VER".lib")
OpenCV 2.4.7のドキュメントの変更点
ダウンロードしたSDKのbuild/docにドキュメントが格納されている
ページ数のみの比較
The OpenCV User Guide Release 2.4.7.0
P17(21) 2013/11/7
2.4.6から変更
The OpenCV Tutorials Release 2.4.6.0
P421(427) 2013/7/1
2.4.6から変わらず
The OpenCV Reference Manual Release 2.4.7.0
P869(875) 2013/11/7
2.4.6から大幅に増加
The OpenCV Manager Manual Release 2.4.7.0
P11(15) 2013/11/7
2.4.6に存在していたか未確認
以上
ページ数のみの比較
The OpenCV User Guide Release 2.4.7.0
P17(21) 2013/11/7
2.4.6から変更
The OpenCV Tutorials Release 2.4.6.0
P421(427) 2013/7/1
2.4.6から変わらず
The OpenCV Reference Manual Release 2.4.7.0
P869(875) 2013/11/7
2.4.6から大幅に増加
The OpenCV Manager Manual Release 2.4.7.0
P11(15) 2013/11/7
2.4.6に存在していたか未確認
以上
OpenCv2.4.7がリリースされた
ようやく公式でアナウンスされた。
変更点
OpenCL
OpenCL SDKがなくてもビルドできる
実行時に動的にOpenCLの使用が判断される
再ビルドなしにデフォルトのCLデバイスを変更可能
モジュールの最適化、バグ修正、ドキュメントの更新
SVM, MOG/MOG2, KalmanFilter なども対応
CUDA
histograms, TV-L1 optical flow 、 resizeに対応
stereo matchingのサンプル更新
BGR<->YUV変換とbitwize操作のバグ修正
ビルド時の問題を解決
Android
NDK-r9をサポート
native cameraのバグ修正
API level 14 以降のMediaRecorder hintに対応
JavaCameraViewの速度低下を修正
WindowsRT
OpenEXR とカメラを除くMSの認証試験の問題に対応
XAMLベースのビデオ処理を実装
back-end for VideoCaptureを修正
github
326の382 pull requestsをマージ
バグ修正
2.4.6で報告された54のバグを修正
2013年11月8日金曜日
OpenCV 2.4.7が公開された
公式はアナウンスされていないが、ここからダウンロードできる。
ただし、Win版(ダウンロードサイズが272M)とUNIX版のみでiOSとAndoridは遅れているようだ
変更点のアナウンスはまだされていない
ダウンロードした中身を見たらフォルダー構成が変更されており、直下には、buildとsourcesのみとなった
2.4.6まで、直下にあった他のbuild以外のフォルダーは、sourcesの下に移動したので注意
Win版のサポートされている開発環境からvc9(Visual Studio 2008)がなくなり、vc10(Visual Studio 2010)とvc11(Visual Studio 2012)になった。
Visual Studio 2013もまだ対応されていないので注意
ただし、Win版(ダウンロードサイズが272M)とUNIX版のみでiOSとAndoridは遅れているようだ
変更点のアナウンスはまだされていない
ダウンロードした中身を見たらフォルダー構成が変更されており、直下には、buildとsourcesのみとなった
2.4.6まで、直下にあった他のbuild以外のフォルダーは、sourcesの下に移動したので注意
Win版のサポートされている開発環境からvc9(Visual Studio 2008)がなくなり、vc10(Visual Studio 2010)とvc11(Visual Studio 2012)になった。
Visual Studio 2013もまだ対応されていないので注意
登録:
投稿 (Atom)