28 : vertFocal_pix(1.0f),
47 float focal_mm =
static_cast<float>(
49 float pixelSize_mm =
static_cast<float>(
54 params.
skew =
static_cast<float>(0.0);
55 params.
vFOV_rad =
static_cast<float>(
57 params.
zNear_mm =
static_cast<float>(
59 params.
zFar_mm =
static_cast<float>(
68 principalPointOffset[0] = 0;
69 principalPointOffset[1] = 0;
70 linearDisparityParams[0] = 0;
71 linearDisparityParams[1] = 0;
98 drawSidePlanes(false),
99 frustumCorners(nullptr),
100 frustumHull(nullptr) {}
106 frustumHull =
nullptr;
108 if (frustumCorners) {
109 delete frustumCorners;
110 frustumCorners =
nullptr;
115 if (!frustumCorners) {
118 frustumCorners->clear();
121 if (!frustumCorners->reserve(8)) {
123 delete frustumCorners;
124 frustumCorners =
nullptr;
132 if (frustumHull)
return true;
134 if (!frustumCorners || frustumCorners->size() < 8) {
136 "[ccCameraSensor::FrustumInformation::initFrustumHull] Corners "
137 "are not initialized!");
141 frustumHull =
new ccMesh(frustumCorners);
142 if (!frustumHull->reserve(6 * 2)) {
144 "[ccCameraSensor::FrustumInformation::initFrustumHull] Not "
147 frustumHull =
nullptr;
151 frustumHull->addTriangle(0, 2, 3);
152 frustumHull->addTriangle(0, 3, 1);
154 frustumHull->addTriangle(2, 4, 5);
155 frustumHull->addTriangle(2, 5, 3);
157 frustumHull->addTriangle(4, 6, 7);
158 frustumHull->addTriangle(4, 7, 5);
160 frustumHull->addTriangle(6, 0, 1);
161 frustumHull->addTriangle(6, 1, 7);
163 frustumHull->addTriangle(6, 4, 2);
164 frustumHull->addTriangle(6, 2, 0);
166 frustumHull->addTriangle(1, 3, 5);
167 frustumHull->addTriangle(1, 5, 7);
169 frustumHull->setVisible(
true);
186 m_projectionMatrixIsValid(false) {
198 m_projectionMatrix(sensor.m_projectionMatrix),
199 m_projectionMatrixIsValid(false) {
246 if (!withGLFeatures) {
266 CCVector3(upperLeftPoint.
x, upperLeftPoint.
y, -upperLeftPoint.
z));
268 CCVector3(-upperLeftPoint.
x, upperLeftPoint.
y, -upperLeftPoint.
z));
270 CCVector3(-upperLeftPoint.
x, -upperLeftPoint.
y, -upperLeftPoint.
z));
272 CCVector3(upperLeftPoint.
x, -upperLeftPoint.
y, -upperLeftPoint.
z));
280 for (
unsigned i = 0; i < cornerCount; ++i)
299 if (upperLeftPoint.
z > 0) {
300 return ccBBox(-upperLeftPoint,
309 assert(vertFocal_pix > 0);
334 "[ccCameraSensor::applyViewport] No associated display!");
344 CVLog::Warning(
"[ccCameraSensor::applyViewport] Sensor height is 0!");
362 if (upperLeftPointd.
z > 0) {
373 "[ccCameraSensor::applyViewport] Viewing dir is parallel to "
422 assert(out.isOpen() && (out.openMode() & QIODevice::WriteOnly));
423 if (dataVersion < 38) {
437 QDataStream outStream(&out);
454 outStream << static_cast<uint32_t>(distModel);
462 outStream << params->
k1;
463 outStream << params->
k2;
470 outStream << params->
k1;
471 outStream << params->
k2;
472 outStream << params->
k3;
507 return std::max(
static_cast<short>(43),
519 if (dataVersion < 35)
return false;
522 if (dataVersion < 38) {
525 if (!dummyMatrix.
fromFile(in, dataVersion, flags, oldToNewIDMap))
533 QDataStream inStream(&in);
544 if (dataVersion >= 43) {
557 if (dataVersion < 38) {
562 inStream >> distModeli;
571 inStream >> distParams->
k1;
572 inStream >> distParams->
k2;
581 inStream >> distParams->
k1;
582 inStream >> distParams->
k2;
583 inStream >> distParams->
k3;
612 if (dataVersion < 38) {
615 inStream >> dummyBool;
623 if (dataVersion < 38) {
625 for (
unsigned i = 0; i < 8; ++i) {
641 globalCoord = localCoord;
642 trans.
apply(globalCoord);
653 localCoord = globalCoord;
662 bool withLensError )
const {
663 #ifdef CHECK_THIS_AFTERWARDS
666 CCVector3 imageCoordSystem(localCoord.
x, localCoord.
y, -localCoord.
z);
670 if (imageCoordSystem.
z < FLT_EPSILON)
return false;
678 projCoord = projCoord / projCoord.
z;
699 double depth = -
static_cast<double>(
701 #define BACK_POINTS_CULLING
702 #ifdef BACK_POINTS_CULLING
703 if (depth < FLT_EPSILON)
return false;
707 CCVector2d p(localCoord.
x / depth, localCoord.
y / depth);
718 double norm2 = p.
norm2();
720 norm2 * (params->
k1 +
729 double norm2 = p.
norm2();
732 norm2 * (params->
k1 +
733 norm2 * (params->
k2 +
734 norm2 * params->
k3));
760 bool withLensCorrection )
const {
783 bool withLensError )
const {
794 bool withLensCorrection )
const {
819 #ifdef BACK_POINTS_CULLING
820 if (u < 0)
return false;
823 globalCoord = camC + u * viewDir;
856 float dx = (
static_cast<float>(real.
x) - cx) *
858 float dy = (
static_cast<float>(real.
y) - cy) *
862 float r = sqrt(dx2 + dy2);
873 float correctedX = (dx * (1 + K1 * r2 + K2 * r4 + K3 * r6) +
874 P1 * (r2 + 2 * dx2) + 2 * P2 * dx * dy);
875 float correctedY = (dy * (1 + K1 * r2 + K2 * r4 + K3 * r6) +
876 P2 * (r2 + 2 * dy2) + 2 * P1 * dx * dy);
925 if (pixel.
x < 0 || pixel.
x >
width || pixel.
y < 0 ||
926 pixel.
y >
height || depth < FLT_EPSILON)
931 float z2 = depth * depth;
932 float invSigmaD = 8.0f;
933 float factor = A * z2 / invSigmaD;
940 sigma.
x =
static_cast<ScalarType
>(
941 std::abs(factor * (pixel.
x - c[0]) / horizFocal_pix));
942 sigma.
y =
static_cast<ScalarType
>(
943 std::abs(factor * (pixel.
y - c[1]) / verFocal_pix));
944 sigma.
z =
static_cast<ScalarType
>(std::abs(factor * mu));
964 "[ccCameraSensor::computeUncertainty] Internal error: invalid "
972 "[ccCameraSensor::computeUncertainty] Sensor has no associated "
973 "uncertainty model! (Brown, etc.)");
980 accuracy.resize(
count);
981 }
catch (
const std::bad_alloc&) {
983 "[ccCameraSensor::computeUncertainty] Not enough memory!");
987 for (
unsigned i = 0; i <
count; i++) {
996 accuracy[i].x = accuracy[i].y = accuracy[i].z =
NAN_VALUE;
1006 if (
image.isNull()) {
1007 CVLog::Warning(
"[ccCameraSensor::undistort] Invalid input image!");
1014 CVLog::Warning(
"[ccCameraSensor::undistort] No distortion model set!");
1024 float k1 = params->
k1;
1025 float k2 = params->
k2;
1026 if (k1 == 0 && k2 == 0) {
1028 "[ccCameraSensor::undistort] Invalid radial distortion "
1042 float xScale =
image.width() /
1044 float yScale =
image.height() /
1046 float rScale = sqrt(xScale * xScale + yScale * yScale);
1050 if (newImage.isNull()) {
1052 "[ccCameraSensor::undistort] Not enough memory!");
1059 float vf2 = vertFocal_pix * vertFocal_pix;
1060 float hf2 = horizFocal_pix * horizFocal_pix;
1067 assert((
image.depth() % 8) == 0);
1068 int depth =
image.depth() / 8;
1069 int bytesPerLine =
image.bytesPerLine();
1071 uchar* oImageBits = newImage.bits();
1075 for (
int i = 0; i <
width; ++i) {
1078 for (
int j = 0; j <
height; ++j) {
1082 float p2 = x2 / hf2 + y2 / vf2;
1086 p2 * (k2 + p2 * k3));
1090 float eqx = rp *
x + cx;
1091 float eqy = rp *
y + cy;
1093 int pixx =
static_cast<int>(eqx);
1094 int pixy =
static_cast<int>(eqy);
1095 if (pixx >= 0 && pixx < width && pixy >= 0 &&
1097 const uchar* iPixel =
1098 iImageBits + j * bytesPerLine + i * depth;
1099 uchar* oPixel = oImageBits + pixy * bytesPerLine +
1101 memcpy(oPixel, iPixel, depth);
1122 "[ccCameraSensor::undistort] Can't undistort the image with the "
1123 "current distortion model!");
1129 bool inplace )
const {
1132 "[ccCameraSensor::undistort] Invalid/empty input image!");
1137 if (newImage.isNull()) {
1144 image->setData(newImage);
1147 return new ccImage(newImage,
image->getName() + QString(
".undistort"));
1161 const float&
z = localCoord.
z;
1165 return (-z <= f && -z > n && std::abs(f +
z) >= FLT_EPSILON &&
1166 std::abs(n +
z) >= FLT_EPSILON);
1182 upperLeftPoint.y = upperLeftPoint.z * tanf(halfFov);
1183 upperLeftPoint.x = upperLeftPoint.z * tanf(halfFov * ar);
1185 return upperLeftPoint;
1191 "[ccCameraSensor::computeFrustumCorners] Sensor height is 0!");
1199 float xIn = std::abs(tan(halfFov * ar));
1200 float yIn = std::abs(tan(halfFov));
1208 "[ccCameraSensor::computeFrustumCorners] Not enough memory!");
1237 float dz = P0->
z - P5->
z;
1238 float z = (std::abs(dz) < FLT_EPSILON
1251 float planeCoefficients[6][4],
1340 for (
int i = 0; i < 4; i++) {
1341 CCVector3 v1 = frustumCorners[i * 2 + 1] - frustumCorners[i * 2];
1343 frustumCorners[((i + 1) * 2) % 8] - frustumCorners[i * 2];
1346 planeCoefficients[i][0] = n.
x;
1347 planeCoefficients[i][1] = n.
y;
1348 planeCoefficients[i][2] = n.
z;
1349 planeCoefficients[i][3] = -frustumCorners[i * 2].dot(n);
1353 CCVector3 v1 = frustumCorners[0] - frustumCorners[6];
1354 CCVector3 v2 = frustumCorners[4] - frustumCorners[6];
1357 planeCoefficients[4][0] = n.
x;
1358 planeCoefficients[4][1] = n.
y;
1359 planeCoefficients[4][2] = n.
z;
1360 planeCoefficients[4][3] = -frustumCorners[6].dot(n);
1361 planeCoefficients[5][0] = -n.
x;
1362 planeCoefficients[5][1] = -n.
y;
1363 planeCoefficients[5][2] = -n.
z;
1364 planeCoefficients[5][3] = -frustumCorners[7].dot(-n);
1369 edges[0] = frustumCorners[1] - frustumCorners[0];
1370 edges[1] = frustumCorners[3] - frustumCorners[2];
1371 edges[2] = frustumCorners[5] - frustumCorners[4];
1372 edges[3] = frustumCorners[7] - frustumCorners[6];
1373 edges[4] = frustumCorners[6] - frustumCorners[0];
1374 edges[5] = frustumCorners[2] - frustumCorners[0];
1375 for (
unsigned i = 0; i < 6; i++) {
1393 upperLeftPointd.
x, upperLeftPointd.
y, -upperLeftPointd.
z));
1395 -upperLeftPointd.
x, upperLeftPointd.
y, -upperLeftPointd.
z));
1397 -upperLeftPointd.
x, -upperLeftPointd.
y, -upperLeftPointd.
z));
1399 upperLeftPointd.
x, -upperLeftPointd.
y, -upperLeftPointd.
z));
1409 upperLeftPointd.
x, upperLeftPointd.
y, -upperLeftPointd.
z));
1411 -upperLeftPointd.
x, upperLeftPointd.
y, -upperLeftPointd.
z));
1413 -upperLeftPointd.
x, -upperLeftPointd.
y, -upperLeftPointd.
z));
1415 upperLeftPointd.
x, -upperLeftPointd.
y, -upperLeftPointd.
z));
1422 const double arrowHeight = 3 * upperLeftPointd.
y / 2;
1423 const double baseHeight = 6 * upperLeftPointd.
y / 5;
1424 const double arrowHalfWidth = 2 * upperLeftPointd.
x / 5;
1425 const double baseHalfWidth = 1 * upperLeftPointd.
x / 5;
1430 Eigen::Vector3d(-baseHalfWidth, baseHeight, -upperLeftPointd.
z));
1432 Eigen::Vector3d(baseHalfWidth, baseHeight, -upperLeftPointd.
z));
1433 m_arrow.
points_.push_back(Eigen::Vector3d(baseHalfWidth, upperLeftPointd.
y,
1434 -upperLeftPointd.
z));
1435 m_arrow.
points_.push_back(Eigen::Vector3d(-baseHalfWidth, upperLeftPointd.
y,
1436 -upperLeftPointd.
z));
1442 Eigen::Vector3d(-arrowHalfWidth, baseHeight, -upperLeftPointd.
z));
1444 Eigen::Vector3d(arrowHalfWidth, baseHeight, -upperLeftPointd.
z));
1446 Eigen::Vector3d(0, arrowHeight, -upperLeftPointd.
z));
1453 double l = std::abs(upperLeftPointd.
z) / 2.0;
1647 float ccdPixelSize_mm) {
1648 if (ccdPixelSize_mm < FLT_EPSILON) {
1650 "[ccCameraSensor::convertFocalPixToMM] Invalid CCD pixel size! "
1655 return focal_pix * ccdPixelSize_mm;
1659 float ccdPixelSize_mm) {
1660 if (ccdPixelSize_mm < FLT_EPSILON) {
1662 "[ccCameraSensor::convertFocalMMToPix] Invalid CCD pixel size! "
1667 return focal_mm / ccdPixelSize_mm;
1671 int imageSize_pix) {
1672 if (imageSize_pix <= 0) {
1677 return 2 * atanf(imageSize_pix / (2 * focal_pix));
1682 if (ccdSize_mm < FLT_EPSILON) {
1687 return 2 * atanf(ccdSize_mm / (2 * focal_mm));
1693 std::vector<KeyPoint>& keypointsImage,
1696 double c_out[3])
const {
1697 if (!
image || !keypoints3D)
return false;
1699 unsigned count =
static_cast<unsigned>(keypointsImage.size());
1700 if (
count < 4)
return false;
1703 double norm =
static_cast<double>(std::max(
image->getW(),
image->getH()));
1704 double X0[8] = {1.0 / sqrt(norm), 1.0 / norm, 1.0 / norm, 1.0 / sqrt(norm),
1705 1.0 / norm, 1.0 / norm, 1.0 / norm, 1.0 / norm};
1708 unsigned Neq = 2 *
count;
1709 double* A =
new double[8 * Neq];
1710 double* b =
new double[Neq];
1722 for (
unsigned i = 0; i <
count; ++i) {
1723 const KeyPoint& kp = keypointsImage[i];
1724 double kpx =
static_cast<double>(kp.
x);
1725 double kpy =
static_cast<double>(kp.
y);
1734 *_A++ = -kpx *
static_cast<double>(P->
x);
1735 *_A++ = -kpy *
static_cast<double>(P->
x);
1736 *_b++ =
static_cast<double>(P->
x);
1744 *_A++ = -kpx *
static_cast<double>(P->
y);
1745 *_A++ = -kpy *
static_cast<double>(P->
y);
1746 *_b++ =
static_cast<double>(P->
y);
1754 double* tAb = cg.
b();
1758 for (
unsigned i = 0; i < 8; ++i) {
1760 for (
unsigned j = i; j < 8; ++j) {
1761 double sum_prod = 0;
1762 const double* _Ai = A + i;
1763 const double* _Aj = A + j;
1764 for (
unsigned k = 0; k < Neq; ++k) {
1766 sum_prod += (*_Ai) * (*_Aj);
1775 double sum_prod = 0;
1776 const double* _Ai = A + i;
1777 const double* _b = b;
1778 for (
unsigned k = 0; k < Neq; ++k) {
1780 sum_prod += (*_Ai) * (*_b++);
1793 double convergenceThreshold =
1795 for (
unsigned i = 0; i < 1500; ++i) {
1797 if (lastError < convergenceThreshold)
1800 QString(
"[computeOrthoRectificationParams] Convergence "
1801 "reached in %1 iteration(s) (error: %2)")
1831 bool undistortImages ,
1834 double* realCorners )
const {
1850 assert((xTopLeft - check).norm2() <
1866 assert((xTopRight - check).norm2() <
1883 assert((xBottomRight - check).norm2() <
1899 assert((xBottomLeft - check).norm2() <
1906 if (realCorners) memcpy(realCorners, corners, 8 *
sizeof(
double));
1909 double minC[2] = {corners[0], corners[1]};
1910 double maxC[2] = {corners[0], corners[1]};
1912 for (
unsigned k = 1; k < 4; ++k) {
1913 const double* C = corners + 2 * k;
1916 else if (maxC[0] < C[0])
1921 else if (maxC[1] < C[1])
1927 minCorner[0] = minC[0];
1928 minCorner[1] = minC[1];
1931 maxCorner[0] = maxC[0];
1932 maxCorner[1] = maxC[1];
1935 double dx = maxC[0] - minC[0];
1936 double dy = maxC[1] - minC[1];
1938 double _pixelSize = pixelSize;
1939 if (_pixelSize <= 0) {
1941 _pixelSize = std::max(dx, dy) / maxSize;
1943 unsigned w =
static_cast<unsigned>(dx / _pixelSize);
1944 unsigned h =
static_cast<unsigned>(dy / _pixelSize);
1946 QImage orthoImage(w, h, QImage::Format_ARGB32);
1947 if (orthoImage.isNull())
1950 const QRgb blackValue = qRgb(0, 0, 0);
1951 const QRgb blackAlphaZero = qRgba(0, 0, 0, 0);
1953 for (
unsigned i = 0; i < w; ++i) {
1956 for (
unsigned j = 0; j < h; ++j) {
1960 QRgb
rgb = blackValue;
1966 int x =
static_cast<int>(imageCoord.
x);
1967 int y =
static_cast<int>(imageCoord.
y);
1968 if (
x >= 0 && x < width && y >= 0 &&
y <
height) {
1974 orthoImage.setPixel(i, h - 1 - j,
1975 rgb != blackValue ?
rgb : blackAlphaZero);
1980 pixelSize = _pixelSize;
1988 std::vector<KeyPoint>& keypointsImage,
1992 double* realCorners )
const {
1993 double a[3], b[3], c[3];
2000 const double& a0 =
a[0];
2001 const double& a1 =
a[1];
2002 const double& a2 =
a[2];
2003 const double& b0 = b[0];
2004 const double& b1 = b[1];
2005 const double& b2 = b[2];
2007 const double& c1 = c[1];
2008 const double& c2 = c[2];
2016 double halfWidth =
width / 2.0;
2017 double halfHeight =
height / 2.0;
2022 qi = 1.0 + c1 * xi + c2 * yi;
2023 corners[0] = (a0 + a1 * xi + a2 * yi) / qi;
2024 corners[1] = (b0 + b1 * xi + b2 * yi) / qi;
2029 qi = 1.0 + c1 * xi + c2 * yi;
2030 corners[2] = (a0 + a1 * xi + a2 * yi) / qi;
2031 corners[3] = (b0 + b1 * xi + b2 * yi) / qi;
2036 qi = 1.0 + c1 * xi + c2 * yi;
2037 corners[4] = (a0 + a1 * xi + a2 * yi) / qi;
2038 corners[5] = (b0 + b1 * xi + b2 * yi) / qi;
2043 qi = 1.0 + c1 * xi + c2 * yi;
2044 corners[6] = (a0 + a1 * xi + a2 * yi) / qi;
2045 corners[7] = (b0 + b1 * xi + b2 * yi) / qi;
2048 memcpy(realCorners, corners, 8 *
sizeof(
double));
2052 double minC[2] = {corners[0], corners[1]};
2053 double maxC[2] = {corners[0], corners[1]};
2055 for (
unsigned k = 1; k < 4; ++k) {
2056 const double* C = corners + 2 * k;
2059 else if (maxC[0] < C[0])
2064 else if (maxC[1] < C[1])
2070 minCorner[0] = minC[0];
2071 minCorner[1] = minC[1];
2074 maxCorner[0] = maxC[0];
2075 maxCorner[1] = maxC[1];
2078 double dx = maxC[0] - minC[0];
2079 double dy = maxC[1] - minC[1];
2081 double _pixelSize = pixelSize;
2082 if (_pixelSize <= 0) {
2084 _pixelSize = std::max(dx, dy) / maxSize;
2086 unsigned w =
static_cast<unsigned>(dx / _pixelSize);
2087 unsigned h =
static_cast<unsigned>(dy / _pixelSize);
2089 QImage orthoImage(w, h, QImage::Format_ARGB32);
2090 if (orthoImage.isNull())
2093 const QRgb blackValue = qRgb(0, 0, 0);
2094 const QRgb blackAlphaZero = qRgba(0, 0, 0, 0);
2096 for (
unsigned i = 0; i < w; ++i) {
2097 double xip = minC[0] +
static_cast<double>(i) * _pixelSize;
2098 for (
unsigned j = 0; j < h; ++j) {
2099 QRgb
rgb = blackValue;
2102 double yip = minC[1] +
static_cast<double>(j) * _pixelSize;
2103 double q = (c2 * xip - a2) * (c1 * yip - b1) -
2104 (c2 * yip - b2) * (c1 * xip - a1);
2106 (a0 - xip) * (c1 * yip - b1) - (b0 - yip) * (c1 * xip - a1);
2109 int y =
static_cast<int>(yi);
2112 q = (c1 * xip - a1) * (c2 * yip - b2) -
2113 (c1 * yip - b1) * (c2 * xip - a2);
2114 p = (a0 - xip) * (c2 * yip - b2) - (b0 - yip) * (c2 * xip - a2);
2117 int x =
static_cast<int>(xi);
2125 orthoImage.setPixel(i, h - 1 - j,
2126 rgb != blackValue ?
rgb : blackAlphaZero);
2131 pixelSize = _pixelSize;
2137 std::vector<ccImage*> images,
2143 std::vector<ccImage*>*
result ,
2144 std::vector<std::pair<double, double>>* relativePos ) {
2145 size_t count = images.size();
2152 std::vector<double> minCorners;
2153 std::vector<double> maxCorners;
2155 minCorners.resize(2 *
count);
2156 maxCorners.resize(2 *
count);
2157 }
catch (
const std::bad_alloc&) {
2163 double maxDimAllImages = 0;
2165 double globalCorners[4] = {0, 0, 0, 0};
2168 for (
size_t k = 0; k <
count; ++k) {
2169 const double& a0 =
a[k * 3];
2170 const double& a1 =
a[k * 3 + 1];
2171 const double& a2 =
a[k * 3 + 2];
2172 const double& b0 = b[k * 3];
2173 const double& b1 = b[k * 3 + 1];
2174 const double& b2 = b[k * 3 + 2];
2176 const double& c1 = c[k * 3 + 1];
2177 const double& c2 = c[k * 3 + 2];
2183 unsigned width = images[k]->getW();
2184 unsigned height = images[k]->getH();
2189 qi = 1.0 + c1 * xi + c2 * yi;
2190 corners[0] = (a0 + a1 * xi + a2 * yi) / qi;
2191 corners[1] = (b0 + b1 * xi + b2 * yi) / qi;
2196 qi = 1.0 + c1 * xi + c2 * yi;
2197 corners[2] = (a0 + a1 * xi + a2 * yi) / qi;
2198 corners[3] = (b0 + b1 * xi + b2 * yi) / qi;
2203 qi = 1.0 + c1 * xi + c2 * yi;
2204 corners[4] = (a0 + a1 * xi + a2 * yi) / qi;
2205 corners[5] = (b0 + b1 * xi + b2 * yi) / qi;
2210 qi = 1.0 + c1 * xi + c2 * yi;
2211 corners[6] = (a0 + a1 * xi + a2 * yi) / qi;
2212 corners[7] = (b0 + b1 * xi + b2 * yi) / qi;
2215 double* minC = &minCorners[2 * k];
2216 double* maxC = &maxCorners[2 * k];
2217 maxC[0] = minC[0] = corners[0];
2218 maxC[1] = minC[1] = corners[1];
2219 for (
unsigned k = 1; k < 4; ++k) {
2220 const double* C = corners + 2 * k;
2224 else if (maxC[0] < C[0])
2227 if (globalCorners[0] > minC[0]) globalCorners[0] = minC[0];
2228 if (globalCorners[2] < maxC[0]) globalCorners[2] = maxC[0];
2233 else if (maxC[1] < C[1])
2236 if (globalCorners[1] > minC[1]) globalCorners[1] = minC[1];
2237 if (globalCorners[3] < maxC[1]) globalCorners[3] = maxC[1];
2240 double dx = maxC[0] - minC[0];
2241 double dy = maxC[1] - minC[1];
2242 double maxd = std::max(dx, dy);
2243 if (maxd > maxDimAllImages) maxDimAllImages = maxd;
2247 double pixelSize = maxDimAllImages / maxSize;
2251 QFile f(outputDir->absoluteFilePath(
"ortho_rectification_log.txt"));
2252 if (f.open(QIODevice::WriteOnly | QIODevice::Text)) {
2253 QTextStream stream(&f);
2254 stream.setRealNumberNotation(QTextStream::FixedNotation);
2255 stream.setRealNumberPrecision(6);
2257 stream <<
"Global3DBBox" <<
' ' << globalCorners[0] <<
' '
2258 << globalCorners[1] <<
' ' << globalCorners[2] <<
' '
2260 int globalWidth =
static_cast<int>(
2261 ceil((globalCorners[2] - globalCorners[0]) / pixelSize));
2262 int globalHeight =
static_cast<int>(
2263 ceil((globalCorners[3] - globalCorners[1]) / pixelSize));
2264 stream <<
"Global2DBBox" <<
' ' << 0 <<
' ' << 0 <<
' '
2265 << globalWidth - 1 <<
' ' << globalHeight - 1
2271 for (
size_t k = 0; k <
count; ++k) {
2272 double* minC = &minCorners[2 * k];
2273 double* maxC = &maxCorners[2 * k];
2274 double dx = maxC[0] - minC[0];
2275 double dy = maxC[1] - minC[1];
2278 unsigned width = images[k]->getW();
2279 unsigned height = images[k]->getH();
2280 unsigned w =
static_cast<unsigned>(
ceil(dx / pixelSize));
2281 unsigned h =
static_cast<unsigned>(
ceil(dy / pixelSize));
2283 QImage orthoImage(w, h, QImage::Format_ARGB32);
2284 if (orthoImage.isNull())
2288 while (!
result->empty()) {
2298 const double& a0 =
a[k * 3];
2299 const double& a1 =
a[k * 3 + 1];
2300 const double& a2 =
a[k * 3 + 2];
2301 const double& b0 = b[k * 3];
2302 const double& b1 = b[k * 3 + 1];
2303 const double& b2 = b[k * 3 + 2];
2305 const double& c1 = c[k * 3 + 1];
2306 const double& c2 = c[k * 3 + 2];
2308 for (
unsigned i = 0; i < w; ++i) {
2309 double xip = minC[0] +
static_cast<double>(i) * pixelSize;
2310 for (
unsigned j = 0; j < h; ++j) {
2311 double yip = minC[1] +
static_cast<double>(j) * pixelSize;
2312 double q = (c2 * xip - a2) * (c1 * yip - b1) -
2313 (c2 * yip - b2) * (c1 * xip - a1);
2314 double p = (a0 - xip) * (c1 * yip - b1) -
2315 (b0 - yip) * (c1 * xip - a1);
2318 q = (c1 * xip - a1) * (c2 * yip - b2) -
2319 (c1 * yip - b1) * (c2 * xip - a2);
2320 p = (a0 - xip) * (c2 * yip - b2) - (b0 - yip) * (c2 * xip - a2);
2326 int x =
static_cast<int>(xi);
2327 int y =
static_cast<int>(yi);
2328 if (
x >= 0 &&
x <
static_cast<int>(
width) &&
y >= 0 &&
2329 y < static_cast<int>(
height)) {
2332 if (qRed(
rgb) + qGreen(
rgb) + qBlue(
rgb) > 0)
2333 orthoImage.setPixel(i, h - 1 - j,
rgb);
2335 orthoImage.setPixel(
2337 qRgba(qRed(
rgb), qGreen(
rgb), qBlue(
rgb), 0));
2339 orthoImage.setPixel(i, h - 1 - j, qRgba(255, 0, 255, 0));
2345 double xShift = (minC[0] - minCorners[0]) / pixelSize;
2346 double yShift = (minC[1] - minCorners[1]) / pixelSize;
2347 relativePos->emplace_back(xShift, yShift);
2352 QString exportFilename =
2353 QString(
"ortho_rectified_%1.png").arg(
image->getName());
2354 orthoImage.save(outputDir->absoluteFilePath(exportFilename));
2357 QFile f(outputDir->absoluteFilePath(
"ortho_rectification_log.txt"));
2361 double xShiftGlobal = (minC[0] - globalCorners[0]) / pixelSize;
2362 double yShiftGlobal = (minC[1] - globalCorners[1]) / pixelSize;
2363 QTextStream stream(&f);
2364 stream.setRealNumberNotation(QTextStream::FixedNotation);
2365 stream.setRealNumberPrecision(6);
2366 stream <<
"Image" <<
' ' << exportFilename <<
' ';
2367 stream <<
"Local3DBBox" <<
' ' << minC[0] <<
' ' << minC[1]
2368 <<
' ' << maxC[0] <<
' ' << maxC[1] <<
' ';
2369 stream <<
"Local2DBBox" <<
' ' << xShiftGlobal <<
' '
2370 << yShiftGlobal <<
' ' << xShiftGlobal + (double)(w - 1)
2371 <<
' ' << yShiftGlobal + (double)(h - 1)
2387 std::vector<KeyPoint>& keypointsImage)
const {
2388 double a[3], b[3], c[3];
2394 const double& a0 =
a[0];
2395 const double& a1 =
a[1];
2396 const double& a2 =
a[2];
2397 const double& b0 = b[0];
2398 const double& b1 = b[1];
2399 const double& b2 = b[2];
2401 const double& c1 = c[1];
2402 const double& c2 = c[2];
2418 unsigned realCount = 0;
2422 for (
unsigned pi = 0; pi <
width; ++pi) {
2423 double xi =
static_cast<double>(pi) - 0.5 *
width;
2424 for (
unsigned pj = 0; pj <
height; ++pj) {
2425 double yi =
static_cast<double>(pj) - 0.5 *
height;
2426 double qi = 1.0 + c1 * xi + c2 * yi;
2428 (a0 + a1 * xi + a2 * yi) / qi),
2430 (b0 + b1 * xi + b2 * yi) / qi),
2434 QRgb
rgb =
image->data().pixel(pi, pj);
2436 int g = qGreen(
rgb);
2438 if (r + g + b > 0) {
2452 if (realCount == 0) {
2453 CVLog::Warning(QString(
"[orthoRectifyAsCloud] Image '%1' was black, "
2454 "nothing to project!")
2455 .arg(
image->getName()));
2472 if (!
octree)
return false;
2479 cloudViewer::DgmOctree::cellsContainer::const_iterator it =
2480 thePointsAndTheirCellCodes.begin();
2483 for (it = thePointsAndTheirCellCodes.begin();
2484 it != thePointsAndTheirCellCodes.end(); ++it) {
2486 for (
unsigned char level = 1;
2488 unsigned char bitDec =
2493 }
catch (
const std::bad_alloc&) {
2494 CVLog::Warning(
"[ccCameraSensor::prepareOctree] Not enough memory!");
2510 const float planesCoefficients[6][4],
2516 CCVector3 boxCenter = (bbMax + bbMin) / 2;
2520 (frustumCorners[0] - frustumCenter).norm();
2530 for (
unsigned i = 0; i < 8; i++)
2531 boxCorners[i] =
CCVector3((i & 4) ? bbMin.
x : bbMax.
x,
2532 (i & 2) ? bbMin.
y : bbMax.
y,
2533 (i & 1) ? bbMin.
z : bbMax.
z);
2543 static const unsigned nbVecToTest = 28;
2550 VecToTest[3] =
CCVector3(planesCoefficients[0][0], planesCoefficients[0][1],
2551 planesCoefficients[0][2]);
2552 VecToTest[4] =
CCVector3(planesCoefficients[1][0], planesCoefficients[1][1],
2553 planesCoefficients[1][2]);
2554 VecToTest[5] =
CCVector3(planesCoefficients[2][0], planesCoefficients[2][1],
2555 planesCoefficients[2][2]);
2556 VecToTest[6] =
CCVector3(planesCoefficients[3][0], planesCoefficients[3][1],
2557 planesCoefficients[3][2]);
2558 VecToTest[7] =
CCVector3(planesCoefficients[4][0], planesCoefficients[4][1],
2559 planesCoefficients[4][2]);
2561 VecToTest[8] = VecToTest[0].
cross(frustumEdges[0]);
2562 VecToTest[9] = VecToTest[0].
cross(frustumEdges[1]);
2563 VecToTest[10] = VecToTest[0].
cross(frustumEdges[2]);
2564 VecToTest[11] = VecToTest[0].
cross(frustumEdges[3]);
2565 VecToTest[12] = VecToTest[0].
cross(frustumEdges[4]);
2566 VecToTest[13] = VecToTest[0].
cross(frustumEdges[5]);
2567 VecToTest[14] = VecToTest[1].
cross(frustumEdges[0]);
2568 VecToTest[15] = VecToTest[1].
cross(frustumEdges[1]);
2569 VecToTest[16] = VecToTest[1].
cross(frustumEdges[2]);
2570 VecToTest[17] = VecToTest[1].
cross(frustumEdges[3]);
2571 VecToTest[18] = VecToTest[1].
cross(frustumEdges[4]);
2572 VecToTest[19] = VecToTest[1].
cross(frustumEdges[5]);
2573 VecToTest[20] = VecToTest[2].
cross(frustumEdges[0]);
2574 VecToTest[21] = VecToTest[2].
cross(frustumEdges[1]);
2575 VecToTest[22] = VecToTest[2].
cross(frustumEdges[2]);
2576 VecToTest[23] = VecToTest[2].
cross(frustumEdges[3]);
2577 VecToTest[24] = VecToTest[2].
cross(frustumEdges[4]);
2578 VecToTest[25] = VecToTest[2].
cross(frustumEdges[5]);
2580 VecToTest[26] = frustumEdges[0].
cross(frustumEdges[2]);
2581 VecToTest[27] = frustumEdges[1].
cross(frustumEdges[3]);
2585 for (
unsigned i = 0; i < nbVecToTest; i++) VecToTest[i].normalize();
2588 bool boxInside =
true;
2592 for (
unsigned i = 0; i < nbVecToTest; i++) {
2596 float dMinBox = testVec.
dot(boxCorners[0]);
2597 float dMaxBox = dMinBox;
2599 for (
unsigned j = 1; j < 8; j++) {
2600 float d = testVec.
dot(boxCorners[j]);
2601 if (d > dMaxBox) dMaxBox = d;
2602 if (d < dMinBox) dMinBox = d;
2607 float dMinFru = testVec.
dot(frustumCorners[0]);
2608 float dMaxFru = dMinFru;
2610 for (
unsigned j = 1; j < 8; j++) {
2611 float d = testVec.
dot(frustumCorners[j]);
2612 if (d > dMaxFru) dMaxFru = d;
2613 if (d < dMinFru) dMinFru = d;
2619 if (dMaxBox < dMinFru || dMaxFru < dMinBox)
2626 if (dMaxBox > dMaxFru || dMinBox < dMinFru) boxInside =
false;
2635 unsigned char level,
2638 const float planesCoefficients[6][4],
2646 (parentTruncatedCode << 3);
2649 for (
unsigned i = 0; i < 8; i++) {
2655 std::unordered_set<cloudViewer::DgmOctree::CellCode>::const_iterator
2669 ptsFrustum, edges, center));
2683 level + 1, truncatedCode,
result,
2684 planesCoefficients, ptsFrustum, edges, center);
2691 std::vector<std::pair<unsigned, CCVector3>>& pointsToTest,
2692 std::vector<unsigned>& inCameraFrustum,
2693 const float planesCoefficients[6][4],
2707 planesCoefficients, ptsFrustum, edges,
2711 unsigned char level =
static_cast<unsigned char>(
2715 std::unordered_set<cloudViewer::DgmOctree::CellCode>::const_iterator it;
2725 for (
size_t i = 0; i < pointsInCell.
size(); i++)
2727 static_cast<unsigned>(i)));
2739 size_t pointCount = pointsInCell.
size();
2740 size_t sizeBefore = pointsToTest.size();
2741 pointsToTest.resize(pointCount + sizeBefore);
2742 for (
size_t i = 0; i < pointCount; i++) {
2744 static_cast<unsigned>(i));
2746 pointsInCell.
getPoint(
static_cast<unsigned>(i));
2747 pointsToTest[sizeBefore + i] =
2748 std::pair<unsigned, CCVector3>(currentIndice, *vec);
constexpr PointCoordinateType PC_ONE
'1' as a PointCoordinateType value
constexpr ScalarType NAN_VALUE
NaN as a ScalarType value.
Vector3Tpl< PointCoordinateType > CCVector3
Default 3D Vector.
float PointCoordinateType
Type of the coordinates of a (N-D) point.
std::shared_ptr< core::Tensor > image
static bool PrintDebug(const char *format,...)
Same as Print, but works only in Debug mode.
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
Type norm2() const
Returns vector square norm.
void normalize()
Sets vector norm to unity.
Type dot(const Vector3Tpl &v) const
Dot product.
Type norm2() const
Returns vector square norm.
Type norm() const
Returns vector norm.
Vector3Tpl cross(const Vector3Tpl &v) const
Cross product.
static Vector3Tpl fromArray(const int a[3])
Constructor from an int array.
Camera (projective) sensor.
const ecvColor::Rgb & getPlaneColor() const
virtual ccBBox getOwnBB(bool withGLFeatures=false) override
Returns the entity's own bounding-box.
bool computeGlobalPlaneCoefficients(float planeCoefficients[6][4], CCVector3 ptsFrustum[8], CCVector3 edges[6], CCVector3 ¢er)
ccCameraSensor()
Default constructor.
FrustumInformation m_frustumInfos
Frustum information structure.
bool fromImageCoordToLocalCoord(const CCVector2 &imageCoord, CCVector3 &localCoord, PointCoordinateType depth, bool withLensCorrection=true) const
ecvColor::Rgb m_plane_color
void computeProjectionMatrix()
Compute the projection matrix (from intrinsic parameters)
virtual ccBBox getOwnFitBB(ccGLMatrix &trans) override
Returns best-fit bounding-box (if available)
LensDistortionParameters::Shared m_distortionParams
Lens distortion parameters.
void setVerticalFov_rad(float fov_rad)
Sets the (vertical) field of view in radians.
bool computeOrthoRectificationParams(const ccImage *image, cloudViewer::GenericIndexedCloud *keypoints3D, std::vector< KeyPoint > &keypointsImage, double a[3], double b[3], double c[3]) const
Computes ortho-rectification parameters for a given image.
cloudViewer::geometry::LineSet m_arrow
ccPointCloud * orthoRectifyAsCloud(const ccImage *image, cloudViewer::GenericIndexedCloud *keypoints3D, std::vector< KeyPoint > &keypointsImage) const
Projective ortho-rectification of an image (as cloud)
virtual void hideShowDrawings(CC_DRAW_CONTEXT &context) override
bool toFile_MeOnly(QFile &out, short dataVersion) const override
Save own object data.
bool computeFrustumCorners()
Computes the eight corners of the frustum.
virtual ~ccCameraSensor() override
Destructor.
float getVertFocal_pix() const
Returns vertical focal (in pixels)
static float ConvertFocalMMToPix(float focal_mm, float ccdPixelSize_mm)
Helper: converts camera focal from mm to pixels.
bool fromGlobalCoordToImageCoord(const CCVector3 &globalCoord, CCVector2 &imageCoord, bool withLensError=true) const
CCVector3 computeUpperLeftPoint() const
Used internally for display.
void setVertFocal_pix(float vertFocal_pix)
Sets focal (in pixels)
ccImage * orthoRectifyAsImageDirect(const ccImage *image, PointCoordinateType altitude, double &pixelSize, bool undistortImages=true, double *minCorner=nullptr, double *maxCorner=nullptr, double *realCorners=nullptr) const
Direct ortho-rectification of an image (as image)
short minimumFileVersion_MeOnly() const override
virtual void clearDrawings() override
ccImage * orthoRectifyAsImage(const ccImage *image, cloudViewer::GenericIndexedCloud *keypoints3D, std::vector< KeyPoint > &keypointsImage, double &pixelSize, double *minCorner=nullptr, double *maxCorner=nullptr, double *realCorners=nullptr) const
Projective ortho-rectification of an image (as image)
bool isGlobalCoordInFrustum(const CCVector3 &globalCoord) const
Tests if a 3D point is in the field of view of the camera.
void setIntrinsicParameters(const IntrinsicParameters ¶ms)
Sets intrinsic parameters.
bool fromGlobalCoordToLocalCoord(const CCVector3 &globalCoord, CCVector3 &localCoord) const
static float ComputeFovRadFromFocalPix(float focal_pix, int imageSize_pix)
Helper: deduces camera f.o.v. (in radians) from focal (in pixels)
cloudViewer::geometry::LineSet m_nearPlane
static bool OrthoRectifyAsImages(std::vector< ccImage * > images, double a[], double b[], double c[], unsigned maxSize, QDir *outputDir=nullptr, std::vector< ccImage * > *orthoRectifiedImages=nullptr, std::vector< std::pair< double, double >> *relativePos=nullptr)
Projective ortho-rectification of multiple images (as image files)
float getHorizFocal_pix() const
Returns horizontal focal (in pixels)
cloudViewer::geometry::LineSet m_axis
bool fromLocalCoordToGlobalCoord(const CCVector3 &localCoord, CCVector3 &globalCoord) const
cloudViewer::geometry::LineSet m_sideLines
virtual void drawMeOnly(CC_DRAW_CONTEXT &context) override
Draws the entity only (not its children)
bool getProjectionMatrix(ccGLMatrix &matrix)
Returns the camera projection matrix.
IntrinsicParameters m_intrinsicParams
Camera intrinsic parameters.
bool computeUncertainty(const CCVector2 &pixel, const float depth, Vector3Tpl< ScalarType > &sigma) const
static float ConvertFocalPixToMM(float focal_pix, float ccdPixelSize_mm)
Helper: converts camera focal from pixels to mm.
bool fromLocalCoordToImageCoord(const CCVector3 &localCoord, CCVector2 &imageCoord, bool withLensError=true) const
bool fromFile_MeOnly(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap) override
Loads own object data.
QImage undistort(const QImage &image) const
Undistorts an image based on the sensor distortion parameters.
static float ComputeFovRadFromFocalMm(float focal_mm, float ccdSize_mm)
Helper: deduces camera f.o.v. (in radians) from focal (in mm)
bool fromImageCoordToGlobalCoord(const CCVector2 &imageCoord, CCVector3 &globalCoord, PointCoordinateType z0, bool withLensCorrection=true) const
virtual bool applyViewport() override
Apply sensor 'viewport' to a 3D view.
bool m_projectionMatrixIsValid
Whether the intrinsic matrix is valid or not.
bool fromRealImCoordToIdealImCoord(const CCVector2 &real, CCVector2 &ideal) const
DistortionModel
Supported distortion models.
@ SIMPLE_RADIAL_DISTORTION
@ EXTENDED_RADIAL_DISTORTION
void setDistortionParameters(LensDistortionParameters::Shared params)
Sets uncertainty parameters.
ccGLMatrix m_projectionMatrix
Intrinsic parameters matrix.
void drawFrustum(bool state)
Sets whether the frustum should be displayed or not.
virtual void lockVisibility(bool state)
Locks/unlocks visibility.
virtual void setTempColor(const ecvColor::Rgb &col, bool autoActivate=true)
Sets current temporary (unique)
virtual void showColors(bool state)
Sets colors visibility.
virtual void setOpacity(float opacity)
Set opacity activation state.
Vector3Tpl< T > getTranslationAsVec3D() const
Returns a copy of the translation as a CCVector3.
virtual void toZero()
Clears matrix.
bool fromFile(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap) override
Loads data from binary stream.
void applyRotation(Vector3Tpl< float > &vec) const
Applies rotation only to a 3D vector (in place) - float version.
T * data()
Returns a pointer to internal data.
void apply(float vec[3]) const
Applies transformation to a 3D vector (in place) - float version.
Vector3Tpl< T > getColumnAsVec3D(unsigned index) const
Returns a copy of a given column as a CCVector3.
static Eigen::Matrix< double, 4, 4 > ToEigenMatrix4(const ccGLMatrixTpl< float > &mat)
Float version of ccGLMatrixTpl.
virtual void showWired(bool state)
Sets whether mesh should be displayed as a wire or with plain facets.
void enableStippling(bool state)
Enables polygon stippling.
ccBBox getOwnBB(bool withGLFeatures=false) override
Returns the entity's own bounding-box.
QString getViewId() const
virtual void setSelectionBehavior(SelectionBehavior mode)
Sets selection behavior (when displayed)
virtual QString getName() const
Returns object name.
void computeFrustumIntersectionWithOctree(std::vector< std::pair< unsigned, CCVector3 >> &pointsToTest, std::vector< unsigned > &inCameraFrustum, const float planesCoefficients[6][4], const CCVector3 ptsFrustum[8], const CCVector3 edges[6], const CCVector3 ¢er)
cloudViewer::DgmOctree * m_associatedOctree
OctreeCellVisibility
Definition of the state of a cell compared to a frustum.
OctreeCellVisibility separatingAxisTest(const CCVector3 &bbMin, const CCVector3 &bbMax, const float planesCoefficients[6][4], const CCVector3 frustumCorners[8], const CCVector3 frustumEdges[6], const CCVector3 &frustumCenter)
Separating Axis Test.
bool build(cloudViewer::DgmOctree *octree)
Prepares structure for frustum filtering.
std::unordered_set< cloudViewer::DgmOctree::CellCode > m_cellsBuilt[cloudViewer::DgmOctree::MAX_OCTREE_LEVEL+1]
void computeFrustumIntersectionByLevel(unsigned char level, cloudViewer::DgmOctree::CellCode parentTruncatedCode, OctreeCellVisibility parentResult, const float planesCoefficients[6][4], const CCVector3 ptsFrustum[8], const CCVector3 edges[6], const CCVector3 ¢er)
std::unordered_set< cloudViewer::DgmOctree::CellCode > m_cellsInFrustum[cloudViewer::DgmOctree::MAX_OCTREE_LEVEL+1]
std::unordered_set< cloudViewer::DgmOctree::CellCode > m_cellsIntersectFrustum[cloudViewer::DgmOctree::MAX_OCTREE_LEVEL+1]
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
bool reserve(unsigned numberOfPoints) override
Reserves memory for all the active features.
bool reserveTheRGBTable()
Reserves memory to store the RGB colors.
virtual void applyRigidTransformation(const ccGLMatrix &trans) override
Applies a rigid transformation (rotation + translation)
bool resize(unsigned numberOfPoints) override
Resizes all the active features arrays.
void addRGBColor(const ecvColor::Rgb &C)
Pushes an RGB color on stack.
Generic sensor interface.
short minimumFileVersion_MeOnly() const override
bool fromFile_MeOnly(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap) override
Loads own object data.
PointCoordinateType m_scale
Sensor graphic representation scale.
bool toFile_MeOnly(QFile &out, short dataVersion) const override
Save own object data.
double m_activeIndex
Active index (for displayed position, etc.)
bool getAbsoluteTransformation(ccIndexedTransformation &trans, double index) const
bool getActiveAbsoluteTransformation(ccIndexedTransformation &trans) const
Gets currently active absolute transformation.
ecvColor::Rgb m_color
Color of the sensor.
double getActiveIndex() const
Sets currently active index (displayed position, etc.)
const ecvColor::Rgb & getFrameColor() const
QMultiMap< unsigned, unsigned > LoadedIDMap
Map of loaded unique IDs (old ID --> new ID)
static bool ReadError()
Sends a custom error message (read error) and returns 'false'.
static void CoordsFromDataStream(QDataStream &stream, int flags, PointCoordinateType *out, unsigned count=1)
A class to perform a conjugate gradient optimization.
Scalar iterConjugateGradient(Scalar *Xn)
Iterates the conjugate gradient.
cloudViewer::SquareMatrixTpl< Scalar > & A()
Returns A matrix.
void initConjugateGradient(const Scalar *X0)
Initializes the conjugate gradient.
Scalar * b()
Returns b vector.
The octree structure used throughout the library.
unsigned CellCode
Type of the code of an octree cell.
GenericIndexedCloudPersist * associatedCloud() const
Returns the associated cloud.
static const int MAX_OCTREE_LEVEL
Max octree subdivision level.
bool getPointsInCell(CellCode cellCode, unsigned char level, ReferenceCloud *subset, bool isCodeTruncated=false, bool clearOutputCloud=true) const
Returns the points lying in a specific cell.
void computeCellLimits(CellCode code, unsigned char level, CCVector3 &cellMin, CCVector3 &cellMax, bool isCodeTruncated=false) const
Returns the spatial limits of a given cell.
std::vector< IndexAndCode > cellsContainer
Container of 'IndexAndCode' structures.
const cellsContainer & pointsAndTheirCellCodes() const
Returns the octree 'structure'.
static unsigned char GET_BIT_SHIFT(unsigned char level)
Returns the binary shift for a given level of subdivision.
A generic 3D point cloud with index-based point access.
virtual const CCVector3 * getPoint(unsigned index) const =0
Returns the ith point.
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
unsigned size() const override
const CCVector3 * getPoint(unsigned index) const override
A very simple point cloud (no point duplication)
unsigned size() const override
Returns the number of points.
virtual unsigned getPointGlobalIndex(unsigned localIndex) const
const CCVector3 * getPoint(unsigned index) const override
Returns the ith point.
Scalar ** m_values
The matrix rows.
std::vector< Eigen::Vector3d > points_
Points coordinates.
std::vector< Eigen::Vector3d > colors_
RGB colors of lines.
std::vector< Eigen::Vector2i > lines_
Lines denoted by the index of points forming the line.
virtual LineSet & Transform(const Eigen::Matrix4d &transformation) override
Apply transformation (4x4 matrix) to the geometry coordinates.
static Eigen::Vector3d ToEigen(const Type col[3])
Standard parameters for GL displays/viewports.
float fov_deg
Camera F.O.V. (field of view) in degrees.
double zFar
Actual perspective 'zFar' value.
void setPivotPoint(const CCVector3d &P, bool autoUpdateFocal=true)
Sets the pivot point (for object-centered view mode)
void setCameraCenter(const CCVector3d &C, bool autoUpdateFocal=true)
Sets the camera center.
double zNear
Actual perspective 'zNear' value.
unsigned char ColorCompType
Default color components type (R,G and B)
#define MACRO_Draw3D(context)
QTextStream & endl(QTextStream &stream)
Tensor Append(const Tensor &self, const Tensor &other, const utility::optional< int64_t > &axis)
Appends the two tensors, along the given axis into a new tensor. Both the tensors must have same data...
MiniVec< float, N > ceil(const MiniVec< float, N > &a)
float RadiansToDegrees(int radians)
Convert radians to degrees.
bool LessThanEpsilon(float x)
Test a floating point number against our epsilon (a very small number).
constexpr Rgb red(MAX, 0, 0)
constexpr Rgb green(0, MAX, 0)
constexpr Rgb yellow(MAX, MAX, 0)
Eigen::Matrix< Index, 2, 1 > Vector2i
Brown's distortion model + Linear Disparity.
float linearDisparityParams[2]
float principalPointOffset[2]
static void GetKinectDefaults(BrownDistortionParameters ¶ms)
BrownDistortionParameters()
Default initializer.
Extended radial distortion model.
float k3
3rd radial distortion coefficient
Intrinsic parameters of the camera sensor.
IntrinsicParameters()
Default initializer.
static void GetKinectDefaults(IntrinsicParameters ¶ms)
unsigned index
Index in associated point cloud.
float y
2D 'y' coordinate (in pixels)
float x
2D 'x' coordinate (in pixels)
QSharedPointer< LensDistortionParameters > Shared
Shared pointer type.
Simple radial distortion model.
float k2
2nd radial distortion coefficient
float k1
1st radial distortion coefficient
int drawingFlags
Drawing options (see below)
ecvColor::Rgb defaultPolylineColor
Default color for polyline.
ecvColor::Rgb defaultMeshColor
Default color for mesh.
unsigned char currentLineWidth
MESH_RENDERING_MODE meshRenderingMode