OpenCV 4 Computer Vision Application Programming Cookbook(Fourth Edition)
上QQ阅读APP看书,第一时间看更新

How it works...

Working with iterators always follows the same pattern, no matter what kind of collection is scanned.

First, you create your iterator object using the appropriate specialized class, which, in our example, is cv::Mat_<cv::Vec3b>::iterator (or cv::MatIterator_<cv::Vec3b>).

You then obtain an iterator initialized at the starting position (in our example, the upper left corner of the image). This is done using a begin method. With a cv::Mat instance, you obtain it as image.begin<cv::Vec3b>(). You can also use arithmetic on the iterator. For example, if you wish to start at the second row of an image, you can initialize your cv::Mat iterator at image.begin<cv::Vec3b>()+image.cols. The end position of your collection is obtained similarly, but by using the end method. However, the iterator thus obtained is just outside your collection. This is why your iterative process must stop when it reaches the end position. You can also use arithmetic on this iterator; for example, if you wish to stop before the last row, your final iteration would stop when the iterator reaches image.end<cv::Vec3b>()-image.cols.

Once your iterator is initialized, you create a loop that goes over all elements until the end is reached. A typical while loop will look like the following code:

     while (it!= itend) {  
 
        // process each pixel --------------------- 
          
 
        // end of pixel processing ---------------- 
 
        ++it; 
     } 

The ++ operator is the one that is to be used to move to the next element. You can also specify the larger step size. For example, it+=10 would be processed every 10 pixels.

Finally, inside the processing loop, you use the dereferencing * operator in order to access the current element. Using this, you can read (for example, element= *it;) or write (for example, *it= element;). Note that it is also possible to create constant iterators that you use if you receive a reference to const cv::Mat or if you wish to signify that the current loop does not modify the cv::Mat instance. These are declared as follows:

     cv::MatConstIterator_<cv::Vec3b> it;

Or they are declared as follows:

     cv::Mat_<cv::Vec3b>::const_iterator it;