<commit_before>// ========================================================================== //
// This file is part of DO++, a basic set of libraries in C++ for computer 
// vision.
//
// Copyright (C) 2013 <NAME> <<EMAIL>>
//
// This Source Code Form is subject to the terms of the Mozilla Public 
// License v. 2.0. If a copy of the MPL was not distributed with this file, 
// you can obtain one at http://mozilla.org/MPL/2.0/.
// ========================================================================== //

//! @file

#ifndef DO_IMAGEPROCESSING_SCALING_HPP
#define DO_IMAGEPROCESSING_SCALING_HPP

namespace DO {

  /*!
    \ingroup ImageProcessing
    \defgroup Scaling Reduce, enlarge, warp image...
    @{
   */

  // ====================================================================== //
  // Naive upsampling and downsampling functions.
  template <typename T, int N>
  Image<T, N> upscale(const Image<T, N>& I, int fact)
  {
    Image<T, N> I1(I.sizes()*fact);
    typename Image<T, N>::range_iterator it(I1.begin_range());
    typename Image<T, N>::range_iterator end(I1.end_range());
    for ( ; it != end; ++it)
      *it = I(it.coords() / fact);
    return I1;
  }

  template <typename T, int N>
  Image<T, N> downscale(const Image<T, N>& I, int fact)
  {
    Image<T, N> I1(I.sizes()/fact);
    typename Image<T, N>::range_iterator it(I1.begin_range());
    typename Image<T, N>::range_iterator end(I1.end_range());
    for ( ; it != end; ++it)
      *it = I(it.position()*fact);
    return I1;
  }

  template <typename T, int N>
  inline std::pair<T, T> range(const Matrix<T, N, 1>& v)
  {
    return std::make_pair(
      *std::min_element(v.data(), v.data()+N),
      *std::max_element(v.data(), v.data()+N)
    );
  }

  template <typename T, int N>
  Image<T, N> reduce(const Image<T,N>& I, Matrix<int, N, 1> newSizes,
                     bool keepRatio=false)  
  {
    typedef Matrix<double, N, 1> Vectord;

    // Convert in floating type scalar.
    typedef typename ColorTraits<T>::Color64f Color64f;
    Image<Color64f, N> oriI;
    convert(oriI, I);

    // Determine the right blurring factor.
    Vectord oriSizes(I.sizes().template cast<double>());
    Vectord f = oriSizes.cwiseQuotient(newSizes.template cast<double>());
    std::pair<double, double> mM = range(f);
    assert(mM.first >= 1.);
    if (keepRatio)
    {
      f.fill(mM.second);
      newSizes = (oriSizes/mM.second).template cast<int>();
    }

    Vectord sigmas = 1.5*((f.array().sqrt()-.99).matrix());

    // Blur with the Deriche filter.
    inPlaceDericheBlur(oriI, sigmas);

    // Create the new image by interpolating pixel values.
    Image<T, N> nI(newSizes);
    typename Image<T, N>::range_iterator r(nI.begin_range());
    typename Image<T, N>::range_iterator end(nI.end_range());
    for ( ; r != end; ++r)
    {
      Vectord x( r.coords()->template cast<double>().cwiseProduct(f) );
      convertColor(*r, interpolate(oriI, x));
    }

    return nI;
  }
  
  template <typename T>
  inline  Image<T,2> reduce(const Image<T,2>& I, int w, int h, bool keepRatio=false)
  { return reduce(I, Vector2i(w,h), keepRatio); }
  
  template <typename T>
  inline Image<T,3> reduce(const Image<T,3>& I, int w, int h, int d, bool keepRatio=false)
  { return reduce(I, Vector3i(w,h,d), keepRatio); }
  
  template <typename T,int N>
  inline Image<T,N> reduce(const Image<T,N>& I,double fact)  
  {
    Matrix<int, N, 1> nd( (I.sizes().template cast<double>()/fact).
                         template cast<int>() );
    return reduce(I,nd);
  }

