[OpenCV 2]反復器を使用してポインタを巡回する


オブジェクト向けのプログラムでは、1つのループデータの収集に反復器が一般的に使用する.反復器は、各要素を保存するために専用のクラスです.与えられた集合に対して、各要素をどのように取得するかの操作は見えない.この情報隠蔽の原理の応用は容器の遍歴を容易にする.また、どのような種類の集合を用いるも似ている.標準ライブラリテンプレート(STL)には、1つのコンテナクラスとその各集合クラスが関連する.OpenCVは、C++STLの標準容器と互換性のあるcv::Mat容器類を提供する.
Getting ready
この節では、色縮小の例を用いて説明する.
How to do it ...
1つのcv::Matオブジェクトの場合、反復オブジェクトには、まずcv::MatIterator_が作成されます.objectの操作cv::Mat_subclassの場合、この下線表名はテンプレートの方法である.画像容器は通常、画像要素を返すために用いるが、コンパイル時に戻るタイプを知る必要がある.コンテナは次のように宣言されています.
cv::MatIterator_<cv::Vec3b> it;

別の選択肢としてMat_を使用することもできますtemplateクラス定義コンテナタイプ:
 cv::Mat_<cv::Vec3b>::iterator it;

通常、beginおよびend容器法を用いる画素を巡回する.カラー削減機能は次のとおりです.
void colorReduce(cv::Mat &image, int div=64) {
     // obtain iterator at initial position
     cv::Mat_<cv::Vec3b>::iterator it= 
               image.begin<cv::Vec3b>();
     // obtain end position
     cv::Mat_<cv::Vec3b>::iterator itend= 
               image.end<cv::Vec3b>();
     // loop over all pixels
     for ( ; it!= itend; ++it) {
        // process each pixel ---------------------       (*it)[0]= (*it)[0]/div*div + div/2;
       (*it)[1]= (*it)[1]/div*div + div/2;
       (*it)[2]= (*it)[2]/div*div + div/2;
        // end of pixel processing ----------------     }
}
容器の戻りタイプはcv::Vec 3 bであることを覚えておいてください.私たちはカラー画像を処理しているからです.各カラーチャネルは、リロードオペレータ[]を用いるアクセスされる.
How it works...
コンテナを使用すると、どんな種類の集合でも、いつも同じパターンが使用される.
まず、適切な専門クラスを使用します.ここではcv::Mat_<を使用します.cv::Vec 3 b>::iterator(or cv::MatLterator_)コンテナオブジェクトを作成する.
beginメソッドを使用すると、開始位置のコンテナの初期値(私たちの例では、画像の左上隅の点)が得られます.例ではimageを用いる.beigin()方法実現.反復器で計算できます例:
画像の2行目から開始したい場合はimageを使用します.begin()+image.rows初期化cv::Mat容器.容器の終了位置はend法を用いる以外は同様である.しかし、この反復器はあなたが必要とするいくつかの外側にしかありません.反復器は、例えば、反復器ポインタが画像の最後の行に達する前に停止したい場合に計算することができる.end(-image.rows.
容器の初期化が完了すると、終了するまですべての要素をループしなければなりません.典型的なwhileサイクルは次のとおりです.
while (it!= itend) {
        
        // process each pixel ---------------------         …
        // end of pixel processing ----------------        ++it;
     }
このリロードオペレータ++は、次の要素に移動するためのものである.より大きなステップを指定できます.例えばit+=10は、10画素ずつ移動する.
最終的に、ループ操作では、リロードオペレータ*を使用して現在のピクセルの値を範囲することができます.(例えば、element=*it読み取り、*it=element書き込み).なお、定数容器を作成することもできる.const cv::Mat参照を受け取った場合、または現在のループがcv::Matの初期値を変更しないことを望んでいます.次のように定義できます.
     cv::MatConstIterator_<cv::Vec3b> it;
or:
     cv::Mat_<cv::Vec3b>::const_iterator it;

There's more...
本節では、テンプレートメソッドbeginとendを用いて容器の初期位置と終了位置を取得する.この章の最初の例では、cv::Mat_を使用することもできます.instance .これにより、beginメソッドとendメソッドを使用する場合、cv::Mat_referenceが作成されたとき.
   cv::Mat_<cv::Vec3b> cimage= image;
     cv::Mat_<cv::Vec3b>::iterator it= cimage.begin();
     cv::Mat_<cv::Vec3b>::iterator itend= cimage.end();

See also
反復器を使用してサイクルを巡る効率については後述する
オブジェクト向けプログラミングでコンテナの使用に慣れていない場合は、ANSIC++でどのように操作されているか、STLコンテナの説明を読む必要があります.簡単な方法は、サイトにキーワード「STL Iterator」を入力することで、多くの参考文献を得ることができます.