void pingPong()

in source/depth_estimation/Derp.cpp [479:537]


void pingPong(PyramidLevel<PixelType>& pyramidLevel, const int iterations, const int numThreads) {
  for (int dstIdx = 0; dstIdx < int(pyramidLevel.rigDst.size()); ++dstIdx) {
    cv::Mat_<float>& disp = pyramidLevel.dstDisparity(dstIdx);
    cv::Mat_<float>& costs = pyramidLevel.dstCost(dstIdx);
    cv::Mat_<float> dispRes(disp.size());
    disp.copyTo(dispRes);
    cv::Mat_<float> costsRes(disp.size(), INFINITY);
    cv::Mat_<float> confidencesRes(disp.size(), 0);
    cv::Mat_<bool> changed(disp.size(), true);

    cv::Mat_<cv::Vec3b> labImage;
    if (kDoColorPruning) {
      const cv::Mat_<PixelType>& color = pyramidLevel.dstColor(dstIdx);
      cv::Mat_<cv::Vec4b> imageScaled;
      cv::Mat_<cv::Vec3b> bgrImage;
      color.convertTo(imageScaled, CV_8UC4, 255);
      cv::cvtColor(imageScaled, bgrImage, cv::COLOR_BGRA2BGR);
      cv::cvtColor(bgrImage, labImage, cv::COLOR_BGR2Lab);
    }

    for (int it = 1; it <= iterations; ++it) {
      LOG(INFO) << folly::sformat(
          "-- ping pong: iter {}/{}, {}", it, iterations, pyramidLevel.rigDst[dstIdx].id);
      const int radius = kSearchWindowRadius;
      ThreadPool threadPool(numThreads);

      const int edgeX = dispRes.cols;
      const int edgeY = 1;
      for (int y = radius; y < dispRes.rows - radius; y += edgeY) {
        for (int x = radius; x < dispRes.cols - radius; x += edgeX) {
          threadPool.spawn(
              &pingPongRectangle,
              std::ref(dispRes),
              std::ref(costsRes),
              std::ref(confidencesRes),
              std::cref(changed),
              std::cref(labImage),
              std::cref(pyramidLevel),
              dstIdx,
              x,
              y,
              std::min(x + edgeX, dispRes.cols - radius),
              std::min(y + edgeY, dispRes.rows - radius));
        }
      }
      threadPool.join();

      changed = disp != dispRes;
      dispRes.copyTo(disp);
      costsRes.copyTo(costs);

      const cv::Mat_<bool>& fovMask = pyramidLevel.dstFovMask(dstIdx);
      const int countFov = cv::countNonZero(fovMask);
      const int count = cv::countNonZero(changed);
      const float changedPct = 100.0f * count / countFov;
      LOG(INFO) << std::fixed << std::setprecision(2) << folly::sformat("changed: {}%", changedPct);
    }
  }
}