void image_traversal(const ImageView& img, Container& container) { using namespace boost::gil; std::cout << "img height: " << img.height() << std::endl; std::cout << "img width : " << img.width() << std::endl; std::cout << " values:" << num_channels<ImageView>::value << std::endl; long cnt_row = 0; long cnt_col = 0; for (typename ImageView::iterator it=img.begin(); it!=img.end(); ++it ) { for (int c=0; c < num_channels<ImageView>::value; ++c) { long val = (*it)[c]; container[ cnt_row ][ cnt_col ][c] = val; // std::cout << "cntrow: " << cnt_row << " cntcol: " << cnt_col << std::endl; } if ( cnt_col == (img.width()-1) ) { ++cnt_row; cnt_col = 0; } else ++cnt_col; } }
ImagePyramid<T> gaussian_pyramid(const ImageView<T>& image, const ImagePyramidParams& params = ImagePyramidParams()) { using Scalar = typename ImagePyramid<T>::scalar_type; // Resize the image with the appropriate factor. auto resize_factor = pow(2.f, -params.first_octave_index()); auto I = enlarge(image, resize_factor); // Deduce the new camera sigma with respect to the dilated image. auto camera_sigma = Scalar(params.scale_camera())*resize_factor; // Blur the image so that its new sigma is equal to the initial sigma. auto init_sigma = Scalar(params.scale_initial()); if (camera_sigma < init_sigma) { Scalar sigma = sqrt(init_sigma*init_sigma - camera_sigma*camera_sigma); I = gaussian(I, sigma); } // Deduce the maximum number of octaves. auto l = std::min(image.width(), image.height()); auto b = params.image_padding_size(); // l/2^k > 2b // 2^k < l/(2b) // k < log(l/(2b))/log(2) auto num_octaves = static_cast<int>(log(l/(2.f*b))/log(2.f)); // Shorten names. auto k = Scalar(params.scale_geometric_factor()); auto num_scales = params.num_scales_per_octave(); auto downscale_index = int( floor( log(Scalar(2))/log(k)) ); // Create the image pyramid auto G = ImagePyramid<T>{}; G.reset(num_octaves, num_scales, init_sigma, k); for (auto o = 0; o < num_octaves; ++o) { // Compute the octave scaling factor G.octave_scaling_factor(o) = (o == 0) ? 1.f/resize_factor : G.octave_scaling_factor(o-1)*2; // Compute the gaussians in octave \f$o\f$ Scalar sigma_s_1 = init_sigma; G(0, o) = o == 0 ? I : downscale(G(downscale_index, o - 1), 2); for (auto s = 1; s < num_scales; ++s) { auto sigma = sqrt(k*k*sigma_s_1*sigma_s_1 - sigma_s_1*sigma_s_1); G(s,o) = gaussian(G(s-1,o), sigma); sigma_s_1 *= k; } } // Done! return G; }
//! @brief Operator. Image<descriptor_type> operator()(const ImageView<float>& image, int patch_size = 8) { // Blur the image a little bit. // By default, sigma is '1.6' and is justified in A-SIFT paper [Morel, Yu]. auto blurred_image = image.compute<DericheBlur>(1.6f); // Compute the image gradients in polar coordinates. auto gradients = gradient_polar_coordinates(blurred_image); // Compute the feature vector in each pixel. auto patch_radius = patch_size / 2; auto features = Image<descriptor_type> { image.sizes() }; features.array().fill(descriptor_type::Zero()); for (auto y = patch_radius; y < image.height() - patch_radius; ++y) for (auto x = patch_radius; x < image.width() - patch_radius; ++x) features(x, y) = _compute_feature(float(x), float(y), float(patch_radius), gradients); return features; }
inline void colorAberration(ImageView source, ImageView destination) { unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); std::default_random_engine generator(seed); std::uniform_int_distribution<int> red_distribution(2,8); std::uniform_int_distribution<int> green_distribution(1,6); std::uniform_int_distribution<int> blue_distribution(-8,-2); std::uniform_real_distribution<double> distribution(0.9, 1.0); auto red_dice = std::bind(red_distribution, generator); auto blue_dice = std::bind(blue_distribution, generator); auto green_dice = std::bind(green_distribution, generator); auto noise_fn = std::bind(distribution, generator); using namespace boost::gil; rgb8_view_t::x_iterator src_it, dest_r_it, dest_g_it, dest_b_it; //#pragma omp parallel for for (int y = 0; y < source.height(); ++y) { src_it = source.row_begin(y); dest_r_it = destination.row_begin(y) + red_dice(); dest_g_it = destination.row_begin(y) + green_dice(); dest_b_it = destination.row_begin(y) + blue_dice(); double noise = 0.0; for (; src_it < source.row_end(y); ++src_it, ++dest_r_it, ++dest_g_it, ++dest_b_it) { noise = noise_fn(); if (dest_r_it > destination.row_begin(y) && dest_r_it < destination.row_end(y)) { dest_r_it[0][0] = y % 2 == 1 ? src_it[0][0] * noise : src_it[0][0] * 0.9 * noise; } if (dest_g_it > destination.row_begin(y) && dest_g_it < destination.row_end(y)) { dest_g_it[0][1] = y % 2 == 1 ? src_it[0][1] * noise : src_it[0][1] * 0.9 * noise; } if (dest_b_it > destination.row_begin(y) && dest_b_it < destination.row_end(y)) { dest_b_it[0][2] = y % 2 == 1 ? src_it[0][2] * noise : src_it[0][2] * 0.9 * noise; } } } }
vector<Point2i> compute_region_inner_boundary(const ImageView<int>& regions, int region_id) { #ifndef CONNECTIVITY_4 const Vector2i dirs[] = { Vector2i{ 1, 0 }, Vector2i{ 1, 1 }, Vector2i{ 0, 1 }, Vector2i{-1, 1 }, Vector2i{-1, 0 }, Vector2i{-1, -1 }, Vector2i{ 0, -1 }, Vector2i{ 1, -1 } }; #else const Vector2i dirs[] = { Vector2i{ 1, 0 }, Vector2i{ 0, 1 }, Vector2i{-1, 0 }, Vector2i{ 0, -1 } }; #endif const int num_dirs{ sizeof(dirs) / sizeof(Vector2i) }; // Find the starting point. auto start_point = Point2i{ -1, -1 }; for (int y = 0; y < regions.height(); ++y) { for (int x = 0; x < regions.width(); ++x) { if (regions(x, y) == region_id) { start_point = Point2i(x, y); break; } } } if (start_point == Point2i{ -1, -1 }) return {}; auto boundary = vector<Point2i>{ start_point }; #ifndef CONNECTIVITY_4 int dir = 7; #else int dir = 0; #endif do { const Point2i& current_point{ boundary.back() }; #ifndef CONNECTIVITY_4 dir = (dir % 2) == 0 ? (dir + 7) % 8 : (dir + 6) % 8; #else dir = (dir + 3) % 4; #endif for (int d = 0; d < num_dirs; ++d) { Point2i next_point{ current_point + dirs[(dir + d) % num_dirs] }; if (next_point.minCoeff() < 0 || (regions.sizes() - next_point).minCoeff() <= 0) continue; if (regions(next_point) == region_id) { boundary.push_back(next_point); dir = (dir + d) % num_dirs; break; } } } while (boundary.back() != start_point); if (boundary.size() > 1) boundary.pop_back(); return boundary; }
inline QImage as_QImage(ImageView<Rgb8>& image) { return QImage{reinterpret_cast<unsigned char *>(image.data()), image.width(), image.height(), image.width() * 3, QImage::Format_RGB888}; }