- ベストアンサー
opencvのシーケンスとは?座標の取得方法も知りたい!
- opencvのシーケンスとは、メモリストレージオブジェクトと一緒に使用されるデータ構造です。
- シーケンスは、画像処理の中でよく使われ、特に輪郭の情報を格納するのに使用されます。
- CvFindCountorという関数では、引数として渡されたシーケンスに輪郭の情報が保存されています。座標を取得するには、シーケンスの要素を参照することで可能です。
- みんなの回答 (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°以外の直線も含む、直線で輪郭を近似したときの折れ線の角の座標を取得出来るのですが、直線近似のアルゴリズムは私はあまり良く知りません...
その他の回答 (1)
- Akira_Imaging
- ベストアンサー率60% (3/5)
シーケンスやメモリストレージについては、正直、あまり理解はしていないのですが、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_cxcore_sequences.html#decl_CvSeq cvFindContoursの場合、3番目の引数(contour)に最初の輪郭情報のポインタが格納され、 contour = contour->h_next とすると、次の輪郭情報を参照する事ができます。 この辺は http://opencv.jp/opencv-2svn/c/drawing_functions.html のページの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という関数についてですが 早速使ってみたのですが、これは輪郭を構成する辺の座標という事なのでしょうか。 輪郭を構成する角点(特徴点?)の座標のみを抽出してくれる関数というのはないのでしょうか。
お礼
ありがとうございます! cvFindCountorsにそんな便利な引数があるとは知りませんでした!! 早速試してみます。 ずっと引っ掛かっていた事がものすごいスッキリとしました!! 本当にありがとうございました!!!