#include
#include
#include "input_data.hpp"
#include "cv_utils.hpp"
namespace fs = std::filesystem;
using namespace torch::indexing;
using json = nlohmann::json;
namespace ns{ InputData inputDataFromNerfStudio(const std::string &projectRoot); }
namespace cm{ InputData inputDataFromColmap(const std::string &projectRoot); }
namespace osfm { InputData inputDataFromOpenSfM(const std::string &projectRoot); }
InputData inputDataFromX(const std::string &projectRoot){
fs::path root(projectRoot);
if (fs::exists(root / "transforms.json")){
return ns::inputDataFromNerfStudio(projectRoot);
}else if (fs::exists(root / "sparse") || fs::exists(root / "cameras.bin")){
return cm::inputDataFromColmap(projectRoot);
}else if (fs::exists(root / "reconstruction.json")){
return osfm::inputDataFromOpenSfM(projectRoot);
}else if (fs::exists(root / "opensfm" / "reconstruction.json")){
return osfm::inputDataFromOpenSfM((root / "opensfm").string());
}else{
throw std::runtime_error("Invalid project folder (must be either a colmap or nerfstudio project folder)");
}
}
torch::Tensor Camera::getIntrinsicsMatrix(){
return torch::tensor({{fx, 0.0f, cx},
{0.0f, fy, cy},
{0.0f, 0.0f, 1.0f}}, torch::kFloat32);
}
torch::Tensor Camera::undistortTensor(cv::Mat &cImg, torch::Tensor &_K, bool shouldUpdateK, const torch::Dtype dataType){
cv::Rect roi;
torch::Tensor t;
if (hasDistortionParameters()){
// Undistort
std::vector distCoeffs = undistortionParameters();
cv::Mat cK = floatNxNtensorToMat(_K);
cv::Mat newK = cv::getOptimalNewCameraMatrix(cK, distCoeffs, cv::Size(cImg.cols, cImg.rows), 0, cv::Size(), &roi);
cv::Mat undistorted = cv::Mat::zeros(cImg.rows, cImg.cols, cImg.type());
cv::undistort(cImg, undistorted, cK, distCoeffs, newK);
t = imageToTensor(undistorted, dataType);
if (shouldUpdateK){
K = floatNxNMatToTensor(newK);
}
}else{
roi = cv::Rect(0, 0, cImg.cols, cImg.rows);
t = imageToTensor(cImg, dataType);
}
// Crop to ROI
t = t.index({Slice(roi.y, roi.y + roi.height), Slice(roi.x, roi.x + roi.width), Slice()});
return t;
}
void Camera::loadImage(float downscaleFactor){
// Populates image and K, then updates the camera parameters
// Caution: this function has destructive behaviors
// and should be called only once
if (image.numel()) std::runtime_error("loadImage already called");
std::cout