2015年7月4日土曜日

c++ vector iterator index取得とその使用の注意点

まれにiteratorのindexを取得したい場合がある。が、ほんとはこんなことしない方がいいのはわかるが、iteratorの要素ごとの相互関係を定義したいときに使おうと思って試してみた。

#include <vector>

vector<int> v;
vector<int>::iterator it;

for(int i=0; i<10; ++i) v.push_back(i);

it = find(v.begin(), v.end(), 3);

cout << it - v.begin() <<endl;

結果:
3

とりあえずうまく行きそうだが、これってデータを追加・削除するときにbeginのデータがなくなったりしたら順番が全部変わる気がする。試してみよう。erase で 3 の格納されている要素を消してみる。

#include <iostream>
#include <vector>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
vector<int> v;
vector<int>::iterator it;

for (int i = 0; i<10; ++i) v.push_back(i);

it = find(v.begin(), v.end(), 3);

//cout << it - v.begin() << endl;

v.erase(it);

it = find(v.begin(), v.end(), 2);

cout << it - v.begin() << endl;

it = find(v.begin(), v.end(), 4);

cout << it - v.begin() << endl;

return 0;
}

結果:
2
3

2の入っている要素は変わらないが、4の入っている要素が繰り上がって3になっている。

よって、このアルゴリズムを使う注意点としては、要素をpush_backで追加したときはそれまでの要素のIndexがかわらないが、削除した時は変わってしまうことであろう。注意する。


参考
http://kogecoo.hatenablog.com/entry/20090731/1248994749

2015年7月1日水曜日

cmake Visual studio(2013) ALL_BUILD 実行ファイル変更

CmakeでVisual Studio用のファイルのslnを使ってプロジェクトを作ると、実行ファイルが標準ではALL_BUILDとなり、F5とかCtrl+F5で実行できない。

そこで、実行ファイルの指定を変えます。

通常の画面の上の[Project]->[Properties]を起動。

Single startup project でALLBUILDから実行ファイルのあるプロジェクトに変更する。

だけ。自分でVisual Studioを触れば早かったのだが、検索ではいいものがみ、意外に苦労した。意外に苦労した。

CMakeList.txt の設定 (Visual studio 2013 + OpenGL & OpenCV & Eigen)

cmakeをつくるのに苦労したので、その記録。初心者だー
今作っているプログラムは、OpenGL & OpenCV & Eigenを使っています。それらのCmakeの作り方はそれぞれ違っていので、いろいろと参考になるねーってことでまとめ。また、私の環境はいろいろ制限(インストール不可+特定フォルダにアクセス不可)されているので、OpenGLはふつうはこんなことしなくてもいいかも。また、この理由によりパスは私の使っているものなので、自由に変更してほしい。変更するところだけ太字にしておく。

1.OpenCV
Windowsで自前でOpenCVをコンパイルした時にはCmakeはそのフォルダをわかってくれない。そのためOpenCV_DIRで場所をしていしてあげる。

ーーーーーCMakeList.txtの中身ーーーーー
# OpenCVインストールパスを指定
set(OpenCV_DIR "C:/dev/opencv-2.4.10/build/install")

# OpenCVのパッケージを探す
find_package(OpenCV REQUIRED)

# OpenCVが見つかった場合のみ設定を行う
if(OpenCV_FOUND)
  # インクルードパスを指定
  include_directories(${OpenCV_INCLUDE_DIRS})

  # リンクするライブラリ指定
  target_link_libraries(platform ${OpenCV_LIBS})
endif(OpenCV_FOUND)

2.Eigen
Eigenはインクルードのみで使えるライブラリなのでそのパスだけを指定してあげる。

ーーーーーCMakeList.txtの中身ーーーーー
# Eigen
include_directories("C:/dev/eigen-3.2.4")

3.OpenGL
なぜかこれをかなり苦労した。freeglutをダウンロードしてコンパイルして使っているのだが、フォルダ構成が違うせいかOpenCVと同じ方法をとっても何か上手くいかない。そのため、どうせ使うのはfreeglut.libとインクルードだけなので直接指定した。Cmakeの利点が消えている気がするがまぁいい。いつかいいことあるだろう。

ーーーーーCMakeList.txtの中身ーーーーー
# OpenCVのパッケージを探す
find_package(OpenGL REQUIRED)
include_directories("D:/twatanabe8/dev/freeglut-2.8.1/include")

target_link_libraries(platform "D:/twatanabe8/dev/freeglut-2.8.1/lib/x64/freeglut.lib")

2015年6月30日火曜日

Boost libraryのBuild (Windows8) (64bit版対応修正)

今度コンパイルしようと思っているライブラリ(GTSAM)にBoostが必要なので、準備した。

1.Boostライブラリのダウンロード&展開
公式ページにいって、ダウンロードする。この記事の時点では、1.58.0だったので、最新版をダウンロード。展開は、c:/dev/boost に展開とする。まぁ、どこでもいい。

2.コマンドプロンプトを立ち上げる。
Windows Keyをおして、commandと打ち込むとコマンドプロンプトのアイコンが出てくるので起動。

