예제 #1
0
Matrix3f NNUtilities::calcInverseTransformation(const Vector2i& center, const Vector2i& inSize, const Vector2i& outSize, const Angle rotation)
{
  const Vector2i upperLeft = (center.array() - inSize.array() / 2).matrix();
  const Vector2f transformationFactor = (inSize.cast<float>().array() / outSize.cast<float>().array()).matrix();
  //float sin = std::sin(rotation);
  //float cos = std::cos(rotation);

  Matrix3f inverseTransformation; //TODO check rotation
  inverseTransformation(0, 0) = transformationFactor.x();// *cos;
  inverseTransformation(0, 1) = 0;// transformationFactor.x() * (-sin);
  inverseTransformation(1, 0) = 0;// transformationFactor.y() * sin;
  inverseTransformation(1, 1) = transformationFactor.y();// *cos;

  inverseTransformation(0, 2) = upperLeft.x();// +outSize.x() * (1 - cos + sin) / 2 * transformationFactor.x();
  inverseTransformation(1, 2) = upperLeft.y();// +outSize.y() * (1 - sin - cos) / 2 * transformationFactor.y();
  return inverseTransformation;
}
예제 #2
0
void NNUtilities::getImageSection(const Vector2i& center, const Vector2i& inSize, const Vector2i& outSize, const GrayscaledImage& src, OutType* output)
{
  const Vector2i upperLeft = (center.array() - inSize.array() / 2).matrix();
  const Vector2f stepSize = (inSize.cast<float>().array() / outSize.cast<float>().array()).matrix();

  // Calculate Y offset and steps
  int ySteps = outSize.y();
  float yImage = upperLeft.y();
  int yPatchOffset = 0;
  if(yImage < 0.f)
  {
    const float steps = ceilf(-yImage / stepSize.y());
    yImage += steps * stepSize.y();
    yPatchOffset = static_cast<int>(steps);
    ySteps -= std::min(ySteps, yPatchOffset);
  }
  const float yOvershoot = yImage + inSize.y() - src.height + (interpolate ? 1.f : 0.f);
  if(yOvershoot > 0)
    ySteps -= std::min(ySteps, static_cast<int>(ceilf(yOvershoot / stepSize.y())));

  // Calculate X offset and steps
  int xSteps = outSize.x();
  float xImageOffset = upperLeft.x();
  int xPatchOffset = 0;
  if(xImageOffset < 0.f)
  {
    const float steps = ceilf(-xImageOffset / stepSize.x());
    xImageOffset += steps * stepSize.x();
    xPatchOffset = static_cast<int>(steps);
    xSteps -= std::min(xSteps, xPatchOffset);
  }
  const float xOvershoot = xImageOffset + inSize.x() - src.width + (interpolate ? 1.f : 0.f);
  if(xOvershoot > 0)
    xSteps -= std::min(xSteps, static_cast<int>(ceilf(xOvershoot / stepSize.x())));

  // Fill output memory with background color if the patch is partly outside of the image
  if(ySteps < outSize.y() || xSteps < outSize.x())
  {
    static constexpr unsigned char fillColor = 128;
    std::fill_n(output, outSize.x() * outSize.y(), static_cast<OutType>(fillColor));
  }

  // Copy the patch
  OutType* dest = output + yPatchOffset * outSize.x(); //Check x or y 
  if(xSteps < outSize.x())
  {
    const size_t xPatchSkip = outSize.x() - xSteps - xPatchOffset;
    if(!interpolate)
    {
      for(; ySteps; yImage += stepSize.y(), --ySteps)
      {
        const PixelTypes::GrayscaledPixel* row = src[static_cast<size_t>(yImage)];

        dest += xPatchOffset;
        float xImage = xImageOffset;
        for(size_t n = xSteps; n; xImage += stepSize.x(), --n)
          * dest++ = static_cast<OutType>(row[static_cast<size_t>(xImage)]);
        dest += xPatchSkip;
      }
    }
    else
    {
      for(; ySteps; yImage += stepSize.y(), --ySteps)
      {
        const size_t yIndex = static_cast<size_t>(yImage);
        const float yWeight1 = yImage - static_cast<float>(yIndex);
        const float yWeight0 = 1 - yWeight1;
        const PixelTypes::GrayscaledPixel* row0 = src[yIndex];
        const PixelTypes::GrayscaledPixel* row1 = src[yIndex + 1];

        dest += xPatchOffset;
        float xImage = xImageOffset;
        for(size_t n = xSteps; n; xImage += stepSize.x(), --n)
        {
          const size_t xIndex = static_cast<size_t>(xImage);
          const float xWeight1 = xImage - static_cast<float>(xIndex);
          const float xWeight0 = 1 - xWeight1;

          *dest++ = static_cast<OutType>(
                      std::min(
                        255.f,
                        yWeight0 * (static_cast<float>(row0[xIndex]) * xWeight0 + static_cast<float>(row0[xIndex + 1]) * xWeight1)
                        + yWeight1 * (static_cast<float>(row1[xIndex]) * xWeight0 + static_cast<float>(row1[xIndex + 1]) * xWeight1)
                      )
                    );
        }
        dest += xPatchSkip;
      }
    }
  }
  else
  {
    if(!interpolate)
    {
      for(; ySteps; yImage += stepSize.y(), --ySteps)
      {
        const PixelTypes::GrayscaledPixel* row = src[static_cast<size_t>(yImage)];

        float xImage = xImageOffset;
        for(size_t n = xSteps; n; xImage += stepSize.x(), --n)
          * dest++ = static_cast<OutType>(row[static_cast<size_t>(xImage)]);
      }
    }
    else
    {
      for(; ySteps; yImage += stepSize.y(), --ySteps)
      {
        const size_t yIndex = static_cast<size_t>(yImage);
        const float yWeight1 = yImage - static_cast<float>(yIndex);
        const float yWeight0 = 1 - yWeight1;
        const PixelTypes::GrayscaledPixel* row0 = src[yIndex];
        const PixelTypes::GrayscaledPixel* row1 = src[yIndex + 1];

        float xImage = xImageOffset;
        for(size_t n = xSteps; n; xImage += stepSize.x(), --n)
        {
          const size_t xIndex = static_cast<size_t>(xImage);
          const float xWeight1 = xImage - static_cast<float>(xIndex);
          const float xWeight0 = 1 - xWeight1;

          *dest++ = static_cast<OutType>(
                      std::min(
                        255.f,
                        yWeight0 * (static_cast<float>(row0[xIndex]) * xWeight0 + static_cast<float>(row0[xIndex + 1]) * xWeight1)
                        + yWeight1 * (static_cast<float>(row1[xIndex]) * xWeight0 + static_cast<float>(row1[xIndex + 1]) * xWeight1)
                      )
                    );
        }
      }
    }
  }

  RECTANGLE("module:NNBallPerceptor:spots", upperLeft.x(), upperLeft.y(), static_cast<int>(upperLeft.x() + inSize.x()), static_cast<int>(upperLeft.y() + inSize.y()), 2, Drawings::PenStyle::solidPen, ColorRGBA::black);
}