FloatImageView* med_filter(const T &src, size_t region_size) { if ((region_size < 1) || (region_size > std::min(src.nrows(), src.ncols()))) throw std::out_of_range("median_filter: region_size out of range"); size_t half_region_size = region_size / 2; typename ImageFactory<T>::view_type* copy = ImageFactory<T>::new_view(src); FloatImageData* data = new FloatImageData(src.size(), src.origin()); FloatImageView* view = new FloatImageView(*data); for (coord_t y = 0; y < src.nrows(); ++y) { for (coord_t x = 0; x < src.ncols(); ++x) { // Define the region. Point ul((coord_t)std::max(0, (int)x - (int)half_region_size), (coord_t)std::max(0, (int)y - (int)half_region_size)); Point lr((coord_t)std::min(x + half_region_size, src.ncols() - 1), (coord_t)std::min(y + half_region_size, src.nrows() - 1)); copy->rect_set(ul, lr); view->set(Point(x, y), image_med(*copy)); } } delete copy; return view; }
FloatImageView* variance_filter(const T &src, const FloatImageView &means, size_t region_size) { if ((region_size < 1) || (region_size > std::min(src.nrows(), src.ncols()))) throw std::out_of_range("variance_filter: region_size out of range"); if (src.size() != means.size()) throw std::invalid_argument("variance_filter: sizes must match"); size_t half_region_size = region_size / 2; // Compute squares of each element. This step avoid repeating the squaring // operation for overlapping regions. FloatImageData* squaredData = new FloatImageData(src.size(), src.origin()); FloatImageView* squares = new FloatImageView(*squaredData); transform(src.vec_begin(), src.vec_end(), squares->vec_begin(), double_squared<typename T::value_type>()); FloatImageData* data = new FloatImageData(src.size(), src.origin()); FloatImageView* view = new FloatImageView(*data); for (coord_t y = 0; y < src.nrows(); ++y) { for (coord_t x = 0; x < src.ncols(); ++x) { // Define the region. Point ul((coord_t)std::max(0, (int)x - (int)half_region_size), (coord_t)std::max(0, (int)y - (int)half_region_size)); Point lr((coord_t)std::min(x + half_region_size, src.ncols() - 1), (coord_t)std::min(y + half_region_size, src.nrows() - 1)); squares->rect_set(ul, lr); // Compute the variance. FloatPixel sum = std::accumulate(squares->vec_begin(), squares->vec_end(), (FloatPixel)0); size_t area = squares->nrows() * squares->ncols(); FloatPixel mean = means.get(Point(x,y)); view->set(Point(x, y), sum / area - mean * mean); } } delete squaredData; delete squares; return view; }