3.展開したフォルダに移動。
command prompt では cd コマンドを使って移動しましょう。

4.bootstrap.batを起動
bootstrap.bat
と入力します。結構待ちます。

5.コンパイル&インストール
./b2 install -j2 --prefix=(インストールしたいディレクトリ)
上のコマンドでは32bit版が出来上がり、後で苦労します。そのため、64bit用のコマンドに変更します。
b2 toolset=msvc threading=multi variant=debug,release link=shared runtime-link=shared address-model=64 --stagedir=stage/x64 -j 8
この後には、インストールしたいディレクトリの元のstageにLibファイルが出来上がっています。

ちなみに、j2はマルチスレッドでコンパイルするという意味なのでCPUのコア数にしましょう。

6.環境変数に追加
5でできたStageのフォルダにパスを通しましょう。

終わりです。

参考:
http://qiita.com/softgate/items/75f123f01ccdee6d36d0

Boost libraryのBuild (Windows8)

今度コンパイルしようと思っているライブラリ(GTSAM)にBoostが必要なので、準備した。

1.Boostライブラリのダウンロード&展開
公式ページにいって、ダウンロードする。この記事の時点では、1.58.0だったので、最新版をダウンロード。展開は、c:/dev/boost に展開とする。まぁ、どこでもいい。

2.コマンドプロンプトを立ち上げる。
Windows Keyをおして、commandと打ち込むとコマンドプロンプトのアイコンが出てくるので起動。

3.展開したフォルダに移動。
command prompt では cd コマンドを使って移動しましょう。

4.bootstrap.batを起動
bootstrap.bat
と入力します。結構待ちます。

5.コンパイル&インストール
./b2 install -j2 --prefix=(インストールしたいディレクトリ)
この後には、インストールしたいディレクトリの元のstageにLibファイルが出来上がっています。

6.環境変数に追加
5でできたStageのフォルダにパスを通しましょう。

終わりです。

OpenGL 取得した画像をOpenCVで処理してOpenGLで表示する。

内部でSimulationをするために、OpenGLでレンダリングし、その画像を取得しOpenCVで処理することを考えた。まぁ、一般的だと思う。そのためには、

1.OpenGLから画像情報の取得
画像情報の取得には3つ方法がある。
・OpenGLで画像を表示させ、glReadPixels を使って画像情報を取得
・ビデオメモリからWindowの画像情報を取得
・オフスクリーンレンダリング
・ダブルバッファから画像情報の取得
下の3つはまだ試していないので今後にやったらご紹介するとして、1つ目が一番簡単なのでその手法を採用した。

仮のコード(double bufferを使うコードから取得)
cv::Mat ReadDisplay;

glutSwapBuffers();
glReadPixels(0, 0, WIDTH, HEIGHT, GL_BGR_EXT, GL_UNSIGNED_BYTE, ReadDisplay.data);

2.画像を上下反転
OpenGLの座標系のY軸は上向きが正。OpenCVの座標系のY軸は下向きが正(左上が原点)。これを変換する必要がある。

cv::flip(ReadDisplay, ReadDisplay, 0);

3.なんか処理する。
特徴点抽出でもやりましょう。でも、本題でないため細かくは略します。ほしかったら連絡ください。
detector = new ORB(80, 1.25f, 4, 7, 0, 2, 0, 7);
detector->detect(img1, keypoints);
cv::drawKeypoints(img1, keypoints, output);

4.OpenCV 色の変更
なぜだかわからないけど、OpenCVはBGR らしい。そのため、BGRから RGB変更しましょう。

cv::cvtColor(output, output, CV_BGR2RGB);

これをやらないとセピア色になります。

5. 画像を上下反転
OpenGLで表示するために、また画像を上下反転します。

cv::flip(output, output, 0);

6.OpenGLのテクスチャに張り付けて、GLのWindowに画像を表示する。
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrtho(0.0, WIDTH, HEIGHT, 0.0, -1.0, 1.0);

glEnable(GL_TEXTURE_2D);//テクスチャ有効
//glBindTexture(GL_TEXTURE_2D, img.data);

/* テクスチャ画像はバイト単位に詰め込まれている */
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
/* テクスチャの割り当て */
glTexImage2D(GL_TEXTURE_2D, 0, 3, img.cols, img.rows, 0, GL_RGB, GL_UNSIGNED_BYTE, img.data);
/* テクスチャを拡大・縮小する方法の指定 */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glEnable(GL_ALPHA_TEST);//アルファテスト開始
glBegin(GL_POLYGON);
glTexCoord2f(0.0f, 0.0f); glVertex2d(0, HEIGHT);//左下
glTexCoord2f(0.0f, 1.0f); glVertex2d(0, 0);//左上
glTexCoord2f(1.0f, 1.0f); glVertex2d(WIDTH, 0);//右上
glTexCoord2f(1.0f, 0.0f); glVertex2d(WIDTH, HEIGHT);//右下
glEnd();
glDisable(GL_ALPHA_TEST);//アルファテスト終了
glDisable(GL_TEXTURE_2D);//テクスチャ無効

