// Copyright (c) 2012-2017 VideoStitch SAS // Copyright (c) 2018 stitchEm #include "panoInputDefsPimpl.hpp" #include "parse/json.hpp" #include "core/transformGeoParams.hpp" #include "libvideostitch/logging.hpp" namespace VideoStitch { namespace Core { namespace { bool operator!=(NormalDouble const& a, NormalDouble const& b) { return (a.mean == b.mean) && (a.variance == b.variance); } } // namespace const double CameraDefinition::max_fu_variance = 1e12; const double CameraDefinition::max_fv_variance = 1e12; const double CameraDefinition::max_cu_variance = 1e8; const double CameraDefinition::max_cv_variance = 1e8; const double CameraDefinition::max_distorta_variance = 1e4; const double CameraDefinition::max_distortb_variance = 1e4; const double CameraDefinition::max_distortc_variance = 1e4; CameraDefinition::Pimpl::Pimpl() : name("") { width = 1; height = 1; fu.mean = 0.0; fu.variance = CameraDefinition::max_fu_variance; fv.mean = 0.0; fv.variance = CameraDefinition::max_fv_variance; cu.mean = 0.0; cu.variance = CameraDefinition::max_cu_variance; cv.mean = 0.0; cv.variance = CameraDefinition::max_cv_variance; distortion[0].mean = 0.0; distortion[0].variance = CameraDefinition::max_distorta_variance; distortion[1].mean = 0.0; distortion[1].variance = CameraDefinition::max_distortb_variance; distortion[2].mean = 0.0; distortion[2].variance = CameraDefinition::max_distortc_variance; format = InputDefinition::Format::FullFrameFisheye_Opt; } CameraDefinition::CameraDefinition() : pimpl(new Pimpl()) {} CameraDefinition* CameraDefinition::clone() const { CameraDefinition* result = new CameraDefinition(); result->setName(getName()); result->setType(getType()); result->setWidth(getWidth()); result->setHeight(getHeight()); result->setFu(getFu()); result->setFv(getFv()); result->setCu(getCu()); result->setCv(getCv()); result->setDistortionA(getDistortionA()); result->setDistortionB(getDistortionB()); result->setDistortionC(getDistortionC()); return result; } bool CameraDefinition::operator==(const CameraDefinition& other) const { if (getWidth() != other.getWidth()) return false; if (getHeight() != other.getHeight()) return false; if (getFu() != other.getFu()) return false; if (getFv() != other.getFv()) return false; if (getCu() != other.getCu()) return false; if (getCv() != other.getCv()) return false; if (getDistortionA() != other.getDistortionA()) return false; if (getDistortionB() != other.getDistortionB()) return false; if (getDistortionC() != other.getDistortionC()) return false; if (getName() != other.getName()) return false; if (getType() != other.getType()) return false; return true; } bool CameraDefinition::validate(std::ostream& os) const { if (getName() == "") { os << "Invalid name" << std::endl; return false; } if (getFu().mean < 0.0) { os << "Invalid horizontal focal" << std::endl; return false; } if (getFv().mean < 0.0) { os << "Invalid vertical focal" << std::endl; return false; } if (getFu().variance < 0.0) { os << "Invalid variance value" << std::endl; } if (getFv().variance < 0.0) { os << "Invalid variance value" << std::endl; } if (getCu().variance < 0.0) { os << "Invalid variance value" << std::endl; } if (getCv().variance < 0.0) { os << "Invalid variance value" << std::endl; } if (getDistortionA().variance < 0.0) { os << "Invalid variance value" << std::endl; } if (getDistortionB().variance < 0.0) { os << "Invalid variance value" << std::endl; } if (getDistortionC().variance < 0.0) { os << "Invalid variance value" << std::endl; } return true; } CameraDefinition::~CameraDefinition() { delete pimpl; } CameraDefinition::Pimpl::~Pimpl() {} CameraDefinition* CameraDefinition::createDefault(const std::string& name) { std::unique_ptr<CameraDefinition> res(new CameraDefinition()); res->pimpl->name = name; return res.release(); } CameraDefinition* CameraDefinition::create(const Ptv::Value& value) { #define PROPAGATE_NOK(call) \ if (call != Parse::PopulateResult_Ok) { \ return nullptr; \ } if (!Parse::checkType("Camera", value, Ptv::Value::OBJECT)) { return nullptr; } std::unique_ptr<CameraDefinition> res(new CameraDefinition()); std::string stype; PROPAGATE_NOK(Parse::populateString("CameraDefinition", value, "name", res->pimpl->name, true)); PROPAGATE_NOK(Parse::populateString("CameraDefinition", value, "format", stype, true)); if (!InputDefinition::getFormatFromName(stype, res->pimpl->format)) { return nullptr; } PROPAGATE_NOK(Parse::populateInt("CameraDefinition", value, "width", res->pimpl->width, true)); PROPAGATE_NOK(Parse::populateInt("CameraDefinition", value, "height", res->pimpl->height, true)); PROPAGATE_NOK(Parse::populateDouble("CameraDefinition", value, "fu_mean", res->pimpl->fu.mean, true)); PROPAGATE_NOK(Parse::populateDouble("CameraDefinition", value, "fv_mean", res->pimpl->fv.mean, true)); PROPAGATE_NOK(Parse::populateDouble("CameraDefinition", value, "cu_mean", res->pimpl->cu.mean, true)); PROPAGATE_NOK(Parse::populateDouble("CameraDefinition", value, "cv_mean", res->pimpl->cv.mean, true)); PROPAGATE_NOK( Parse::populateDouble("CameraDefinition", value, "distorta_mean", res->pimpl->distortion[0].mean, true)); PROPAGATE_NOK( Parse::populateDouble("CameraDefinition", value, "distortb_mean", res->pimpl->distortion[1].mean, true)); PROPAGATE_NOK( Parse::populateDouble("CameraDefinition", value, "distortc_mean", res->pimpl->distortion[2].mean, true)); PROPAGATE_NOK(Parse::populateDouble("CameraDefinition", value, "fu_variance", res->pimpl->fu.variance, true)); PROPAGATE_NOK(Parse::populateDouble("CameraDefinition", value, "fv_variance", res->pimpl->fv.variance, true)); PROPAGATE_NOK(Parse::populateDouble("CameraDefinition", value, "cu_variance", res->pimpl->cu.variance, true)); PROPAGATE_NOK(Parse::populateDouble("CameraDefinition", value, "cv_variance", res->pimpl->cv.variance, true)); PROPAGATE_NOK( Parse::populateDouble("CameraDefinition", value, "distorta_variance", res->pimpl->distortion[0].variance, true)); PROPAGATE_NOK( Parse::populateDouble("CameraDefinition", value, "distortb_variance", res->pimpl->distortion[1].variance, true)); PROPAGATE_NOK( Parse::populateDouble("CameraDefinition", value, "distortc_variance", res->pimpl->distortion[2].variance, true)); if (res->pimpl->fu.variance > CameraDefinition::max_fu_variance) res->pimpl->fu.variance = CameraDefinition::max_fu_variance; if (res->pimpl->fv.variance > CameraDefinition::max_fv_variance) res->pimpl->fv.variance = CameraDefinition::max_fv_variance; if (res->pimpl->cu.variance > CameraDefinition::max_cu_variance) res->pimpl->cu.variance = CameraDefinition::max_cu_variance; if (res->pimpl->cv.variance > CameraDefinition::max_cv_variance) res->pimpl->cv.variance = CameraDefinition::max_cv_variance; if (res->pimpl->distortion[0].variance > CameraDefinition::max_distorta_variance) res->pimpl->distortion[0].variance = CameraDefinition::max_distorta_variance; if (res->pimpl->distortion[1].variance > CameraDefinition::max_distortb_variance) res->pimpl->distortion[1].variance = CameraDefinition::max_distortb_variance; if (res->pimpl->distortion[2].variance > CameraDefinition::max_distortc_variance) res->pimpl->distortion[2].variance = CameraDefinition::max_distortc_variance; #undef PROPAGATE_NOK return res.release(); } Ptv::Value* CameraDefinition::serialize() const { Ptv::Value* res = Ptv::Value::emptyObject(); std::string typestr = InputDefinition::getFormatName(getType()); res->push("name", new Parse::JsonValue(getName())); res->push("format", new Parse::JsonValue(typestr)); res->push("width", new Parse::JsonValue((int)getWidth())); res->push("height", new Parse::JsonValue((int)getHeight())); res->push("fu_mean", new Parse::JsonValue(getFu().mean)); res->push("fu_variance", new Parse::JsonValue(getFu().variance)); res->push("fv_mean", new Parse::JsonValue(getFv().mean)); res->push("fv_variance", new Parse::JsonValue(getFv().variance)); res->push("cu_mean", new Parse::JsonValue(getCu().mean)); res->push("cu_variance", new Parse::JsonValue(getCu().variance)); res->push("cv_mean", new Parse::JsonValue(getCv().mean)); res->push("cv_variance", new Parse::JsonValue(getCv().variance)); res->push("distorta_mean", new Parse::JsonValue(getDistortionA().mean)); res->push("distorta_variance", new Parse::JsonValue(getDistortionA().variance)); res->push("distortb_mean", new Parse::JsonValue(getDistortionB().mean)); res->push("distortb_variance", new Parse::JsonValue(getDistortionB().variance)); res->push("distortc_mean", new Parse::JsonValue(getDistortionC().mean)); res->push("distortc_variance", new Parse::JsonValue(getDistortionC().variance)); return res; } /************ Getters and Setters **********/ std::string CameraDefinition::getName() const { return pimpl->name; } void CameraDefinition::setName(const std::string& val) { pimpl->name = val; } InputDefinition::Format CameraDefinition::getType() const { return pimpl->format; } void CameraDefinition::setType(const InputDefinition::Format& val) { pimpl->format = val; } NormalDouble CameraDefinition::getFu() const { return pimpl->fu; } void CameraDefinition::setFu(const NormalDouble& val) { pimpl->fu = val; } size_t CameraDefinition::getWidth() const { return pimpl->width; } void CameraDefinition::setWidth(size_t val) { pimpl->width = val; } size_t CameraDefinition::getHeight() const { return pimpl->height; } void CameraDefinition::setHeight(size_t val) { pimpl->height = val; } void CameraDefinition::setFov(const NormalDouble& fov) { pimpl->fu.mean = TransformGeoParams::computeInputScale(pimpl->format, pimpl->width, (float)fov.mean); pimpl->fu.variance = fov.variance; pimpl->fv.mean = pimpl->fu.mean; pimpl->fv.variance = pimpl->fu.variance; } NormalDouble CameraDefinition::getFv() const { return pimpl->fv; } void CameraDefinition::setFv(const NormalDouble& val) { pimpl->fv = val; } NormalDouble CameraDefinition::getCu() const { return pimpl->cu; } void CameraDefinition::setCu(const NormalDouble& val) { pimpl->cu = val; } NormalDouble CameraDefinition::getCv() const { return pimpl->cv; } void CameraDefinition::setCv(const NormalDouble& val) { pimpl->cv = val; } NormalDouble CameraDefinition::getDistortionA() const { return pimpl->distortion[0]; } void CameraDefinition::setDistortionA(const NormalDouble& val) { pimpl->distortion[0] = val; } NormalDouble CameraDefinition::getDistortionB() const { return pimpl->distortion[1]; } void CameraDefinition::setDistortionB(const NormalDouble& val) { pimpl->distortion[1] = val; } NormalDouble CameraDefinition::getDistortionC() const { return pimpl->distortion[2]; } void CameraDefinition::setDistortionC(const NormalDouble& val) { pimpl->distortion[2] = val; } } // namespace Core } // namespace VideoStitch