boost::tuple<double, int, int> detect_slope(boost::gil::rgb8_image_t const& source) { boost::gil::rgb8c_view_t::xy_locator src_loc = boost::gil::const_view(source).xy_at(0, 0); int const w = source.width(); int const h = source.height(); int x = -1; int y = source.height() - 1; for (int i = y + 1; x < 0 && i > 0; --i, --y) { for (int xx = 0; xx < source.width(); ++xx) { if (is_border_mark(src_loc(xx, y)) && ((xx > 0 && y > 0 && is_border_mark(src_loc(xx-1, y-1))) || ( y > 0 && is_border_mark(src_loc(xx, y-1))) || (xx+1 < w && y > 0 && is_border_mark(src_loc(xx+1, y-1))))) { std::string msg = (boost::format("(%d, %d)") % xx % y).str(); ::MessageBox(NULL, multi_to_wide(msg).c_str(), L"slope-bottom was detected", MB_OK); while (is_border_mark(src_loc(xx+1, y))) ++xx; x = xx; break; } } } std::vector<boost::gil::point2<int> > points; if (x <= source.width() / 2) { collect_slope_points_right(source, x, y, std::back_inserter(points)); } else { collect_slope_points_left(source, x, y, std::back_inserter(points)); } double slope, intercept; boost::tie(slope, intercept) = linear_interpolate(points.begin(), points.end()); return boost::make_tuple(slope, x, y); }
pixel_t bilinear_sampler_t::sample( int x, int y, float t, float s) const { float it = 1.0f - t; float is = 1.0f - s; const_image_view_t::xy_locator src_loc( src_.xy_at( x - src_area_.min.x, y - src_area_.min.y)); pixel_t a( *src_loc); pixel_t b( src_loc[tr_]); pixel_t top( (a[0]*it) + (b[0]*t), (a[1]*it) + (b[1]*t), (a[2]*it) + (b[2]*t), (a[3]*it) + (b[3]*t)); a = src_loc[bl_]; b = src_loc[br_]; pixel_t bot( (a[0]*it + b[0]*t), (a[1]*it) + (b[1]*t), (a[2]*it) + (b[2]*t), (a[3]*it) + (b[3]*t)); return pixel_t( (top[0]*is) + (bot[0]*s), (top[1]*is) + (bot[1]*s), (top[2]*is) + (bot[2]*s), (top[3]*is) + (bot[3]*s)); }
void collect_slope_points_right(boost::gil::rgb8_image_t const& source, int x, int y, Output out) { boost::gil::rgb8c_view_t::xy_locator src_loc = boost::gil::const_view(source).xy_at(0, 0); int const w = source.width(); int const h = source.height(); typedef typename Output::container_type::value_type point_type; *out++ = point_type(x, y); for (; x < source.width(); ++x) { int yy = source.height() - 1; for (int i = yy + 1; i > 0; --i, --yy) { if (is_border_mark(src_loc(x, yy))) break; } if (y - 1 <= yy && yy <= y + 1) { *out++ = point_type(x, yy); if (yy == y - 1) y = yy; } } }