glutSwapBuffers();

参考:
OpenGL描画→OpenCV処理→ピクチャボックス描画
http://ameblo.jp/morimoridiary/theme-10081830227.html
C++/CLI フォームアプリとOpenCVの連携(cv::Mat)
http://ameblo.jp/morimoridiary/entry-11879119909.html
【1. OpenGL画像をOpenCV画像(cv::Mat)に変換】
http://ameblo.jp/morimoridiary/entry-11879119909.html
Kinect for Windows SDKによる3次元ポイントクラウド
http://kassymemo.blogspot.com/2012/04/kinect-for-windows-sdk3.html
http://whoopsidaisies.hatenablog.com/entry/2014/08/20/200215

3Dファイルフォーマットの種類

以下のリンクからの頂き物です。



OBJ †

Wavefront OBJ形式.
  • 多くの3Dモデリング,レンダリングソフトが対応している.
  • 拡張子 : obj
  • ASCII
  • OBJ形式

3DS †

Autodesk 3D Studio(現在は3ds Max)用の形式.
  • シーン,モデリング,アニメーションなど多くのデータを扱える.
  • 多くの3Dモデリング,レンダリングソフトが対応している.
  • 拡張子 : 3ds, max
  • バイナリ
  • ID(2バイト),サイズ(4バイト),データで構成されるチャンクと呼ばれるデータ単位で記述される.チャンクは入れ子構造にできて,子チャンク,孫チャンクなどが存在する.
  • 読込/書込用のライブラリとして,lib3ds (オープンソースソフトウェア (LGPL)) がある.
  • The Labs.com - The Unofficial 3DStudio 3DS File Format
  • Wikipedia - .3ds

VRML †

Web上で使用することを前提に設計された形式
  • Virtual Reality Modeling Language
  • シーン,モデリング,アニメーションなどに加えて他のVRMLファイルへのリンクURLも記述できる.
  • 拡張子 : wrl
  • ASCII
  • Web3Dコンソーシアム

X3D †

VRMLの後継ファイル形式
  • XMLを用いて3Dシーンやオブジェクトを表現できるオープンな形式
  • 拡張子 : x3dv, x3d, x3db
  • ASCII
  • 対応ソフト : Blender
  • Web3Dコンソーシアム

DXF †

Autodesk AutoCAD用のファイル形式.
  • CGソフトだけでなくCAD系ソフトにも対応が多い形式(CAD図面の事実上の標準形式)
  • 拡張子 : dxf
  • ASCII & バイナリ
  • 仕様書
  • CAD用でもあり年々様々なデータに対応していっている.全てに対応した入出力ライブラリを作るのは大変だが, 3Dモデルだけで良いならば,ENTITIESセクションの3DFACEエンティティのみに対応していればOK.
  • 3DFACEだけに対応したDXFファイル入力ライブラリは3Dモデルファイルの入出力を参照.

STL †

3D System社の3D CADソフト用のファイル形式.
  • Standard Triangulated Language
  • 三次元形状を三角形ポリゴン(facet)の集合で表す.
  • 標準ではfacetのみの単純な構造なので,コーディングは楽.
  • 拡張子 : stl
  • ASCII,バイナリ
  • Wikipedia - STL

POV †

POV-Ray(Persistence Of Vision Raytracer)用のファイル形式
  • POV-Rayでレンダリングするシーンを記述する.
  • 拡張子 : pov, inc
  • ASCII
  • POV-Ray

COLLADA †

CGソフト間でデータをやり取りするための交換用ファイル形式
  • COLLAborative Design Activity
  • 元々はSonyがPS3,PSP用に作成した形式
  • Ver1.4よりPhysicsサポートが追加された(Bullet, ODE, PhysXなどが対応)
  • 拡張子 : dae
  • KHRONOSのCOLLADAのぺージ

FBX †

Alias社(Autodeskが買収)がオープンソースとして策定したファイル形式
  • SDKが公開されている.
  • 拡張子 : fbx
  • バイナリ
  • Autodesk FBX

LWO †

NetTek LightWave3D用のファイル形式

PLY †

Stanford Universityが公開しているレンジデータを元にしたメッシュを格納したフォーマット.
  • 拡張子 : ply
  • ASCII
  • The Stanford 3D Scanning Repository
  • 上記URLから,CG分野で有名なモデルをダウンロードできる(Stanford Bunny, Happy Buddha,
  • 対応ソフト : Blender

OFF †

Object File Format.Princeton shape benchmark で使われている.

XSI †

SoftImage XSI(現Autodesk SoftImage)社のモデリングソフトウェアSoftImage用のファイル形式

AC3D †

Inivis社の3D CG モデリング,デザインソフトウェアAC3D用のファイル形式.

C3D †

主にモーションキャプチャデータの格納,配布に用いられているフォーマット

BVH †

C3Dと同様に主にモーションキャプチャデータの格納,配布に用いられているフォーマット