58 if (nNeighborhoodSize < 1)
60 LOG_WARNING(logging::g_qSharedLogger,
"GeolocateBox: Invalid neighborhood size {}, defaulting to 5x5", nNeighborhoodSize);
61 nNeighborhoodSize = 5;
65 int nHalfSize = nNeighborhoodSize / 2;
68 std::vector<float> vX, vY, vZ, vDistances;
71 for (
int nOffsetY = -nHalfSize; nOffsetY <= nHalfSize; ++nOffsetY)
73 for (
int nOffsetX = -nHalfSize; nOffsetX <= nHalfSize; ++nOffsetX)
76 int nCurrY = cvPixel.
y + nOffsetY;
77 int nCurrX = cvPixel.
x + nOffsetX;
80 if (nCurrY < 0 || nCurrY >= cvPointcloud.
rows || nCurrX < 0 || nCurrX >= cvPointcloud.
cols)
89 if (cvPoint[2] > 0 && std::isfinite(cvPoint[0]) && std::isfinite(cvPoint[1]) && std::isfinite(cvPoint[2]))
92 vX.push_back(cvPoint[0]);
93 vY.push_back(cvPoint[1]);
94 vZ.push_back(cvPoint[2]);
102 LOG_DEBUG(logging::g_qSharedLogger,
"GeolocateBox: No valid points found in neighborhood around pixel ({}, {})", cvPixel.
x, cvPixel.
y);
108 float fAvgX = std::accumulate(vX.begin(), vX.end(), 0.0f) / vX.size();
109 float fAvgY = std::accumulate(vY.begin(), vY.end(), 0.0f) / vY.size();
110 float fAvgZ = std::accumulate(vZ.begin(), vZ.end(), 0.0f) / vZ.size();
115 double dHeadingRad = dAdjustedHeading * M_PI / 180.0;
127 double dEasting = stRoverUTM.dEasting + (fAvgZ *
cos(dHeadingRad) + fAvgX *
sin(dHeadingRad));
128 double dNorthing = stRoverUTM.dNorthing + (fAvgZ *
sin(dHeadingRad) - fAvgX *
cos(dHeadingRad));
131 double dAltitude = stRoverUTM.dAltitude + fAvgY;
134 geoops::UTMCoordinate stObjectUTM(dEasting, dNorthing, stRoverUTM.nZone, stRoverUTM.bWithinNorthernHemisphere, dAltitude);
137 double dRadius = 0.0;
141 for (
size_t siI = 0; siI < vX.size(); ++siI)
143 double dX = vX[siI] - fAvgX;
144 double dY = vY[siI] - fAvgY;
145 double dZ = vZ[siI] - fAvgZ;
146 vDistances.push_back(
sqrt(dX * dX + dY * dY + dZ * dZ));
150 std::sort(vDistances.begin(), vDistances.end());
151 if (vDistances.size() % 2 == 0)
153 dRadius = (vDistances[vDistances.size() / 2 - 1] + vDistances[vDistances.size() / 2]) / 2.0;
157 dRadius = vDistances[vDistances.size() / 2];
165 return geoops::Waypoint(stObjectUTM, geoops::WaypointType::eUNKNOWN, dRadius);