重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

opencvのシーケンスについて。

opencvのシーケンスとは。
opencvを使っていると、よくシーケンスという言葉に遭遇します。本やネットで調べましたが、どんなものなのかがよく分かりません。
メモリストレージ・オブジェクト等と一緒に出てくるのですが、これらもなかなか理解しがたいです…

例えばCvFindCountorという画像内のn個の辺を持つ輪郭を調べるという関数がありますが、これに関する情報が引数として渡したシーケンスに保存されているようだ。というのは何となく感じとったのですが、この中の座標等を引き出すにはどうしたらいいのでしょうか。

どなたか分かりやすくご教授頂けないでしょうか。
また、分かりやすいサイトや本もご存知であれば教えて下さい。

A 回答 (2件)

CV_GET_SEQ_ELEMで取得する輪郭を構成する頂点座標はcvFindContours関数の6番目の引数methodの設定で取得できる座標が異なります。


method = CV_CHAIN_APPROX_NONEとすると輪郭の座標全てを取得し、
method = CV_CHAIN_APPROX_SIMPLEとすると、輪郭を縦、横、斜め(45°)の直線で構成される折れ線で表した時の角の座標を取得します。
method = CV_CHAIN_APPROX_TC89_L1 もしくは CV_CHAIN_APPROX_TC89_KCOS とすると斜め45°以外の直線も含む、直線で輪郭を近似したときの折れ線の角の座標を取得出来るのですが、直線近似のアルゴリズムは私はあまり良く知りません...
    • good
    • 0
この回答へのお礼

ありがとうございます!
cvFindCountorsにそんな便利な引数があるとは知りませんでした!!
早速試してみます。
ずっと引っ掛かっていた事がものすごいスッキリとしました!!
本当にありがとうございました!!!

お礼日時:2010/06/24 06:57

シーケンスやメモリストレージについては、正直、あまり理解はしていないのですが、cvFindContoursなら...という程度ですが。


シーケンスというのはC言語でいうところの『リスト構造』のようなものだと思います。
例えば、cvFindContoursのような輪郭を抽出する関数では、処理する前からは輪郭の個数は分からないので、輪郭の情報を格納するメモリは予め確保しておく事ができません。
そういう時にC言語ではリストを使います。
リストについては別途調べて頂くと分かると思いますが、例えば、最初に見つかった輪郭の情報を『A』、次に見つかった輪郭を『B』、次が『C』・・・最後に見つかった輪郭が『F』とすると、
 A⇔B⇔C⇔D⇔E⇔F
というように、それぞれの輪郭の情報に前後関係の情報を保持しておきます。
例えば、『C』の輪郭の情報の中に一つまえが『B』で次が『D』である事を保持しておきます。
この前後関係を保持しているのがシーケンス(CvSeq)だと思います。
(参考)
http://opencv.jp/opencv-1.0.0/document/opencvref …

cvFindContoursの場合、3番目の引数(contour)に最初の輪郭情報のポインタが格納され、
contour = contour->h_next
とすると、次の輪郭情報を参照する事ができます。
この辺は
http://opencv.jp/opencv-2svn/c/drawing_functions …

のページのcvDrawContoursのサンプルを見ると比較的分かりやすいかと思います。
また、cvFindContoursの場合は輪郭の内側、外側の情報も構築できるのできるのですが、どのように取得するかはcvFindContoursの5番目の引数(mode)の設定で決まります。
modeをCV_RETR_TREEにすると、輪郭情報がツリー構造で取得する事が出来ます。
この場合、輪郭の内側の輪郭も取得できるので、その場合は
contour = contour->v_next
とする内側の輪郭を参照する事が出来ます。
つまり、現在の輪郭(contour)の一つ次の輪郭はh_next、一つ前の輪郭はh_prev、一つ内側の輪郭はv_next、一つ外側の輪郭はv_prev となっています。
(説明が分かりづらくてスイマセン)

そして、coutourについての輪郭の座標などの取得方法はこんな感じ↓です。

//面積
double Area = fabs(cvContourArea(coutour, CV_WHOLE_SEQ));
//周囲長
double Perimeter = cvArcLength(coutour);
//輪郭を構成する頂点座標を取得
for ( int i = 0; i < coutour->total; i++){
CvPoint *point = CV_GET_SEQ_ELEM (CvPoint, coutour, i);
}

という感じで参考になりますでしょうか?

この回答への補足

返事おそくなってしまい申し訳ありません!
回答ありがとうございました。

おかげさまでCvFindCountorsが何をやっているのかが理解できた気がします。
最後の輪郭を構成する頂点座標を取得するというCV_GET_SEQ_ELEMという関数についてですが
早速使ってみたのですが、これは輪郭を構成する辺の座標という事なのでしょうか。
輪郭を構成する角点(特徴点?)の座標のみを抽出してくれる関数というのはないのでしょうか。

補足日時:2010/06/19 02:12
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!