|
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