2011年1月27日木曜日

【C++】初めてのOpenCV(コンパイル編)

_
あれこれしてたんですがなかなかコンパイルが通らなかったので、ウマく言った記念にメモ。多分もっといいやり方があるし、ほかのOpenCVをコンパイルしている方法よりも面倒だけど、ともかくC++のライブラリへリンクをしてコンパイルする方法を覚えた。

01#include "highgui.h"
02 
03int main(int argc , char** argv){
04  IplImage* img = cvLoadImage(argv[1]);
05  cvNamedWindow("Example1", CV_WINDOW_AUTOSIZE );
06  cvShowImage( "Exapmle1" , img );
07  cvWaitKey(0);
08  cvReleaseImage(&img);
09  cvDestroyWindow( "Example1" );
10}


で、下のようにすれば、コンパイルできました。
1g++-4.0 main.cpp -o main -I/usr/local/include/opencv
2                 -L/usr/local/lib -lopencv_core -lopencv_highgui


ちなみにOpenCVの入れ方は
Mac OSX Snow LeopardにOpenCVを入れてXCodeから使えるようにする手順 (konisimple log)
を参考にさせていただきました。
リンクファイルのパスは
1pkg-config --cflags opencv


1pkg-config --libs opencv


で、調べています。

2011年1月5日水曜日

【C++】vectorで要素の参照が無効になる。

   今書いているプログラムで、可変長配列のvectorをつかっていろいろいじくろうとしていたんだけれど、new演算子を使ってインスタンス化したクラスのポインタをそのままpush_back()したら、何回か格納した後"EXC_BAD_ACCESS"といわれて止まう現象が起こる。まだ解決方法はわかっていないのだけれど、どうやら以下の二つが原因っぽいので忘れないようにメモ。(そろそろ寝る時間なので)

もとはこんな感じです。

1Hoge *hoge = new Hoge();
2hoge ->foo();
3vec.push_back(*hoge);


たぶん原因は下記二点

要素数が自動的に変更されると書きましたが、vector はある程度の個数分の領域を事前に一括で確保しておき、 それが足りなくなったとき(新たに要素を追加しようとして、足りなかったとき)に、領域を拡張するのです。
http://www.geocities.jp/ky_webid/cpp/library/002.html


vector は、配列の長さを増加させた場合、要素の参照や、要素を指すポインタは、無効になる、と覚えておきましょう。
http://homepage2.nifty.com/well/STL.html


そもそもC++が全然わかっていない。


【追記】解決しました。

サンプルコードの正誤表を見たらあっさり訂正が書いてありました。まぁ、勉強になったからよかったとは思いますが。よく考えたら可変長でメモリを再確保するのならば、参照がずれるのは当然なのかもしれませんね。
1vector <CSample*> hoge;

と、vector の要素を自体をポインタにしてあげればよいとのこと。そうするとこうやって配列に入れることができるみたいです。

1Hoge *hoge = new Hoge();
2hoge ->foo();
3vec.push_back(hoge);