bool VideoFrameTransform::generateMapForPlane()

in Transform360/Library/VideoFrameTransform.cpp [534:607]


bool VideoFrameTransform::generateMapForPlane(
  int inputWidth,
  int inputHeight,
  int outputWidth,
  int outputHeight,
  int transformMatPlaneIndex) {
  try {
    assert(
      inputWidth > 0 && inputHeight > 0 &&
      outputWidth > 0 && outputHeight > 0 &&
      ctx_.width_scale_factor > 0 &&
      ctx_.height_scale_factor > 0 &&
      ctx_.kernel_height_scale_factor > 0 &&
      ctx_.num_vertical_segments >= 2 &&
      ctx_.num_vertical_segments <= inputHeight &&
      ctx_.num_horizontal_segments >= 1 &&
      ctx_.num_horizontal_segments <= inputWidth &&
      ctx_.min_kernel_half_height >= 0.5 &&
      ctx_.max_kernel_half_height >= 0.5);

    // Both scaling and low pass filtering processes are for antialiasing
    // purpose
    int scaledOutputWidth =
      (int) (ctx_.width_scale_factor * outputWidth + 0.5);
    int scaledOutputHeight =
      (int) (ctx_.height_scale_factor * outputHeight + 0.5);

    float inputPixelWidth = 1.0f / inputWidth;
    if (ctx_.input_stereo_format == STEREO_FORMAT_LR) {
      inputPixelWidth *= 2;
    }

    Mat warpMat = Mat(scaledOutputHeight, scaledOutputWidth, CV_32FC2);
    for (int i = 0; i < scaledOutputHeight; ++i) {
      for (int j = 0; j < scaledOutputWidth; ++j) {
        float outX, outY;
        float y = (i + 0.5f) / scaledOutputHeight;
        float x = (j + 0.5f) / scaledOutputWidth;
        if (transformPos(
            x, y, &outX, &outY, transformMatPlaneIndex, inputPixelWidth)) {
          // OpenCV uses coordinates system. Where (0, 0) is the center of
          // top-left pixel instead of a corner. In this case we have to
          // shift output (x, y) by (-0.5f, -0.5f) to account for this.
          warpMat.at<Point2f>(i, j) =
            Point2f(outX * inputWidth - 0.5f, outY * inputHeight - 0.5f);
        } else {
          printf(
            "Failed to find the mapping coordinate for point (%d, %d)\n",
            i, j);
          return false;
        }
      }
    }

    warpMats_[transformMatPlaneIndex] = warpMat;

    if (ctx_.enable_low_pass_filter) {
      // Calculate variable kernels for segments of the frame plane
      calcualteFilteringConfig(
        inputWidth,
        inputHeight,
        scaledOutputWidth,
        scaledOutputHeight,
        transformMatPlaneIndex);
    }

    return true;
  } catch (const exception& ex) {
    printf("Could not generate map for plane %d. Error: %s\n",
      transformMatPlaneIndex,
      ex.what());
    return false;
  }
}