  template <typename T, int N>
  inline Image<T,N> enlarge(const Image<T,N>& I, Matrix<int, N, 1> newSizes,
                            bool keepRatio=false)  
  {
    typedef Matrix<double, N, 1> Vectord;

    // Determine the right blurring factor.
    Vectord oriSizes(I.sizes().template cast<double>());
    Vectord f = oriSizes.cwiseQuotient(newSizes.template cast<double>());
    std::pair<double, double> mM = range(f);
    assert(mM.second <= 1.);
    if (keepRatio)
    {
      f.fill(mM.second);
      newSizes = (oriSizes/mM.second).template cast<int>();
    }

    // Create the new image by interpolation.
    Image<T,N> nI(newSizes);
    typename Image<T, N>::range_iterator r(nI.begin_range());
    typename Image<T, N>::range_iterator end(nI.end_range());
    for ( ; r != end; ++r)
    {
      Vectord x( r.position().template cast<double>().cwiseProduct(f) );
      convertColor(*r, interpolate(I, x));
    }
    return nI;
  }

  template <typename T>
  inline Image<T,2> enlarge(const Image<T,2>& I, int w, int h,
                            bool keepRatio = false)
  { return enlarge(I, Point2i(w,h), keepRatio); }

  template <typename T>
  inline Image<T,3> enlarge(const Image<T,3>& I, int w, int h, int d,
                            bool keepRatio = false)
  { return enlarge(I, Vector3i(w,h,d), keepRatio); }

  template <typename T,int N>
  inline Image<T,N> enlarge(const Image<T,N>&I,double fact)  
  {
    Matrix<int, N, 1> nd( (I.sizes().template cast<double>()*fact).
                         template cast<int>() );
    return enlarge(I,nd);
  }

  //! @} file
}

#endif /* DO_IMAGEPROCESSING_SCALING_HPP */<commit_msg>Clean code and add some docstrings.<commit_after>// ========================================================================== //
// This file is part of DO++, a basic set of libraries in C++ for computer 
// vision.
//
// Copyright (C) 2013 <NAME> <<EMAIL>>
//
// This Source Code Form is subject to the terms of the Mozilla Public 
// License v. 2.0. If a copy of the MPL was not distributed with this file, 
// you can obtain one at http://mozilla.org/MPL/2.0/.
// ========================================================================== //

//! @file

#ifndef DO_IMAGEPROCESSING_SCALING_HPP
#define DO_IMAGEPROCESSING_SCALING_HPP


#include <DO/Core/Image/Image.hpp>
#include <DO/Core/Image/Operations.hpp>
#include <DO/ImageProcessing/Deriche.hpp>
#include <DO/ImageProcessing/Interpolation.hpp>


namespace DO {

  /*!
    \ingroup ImageProcessing
    \defgroup Scaling Reduce, enlarge, warp image...
    @{
   */

  //! \brief Upscale image.
  template <typename T, int N>
  Image<T, N> upscale(const Image<T, N>& src, int fact)
  {
    Image<T, N> dst(src.sizes()*fact);
    typename Image<T, N>::array_iterator it(dst.begin_array());
    for ( ; !it.end(); ++it)
      *it = src(it.position() / fact);
    return dst;
  }

  //! \brief Downscale image.
  template <typename T, int N>
  Image<T, N> downscale(const Image<T, N>& src, int fact)
  {
    Image<T, N> dst(src.sizes()/fact);
    typename Image<T, N>::array_iterator it(dst.begin_array());
    for ( ; !it.end(); ++it)
      *it = src(it.position()*fact);
    return dst;
  }

  //! \brief Find min and max coefficient of a vector.
  template <typename T, int N>
  inline std::pair<T, T> range(const Matrix<T, N, 1>& v)
  {
    return std::make_pair(
      *std::min_element(v.data(), v.data()+N),
      *std::max_element(v.data(), v.data()+N)
    );
  }

