Boost logo

Boost Users :

Subject: Re: [Boost-users] [GIL] Some questions about 2D iteration
From: Christian Henning (chhenning_at_[hidden])
Date: 2010-03-31 17:48:07


Hi Brett, don't have much time right now. Have you read the tutorial?

http://www.boost.org/doc/libs/1_42_0/libs/gil/doc/html/giltutorial.html

I'll read your email for thoroughly tomorrow.

Regards,
Christian

On Wed, Mar 31, 2010 at 5:33 PM, Brett Gmoser <bgmoser_at_[hidden]> wrote:
> Hello everybody,
>
> I've been toying with GIL a bit for the last few days in my spare time, and
> I've got a few questions that I can't seem to find answers to in the
> documentation.  The following function which I've written works, but I'd
> like to get a better understanding of how to use iterators to accomplish the
> same task (the documentation says that view(x, y) = z is inefficient), as
> well as a few other things.  The job of this function is to crop an image,
> discarding any white background. In other words, find the top-most,
> left-most, right-most, and bottom-most pixel that isn't the background color
> (white), and crop the image around those coordinates.
>
>
>  template <typename ViewType, typename ImageType>
>  void crop_image(ViewType& src, boost::scoped_ptr<ImageType>& dst) const
>  {
>    int top = 0;
>    int right = 0;
>    int bottom = 0;
>    int left = 0;
>
>    // Find the top, right, bottom, and left extents. First, find the top.
>    for(int y=0; y < src.height(); ++y)
>    {
>      for(typename ViewType::x_iterator xpos = src.row_begin(y); xpos !=
> src.row_end(y); ++xpos)
>      {
>        if(rgb8_pixel_t(255,255,255) != *xpos)
>        {
>          top = y;
>          break;
>        }
>      }
>      if(top)
>        break;
>    }
>
>    // ... Do similar things for finding the right, bottom, and left extents.
>
>    // We should now have the rectangle of the image, and it should be easy
> to copy everything over.
>    dst.reset(new ImageType(1 + (right - left), 1 + (bottom - top)));
>    for(int x = left; x <= right; ++x)
>      for(int y = top; y <= bottom; ++y)
>        view(*dst)((x - left), (y - top)) = src(x, y);
>  }
>
> So, my first question is - is there a better way to do that first chore of
> finding each extent? Such as a way to use std::find or std::find_if, keeping
> in mind that I have to do two of the four sides in reverse (bottom-to-top to
> find bottom-most, right-to-left to find right-most)?
>
> The next question is about the final loop which copies from the source view
> to the newly created destination image. It seems that using iterators, I
> could do something like this, assuming that I had the above loops find
> iterator positions for all four extents (left, top, bottom, and right are
> iterators):
>
>    // Start the copying process by creating a column iterator for the
> destination table beginning at column 0.
>    // The top iterator starts at the top-most extent - and we cycle through
> the source image in a top-to-bottom,
>    // left-to-right fashion.
>    for(typename ImageType::view_t::y_iterator dst_y =
> view(*dst).col_begin(0);
>        top <= bottom; ++dst_y,++top)
>    {
>      // The left iterator needs to be initialized with whatever row we're on
> - this appears to be impossible.  There doesn't
>      // seem to be any suitable way to do this, so consider it pseudocode.
>      typename ViewType::x_iterator src_x = left.y();
>
>      // The destination X iterator also needs to know what Y position to
> begin on. You'd think you would be able to initialize
>      // it with an iterator position, but it doesn't seem that you can.
>  Again, this doesn't actually compile (it's the
>      // view(*dst).row_begin(y) part).
>      for(typename ImageType::view_t::x_iterator dst_x =
> view(*dst).row_begin(y);
>          // Here, I need to be able to tell if src_x has hit the right
> extent. src_x <= right doesn't seem it will work, because
>          // again right doesn't know it's Y position.
>          src_x != right;
>
>          // And increment both src and destination iterators.
>          ++src_x,++dst_x
>       )
>       {
>         // Finally do the should-be-simple task of assigning the source
> pixel to the destination pixel.
>         *dst_x = *src_x;
>       }
>    }
>
> If you read the comments, most of this doesn't seem to be possible. I've
> seen that there is a "transform_pixel_positions" algorithm that may do
> something close to what I want, but unfortunately I cannot find any
> documentation on it (other than mentioning that it exists, and a short
> example that really doesn't help - one of the few examples actually provided
> by the documentation). It seems to pass a unary argument to a functor, but
> that doesn't seem useful if I don't have both the X and Y coordinates, or an
> X iterator and Y iterator. Also, nowhere can I find where it says what the
> argument passed to the functor actually /is/.
>
> So after I figure these few things out, I'm hoping to be able to speed up my
> program a little bit. Right now everything is pretty slow using that view(x,
> y) method. I'd appreciate any help that anybody can give, thanks!
>
> Brett
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net