  //! \brief Reduce image.
  template <typename T, int N>
  Image<T, N> reduce(const Image<T, N>& src, Matrix<int, N, 1> new_sizes,
                     bool keep_ratio=false)  
  {
    // Typedefs.
    typedef typename PixelTraits<T>::template Cast<double>::pixel_type
      DoublePixel;
    typedef typename PixelTraits<T>::channel_type ChannelType;

    // Convert in floating type scalar.
    Image<DoublePixel, N> double_src;
    convert_channel(src, double_src);

    Matrix<double, N, 1> original_sizes;
    Matrix<double, N, 1> scale_factors;
    Matrix<double, N, 1> sigmas;
    std::pair<double, double> min_max;

    // Determine the right blurring factor.
    original_sizes = src.sizes().cast<double>();
    scale_factors = original_sizes.cwiseQuotient(new_sizes.cast<double>());
    min_max = range(scale_factors);
    if (keep_ratio)
    {
      scale_factors.fill(min_max.second);
      new_sizes = (original_sizes/min_max.second).cast<int>();
    }
    sigmas = 1.5*((scale_factors.array().sqrt()-.99).matrix());

    // Blur with Deriche filter.
    inplace_deriche_blur(double_src, sigmas);

    // Create the new image by interpolating pixel values.
    Image<T, N> dst(new_sizes);
    typename Image<T, N>::array_iterator dst_it(dst.begin_array());
    for ( ; !dst_it.end(); ++dst_it)
    {
      Matrix<double, N, 1> position( dst_it.position()
        .cast<double>()
        .cwiseProduct(scale_factors) );

      DoublePixel double_pixel_value;
      double_pixel_value = interpolate(double_src, position);
      convert_channel(double_pixel_value, *dst_it);
    }

    return dst;
  }
  
  //! \brief Reduce image.
  template <typename T>
  inline  Image<T, 2> reduce(const Image<T, 2>& image, int w, int h,
                             bool keep_ratio = false)
  {
    return reduce(image, Vector2i(w,h), keep_ratio);
  }
  
  //! \brief Reduce image.
  template <typename T>
  inline Image<T, 3> reduce(const Image<T, 3>& image, int w, int h, int d,
                            bool keep_ratio = false)
  {
    return reduce(image, Vector3i(w,h,d), keep_ratio);
  }
  
  //! \brief Reduce image.
  template <typename T,int N>
  inline Image<T, N> reduce(const Image<T, N>& image, double fact)  
  {
    Matrix<double, N, 1> new_sizes;
    new_sizes = image.sizes().template cast<double>() / fact;
    return reduce(image, new_sizes.template cast<int>().eval());
  }

  //! \brief Reduce image.
  template <typename T, int N>
  inline Image<T, N> enlarge(const Image<T, N>& image,
                             Matrix<int, N, 1> new_sizes,
                             bool keep_ratio = false)
  {
    typedef Matrix<double, N, 1> double_coords_type;

    // Determine the right blurring factor.
    double_coords_type original_sizes(image.sizes().template cast<double>());
    double_coords_type scale_factor = original_sizes.cwiseQuotient(
      new_sizes.cast<double>());
    std::pair<double, double> min_max = range(scale_factor);

    if (keep_ratio)
    {
      scale_factor.fill(min_max.second);
      new_sizes = (original_sizes/min_max.second).cast<int>();
    }

    // Create the new image by interpolation.
    Image<T,N> dst(new_sizes);
    typename Image<T, N>::array_iterator dst_it(dst.begin_array());
    for ( ; !dst_it.end(); ++dst_it)
    {
      double_coords_type position;
      position = dst_it.position()
        .template cast<double>()
        .cwiseProduct(scale_factor);
      convert_channel(interpolate(image, position), *dst_it);
    }
    return dst;
  }

  //! \brief Enlarge image.
  template <typename T>
  inline Image<T, 2> enlarge(const Image<T, 2>& image, int w, int h,
                             bool keep_ratio = false)
  {
    return enlarge(image, Point2i(w,h), keep_ratio);
  }

  //! \brief Enlarge image.
  template <typename T>
  inline Image<T, 3> enlarge(const Image<T, 3>& image, int w, int h, int d,
                             bool keep_ratio = false)
  {
    return enlarge(image, Vector3i(w,h,d), keep_ratio);
  }

  //! \brief Enlarge image.
  template <typename T,int N>
  inline Image<T, N> enlarge(const Image<T, N>& image, double fact)  
  {
    Matrix<double, N, 1> new_sizes;
    new_sizes = image.sizes().cast<double>()*fact;
    return enlarge(image, new_sizes.cast<int>().eval());
  }

  //! @} file
}


#endif /* DO_IMAGEPROCESSING_SCALING_HPP */
{'fraction_non_alphanumeric': 0.1781508173668483, 'fraction_numerical': 0.007119001582000351, 'mean_word_length': 3.0081014441704825, 'pattern_counts': {'":': 0, '<': 149, '<?xml version=': 0, '>': 150, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5376559', 'n_tokens_mistral': 4007, 'n_tokens_neox': 3820, 'n_words': 972}