数据类型转换
This commit is contained in:
parent
517889ff90
commit
47fef439e3
@ -67,6 +67,10 @@ public:
|
|||||||
std::vector<std::vector<SVzNL3DPosition>>& scanLines,
|
std::vector<std::vector<SVzNL3DPosition>>& scanLines,
|
||||||
size_t* validPointCount = nullptr);
|
size_t* validPointCount = nullptr);
|
||||||
|
|
||||||
|
// 转换统一格式数据为std::vector<std::vector<SVzNLPositionD>>格式
|
||||||
|
int ConvertToSVzNLPositionD(const std::vector<std::pair<EVzResultDataType, SVzLaserLineData>>& unifiedData,
|
||||||
|
std::vector<std::vector<SVzNLPositionD>>& scanLines);
|
||||||
|
|
||||||
// 从文件加载Poly折线数据(带颜色)
|
// 从文件加载Poly折线数据(带颜色)
|
||||||
// polyLines: 每条折线的点坐标列表,polyLines[i] 是第i条折线的所有点(含RGB颜色)
|
// polyLines: 每条折线的点坐标列表,polyLines[i] 是第i条折线的所有点(含RGB颜色)
|
||||||
int LoadPolySegments(const std::string& fileName,
|
int LoadPolySegments(const std::string& fileName,
|
||||||
@ -78,6 +82,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
// 读取XYZ格式的激光数据
|
// 读取XYZ格式的激光数据
|
||||||
int _ParseLaserScanPoint(const std::string& data, SVzNL3DPosition& sData, SVzNL2DPosition& s2DData);
|
int _ParseLaserScanPoint(const std::string& data, SVzNL3DPosition& sData, SVzNL2DPosition& s2DData);
|
||||||
|
int _ParseLaserScanPoint(const std::string& data, SVzNL3DPosition& sData, SVzNL2DPositionF& s2DData);
|
||||||
|
|
||||||
// 读取RGBD格式的激光数据 - 新增RGBD支持
|
// 读取RGBD格式的激光数据 - 新增RGBD支持
|
||||||
int _ParseLaserScanPoint(const std::string& data, SVzNLPointXYZRGBA& sData, SVzNL2DLRPoint& s2DData);
|
int _ParseLaserScanPoint(const std::string& data, SVzNLPointXYZRGBA& sData, SVzNL2DLRPoint& s2DData);
|
||||||
|
|||||||
@ -285,10 +285,15 @@ int LaserDataLoader::LoadLaserScanData(const std::string& fileName,
|
|||||||
SVzNL2DLRPoint* p2DPoints = static_cast<SVzNL2DLRPoint*>(sLaserData.p2DPoint);
|
SVzNL2DLRPoint* p2DPoints = static_cast<SVzNL2DLRPoint*>(sLaserData.p2DPoint);
|
||||||
_ParseLaserScanPoint(line, pRGBAPoints[nLaserPointIdx], p2DPoints[nLaserPointIdx]);
|
_ParseLaserScanPoint(line, pRGBAPoints[nLaserPointIdx], p2DPoints[nLaserPointIdx]);
|
||||||
nLaserPointIdx++;
|
nLaserPointIdx++;
|
||||||
} else {
|
} else if (eDataType == keResultDataType_Position) {
|
||||||
SVzNL3DPosition* p3DPoints = static_cast<SVzNL3DPosition*>(sLaserData.p3DPoint);
|
SVzNL3DPosition* p3DPoints = static_cast<SVzNL3DPosition*>(sLaserData.p3DPoint);
|
||||||
SVzNL2DPosition* p2DPoints = static_cast<SVzNL2DPosition*>(sLaserData.p2DPoint);
|
SVzNL2DPosition* p2DPoints = static_cast<SVzNL2DPosition*>(sLaserData.p2DPoint);
|
||||||
_ParseLaserScanPoint(line, p3DPoints[nLaserPointIdx], p2DPoints[nLaserPointIdx]);
|
result = _ParseLaserScanPoint(line, p3DPoints[nLaserPointIdx], p2DPoints[nLaserPointIdx]);
|
||||||
|
if (result != SUCCESS) {
|
||||||
|
m_lastError = "Invalid XYZUV point line: " + line;
|
||||||
|
LOG_ERROR("%s\n", m_lastError.c_str());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
p3DPoints[nLaserPointIdx].nPointIdx = nLaserPointIdx;
|
p3DPoints[nLaserPointIdx].nPointIdx = nLaserPointIdx;
|
||||||
nLaserPointIdx++;
|
nLaserPointIdx++;
|
||||||
}
|
}
|
||||||
@ -530,6 +535,26 @@ int LaserDataLoader::SaveLaserScanData(const std::string& fileName,
|
|||||||
}
|
}
|
||||||
sw.write(buffer.data(), static_cast<std::streamsize>(buffer.size()));
|
sw.write(buffer.data(), static_cast<std::streamsize>(buffer.size()));
|
||||||
}
|
}
|
||||||
|
} else if (dataType == keResultDataType_PositionF && lineData.p3DPoint) {
|
||||||
|
const SVzNL3DPosition* points = static_cast<const SVzNL3DPosition*>(lineData.p3DPoint);
|
||||||
|
const SVzNL2DPositionF* points2D = static_cast<const SVzNL2DPositionF*>(lineData.p2DPoint);
|
||||||
|
constexpr int BATCH = 256;
|
||||||
|
constexpr int PER_POINT = 160;
|
||||||
|
for (int base = 0; base < lineData.nPointCount; base += BATCH) {
|
||||||
|
int end = (base + BATCH < lineData.nPointCount) ? (base + BATCH) : lineData.nPointCount;
|
||||||
|
std::string buffer;
|
||||||
|
buffer.reserve(BATCH * PER_POINT);
|
||||||
|
for (int i = base; i < end; ++i) {
|
||||||
|
AppendFormattedLine(buffer,
|
||||||
|
"{ %.9f, %.9f, %.9f } - { %.6f, %.6f } - { %.6f, %.6f }\n",
|
||||||
|
points[i].pt3D.x, points[i].pt3D.y, points[i].pt3D.z,
|
||||||
|
points2D ? points2D[i].ptLeft2D.x : 0.0f,
|
||||||
|
points2D ? points2D[i].ptLeft2D.y : 0.0f,
|
||||||
|
points2D ? points2D[i].ptRight2D.x : 0.0f,
|
||||||
|
points2D ? points2D[i].ptRight2D.y : 0.0f);
|
||||||
|
}
|
||||||
|
sw.write(buffer.data(), static_cast<std::streamsize>(buffer.size()));
|
||||||
|
}
|
||||||
} else if (dataType == keResultDataType_PointXYZI && lineData.p3DPoint) {
|
} else if (dataType == keResultDataType_PointXYZI && lineData.p3DPoint) {
|
||||||
// LiDAR 点云:snprintf 批量写入,每 256 点 flush
|
// LiDAR 点云:snprintf 批量写入,每 256 点 flush
|
||||||
// 坐标 mm 范围可达 ±200000 → "%.6f" 最长 14 字符 → 整行 ≤73 字符
|
// 坐标 mm 范围可达 ±200000 → "%.6f" 最长 14 字符 → 整行 ≤73 字符
|
||||||
@ -820,7 +845,7 @@ void LaserDataLoader::FreeLaserScanData(std::vector<std::pair<EVzResultDataType,
|
|||||||
delete[] static_cast<SVzNL3DPosition*>(lineData.p3DPoint);
|
delete[] static_cast<SVzNL3DPosition*>(lineData.p3DPoint);
|
||||||
break;
|
break;
|
||||||
case keResultDataType_PositionF:
|
case keResultDataType_PositionF:
|
||||||
delete[] static_cast<SVzNL3DPositionF*>(lineData.p3DPoint);
|
delete[] static_cast<SVzNL3DPosition*>(lineData.p3DPoint);
|
||||||
break;
|
break;
|
||||||
case keResultDataType_PointF:
|
case keResultDataType_PointF:
|
||||||
delete[] static_cast<SVzNL3DPointF*>(lineData.p3DPoint);
|
delete[] static_cast<SVzNL3DPointF*>(lineData.p3DPoint);
|
||||||
@ -915,6 +940,22 @@ int LaserDataLoader::ConvertToSVzNL3DPosition(const std::vector<std::pair<EVzRes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scanLines.push_back(scanLine);
|
||||||
|
} else if (dataType == keResultDataType_PositionF && lineData.p3DPoint) {
|
||||||
|
std::vector<SVzNL3DPosition> scanLine;
|
||||||
|
scanLine.reserve(lineData.nPointCount);
|
||||||
|
|
||||||
|
const SVzNL3DPosition* points = static_cast<const SVzNL3DPosition*>(lineData.p3DPoint);
|
||||||
|
for (int i = 0; i < lineData.nPointCount; i++) {
|
||||||
|
scanLine.push_back(points[i]);
|
||||||
|
|
||||||
|
if (std::fabs(points[i].pt3D.x) > EPSILON &&
|
||||||
|
std::fabs(points[i].pt3D.y) > EPSILON &&
|
||||||
|
std::fabs(points[i].pt3D.z) > EPSILON) {
|
||||||
|
validCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
scanLines.push_back(scanLine);
|
scanLines.push_back(scanLine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -928,6 +969,82 @@ int LaserDataLoader::ConvertToSVzNL3DPosition(const std::vector<std::pair<EVzRes
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int LaserDataLoader::ConvertToSVzNLPositionD(
|
||||||
|
const std::vector<std::pair<EVzResultDataType, SVzLaserLineData>>& unifiedData,
|
||||||
|
std::vector<std::vector<SVzNLPositionD>>& scanLines)
|
||||||
|
{
|
||||||
|
LOG_DEBUG("Converting unified data to SVzNLPositionD scan lines format\n");
|
||||||
|
|
||||||
|
scanLines.clear();
|
||||||
|
|
||||||
|
for (const auto& linePair : unifiedData) {
|
||||||
|
if (linePair.first != keResultDataType_Position &&
|
||||||
|
linePair.first != keResultDataType_PositionF) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SVzLaserLineData& lineData = linePair.second;
|
||||||
|
if (lineData.nPointCount < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lineData.nPointCount > 0 && (!lineData.p3DPoint || !lineData.p2DPoint)) {
|
||||||
|
m_lastError = "Missing 3D or 2D point buffer in Position laser data";
|
||||||
|
LOG_ERROR("%s, pointCount=%d, p3D=%p, p2D=%p\n",
|
||||||
|
m_lastError.c_str(),
|
||||||
|
lineData.nPointCount,
|
||||||
|
lineData.p3DPoint,
|
||||||
|
lineData.p2DPoint);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<SVzNLPositionD> scanLine;
|
||||||
|
scanLine.reserve(static_cast<size_t>(lineData.nPointCount));
|
||||||
|
if (linePair.first == keResultDataType_Position) {
|
||||||
|
const SVzNL3DPosition* points3D = static_cast<const SVzNL3DPosition*>(lineData.p3DPoint);
|
||||||
|
const SVzNL2DPosition* points2D = static_cast<const SVzNL2DPosition*>(lineData.p2DPoint);
|
||||||
|
for (int i = 0; i < lineData.nPointCount; ++i) {
|
||||||
|
SVzNLPositionD point;
|
||||||
|
std::memset(&point, 0, sizeof(point));
|
||||||
|
point.nPointIdx = points3D[i].nPointIdx;
|
||||||
|
point.pt3D = points3D[i].pt3D;
|
||||||
|
point.ptLeft2D.x = points2D[i].ptLeft2D.x;
|
||||||
|
point.ptLeft2D.y = points2D[i].ptLeft2D.y;
|
||||||
|
point.ptRight2D.x = points2D[i].ptRight2D.x;
|
||||||
|
point.ptRight2D.y = points2D[i].ptRight2D.y;
|
||||||
|
scanLine.push_back(point);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const SVzNL3DPosition* points3D = static_cast<const SVzNL3DPosition*>(lineData.p3DPoint);
|
||||||
|
const SVzNL2DPositionF* points2D = static_cast<const SVzNL2DPositionF*>(lineData.p2DPoint);
|
||||||
|
for (int i = 0; i < lineData.nPointCount; ++i) {
|
||||||
|
SVzNLPositionD point;
|
||||||
|
std::memset(&point, 0, sizeof(point));
|
||||||
|
point.nPointIdx = points3D[i].nPointIdx;
|
||||||
|
point.pt3D = points3D[i].pt3D;
|
||||||
|
point.ptLeft2D.x = points2D[i].ptLeft2D.x;
|
||||||
|
point.ptLeft2D.y = points2D[i].ptLeft2D.y;
|
||||||
|
point.ptRight2D.x = points2D[i].ptRight2D.x;
|
||||||
|
point.ptRight2D.y = points2D[i].ptRight2D.y;
|
||||||
|
scanLine.push_back(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!scanLine.empty()) {
|
||||||
|
scanLines.push_back(scanLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scanLines.empty()) {
|
||||||
|
m_lastError = "No Position laser data to convert";
|
||||||
|
LOG_ERROR("%s\n", m_lastError.c_str());
|
||||||
|
return ERR_CODE(DATA_ERR_INVALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DEBUG("Converted %zu lines to SVzNLPositionD scan lines format\n", scanLines.size());
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
// 转换统一格式数据为SVzNL3DLaserLine格式
|
// 转换统一格式数据为SVzNL3DLaserLine格式
|
||||||
int LaserDataLoader::ConvertToSVzNL3DLaserLine(const std::vector<std::pair<EVzResultDataType, SVzLaserLineData>>& unifiedData,
|
int LaserDataLoader::ConvertToSVzNL3DLaserLine(const std::vector<std::pair<EVzResultDataType, SVzLaserLineData>>& unifiedData,
|
||||||
std::vector<SVzNL3DLaserLine>& xyzData)
|
std::vector<SVzNL3DLaserLine>& xyzData)
|
||||||
@ -938,8 +1055,9 @@ int LaserDataLoader::ConvertToSVzNL3DLaserLine(const std::vector<std::pair<EVzRe
|
|||||||
EVzResultDataType dataType = linePair.first;
|
EVzResultDataType dataType = linePair.first;
|
||||||
const SVzLaserLineData& lineData = linePair.second;
|
const SVzLaserLineData& lineData = linePair.second;
|
||||||
|
|
||||||
// 只处理Position类型的数据
|
// PositionF 的 3D buffer 也是 SVzNL3DPosition;仅 2D UV 为浮点。
|
||||||
if (dataType == keResultDataType_Position && lineData.p3DPoint) {
|
if ((dataType == keResultDataType_Position ||
|
||||||
|
dataType == keResultDataType_PositionF) && lineData.p3DPoint) {
|
||||||
SVzNL3DLaserLine xyzLine;
|
SVzNL3DLaserLine xyzLine;
|
||||||
xyzLine.nTimeStamp = lineData.llTimeStamp;
|
xyzLine.nTimeStamp = lineData.llTimeStamp;
|
||||||
xyzLine.nPositionCnt = lineData.nPointCount;
|
xyzLine.nPositionCnt = lineData.nPointCount;
|
||||||
@ -1043,10 +1161,36 @@ void LaserDataLoader::FreeConvertedData(std::vector<SVzNLXYZRGBDLaserLine>& rgbd
|
|||||||
|
|
||||||
int LaserDataLoader::_ParseLaserScanPoint(const std::string& data, SVzNL3DPosition& sData, SVzNL2DPosition& s2DData)
|
int LaserDataLoader::_ParseLaserScanPoint(const std::string& data, SVzNL3DPosition& sData, SVzNL2DPosition& s2DData)
|
||||||
{
|
{
|
||||||
float X, Y, Z;
|
float X = 0.0f, Y = 0.0f, Z = 0.0f;
|
||||||
float leftX, leftY;
|
float leftX = 0.0f, leftY = 0.0f;
|
||||||
float rightX, rightY;
|
float rightX = 0.0f, rightY = 0.0f;
|
||||||
sscanf(data.c_str(), "{%f,%f,%f}-{%f,%f}-{%f,%f}", &X, &Y, &Z, &leftX, &leftY, &rightX, &rightY);
|
const int parsed = sscanf(data.c_str(),
|
||||||
|
" { %f , %f , %f } - { %f , %f } - { %f , %f }",
|
||||||
|
&X, &Y, &Z, &leftX, &leftY, &rightX, &rightY);
|
||||||
|
if (parsed != 7) {
|
||||||
|
return ERR_CODE(FILE_ERR_FORMAT);
|
||||||
|
}
|
||||||
|
sData.pt3D.x = X;
|
||||||
|
sData.pt3D.y = Y;
|
||||||
|
sData.pt3D.z = Z;
|
||||||
|
s2DData.ptLeft2D.x = leftX;
|
||||||
|
s2DData.ptLeft2D.y = leftY;
|
||||||
|
s2DData.ptRight2D.x = rightX;
|
||||||
|
s2DData.ptRight2D.y = rightY;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LaserDataLoader::_ParseLaserScanPoint(const std::string& data, SVzNL3DPosition& sData, SVzNL2DPositionF& s2DData)
|
||||||
|
{
|
||||||
|
double X = 0.0, Y = 0.0, Z = 0.0;
|
||||||
|
float leftX = 0.0f, leftY = 0.0f;
|
||||||
|
float rightX = 0.0f, rightY = 0.0f;
|
||||||
|
const int parsed = sscanf(data.c_str(),
|
||||||
|
" { %lf , %lf , %lf } - { %f , %f } - { %f , %f }",
|
||||||
|
&X, &Y, &Z, &leftX, &leftY, &rightX, &rightY);
|
||||||
|
if (parsed != 7) {
|
||||||
|
return ERR_CODE(FILE_ERR_FORMAT);
|
||||||
|
}
|
||||||
sData.pt3D.x = X;
|
sData.pt3D.x = X;
|
||||||
sData.pt3D.y = Y;
|
sData.pt3D.y = Y;
|
||||||
sData.pt3D.z = Z;
|
sData.pt3D.z = Z;
|
||||||
@ -1151,7 +1295,7 @@ int LaserDataLoader::_GetLaserType(const std::string& fileName, EVzResultDataTyp
|
|||||||
eDataType = keResultDataType_PointXYZRGBA;
|
eDataType = keResultDataType_PointXYZRGBA;
|
||||||
bFind = true;
|
bFind = true;
|
||||||
} else if (commaCount >= 2) {
|
} else if (commaCount >= 2) {
|
||||||
// XYZ格式: {x,y,z}-{lx,ly}-{rx,ry}
|
// XYZUV文本格式: {x,y,z}-{lx,ly}-{rx,ry}
|
||||||
eDataType = keResultDataType_Position;
|
eDataType = keResultDataType_Position;
|
||||||
bFind = true;
|
bFind = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1188,7 +1188,8 @@ int PointCloudImageUtils::GenerateDepthImage(
|
|||||||
if (!lineData.p3DPoint || lineData.nPointCount <= 0) continue;
|
if (!lineData.p3DPoint || lineData.nPointCount <= 0) continue;
|
||||||
|
|
||||||
// 根据数据类型处理点云数据
|
// 根据数据类型处理点云数据
|
||||||
if (dataType == keResultDataType_Position) {
|
if (dataType == keResultDataType_Position ||
|
||||||
|
dataType == keResultDataType_PositionF) {
|
||||||
SVzNL3DPosition* positions = static_cast<SVzNL3DPosition*>(lineData.p3DPoint);
|
SVzNL3DPosition* positions = static_cast<SVzNL3DPosition*>(lineData.p3DPoint);
|
||||||
for (int i = 0; i < lineData.nPointCount; i++) {
|
for (int i = 0; i < lineData.nPointCount; i++) {
|
||||||
const SVzNL3DPosition& point = positions[i];
|
const SVzNL3DPosition& point = positions[i];
|
||||||
@ -1250,7 +1251,8 @@ int PointCloudImageUtils::GenerateDepthImage(
|
|||||||
|
|
||||||
if (!lineData.p3DPoint || lineData.nPointCount <= 0) continue;
|
if (!lineData.p3DPoint || lineData.nPointCount <= 0) continue;
|
||||||
|
|
||||||
if (dataType == keResultDataType_Position) {
|
if (dataType == keResultDataType_Position ||
|
||||||
|
dataType == keResultDataType_PositionF) {
|
||||||
SVzNL3DPosition* positions = static_cast<SVzNL3DPosition*>(lineData.p3DPoint);
|
SVzNL3DPosition* positions = static_cast<SVzNL3DPosition*>(lineData.p3DPoint);
|
||||||
for (int i = 0; i < lineData.nPointCount; i++) {
|
for (int i = 0; i < lineData.nPointCount; i++) {
|
||||||
const SVzNL3DPosition& point = positions[i];
|
const SVzNL3DPosition& point = positions[i];
|
||||||
|
|||||||
@ -11,11 +11,15 @@ CloudView.file = CloudView/CloudView.pro
|
|||||||
# 添加子项目
|
# 添加子项目
|
||||||
SUBDIRS += \
|
SUBDIRS += \
|
||||||
VrCommon \
|
VrCommon \
|
||||||
VrUtils \
|
VrUtils
|
||||||
|
|
||||||
|
!equals(TARGET_APP, "ParkingSpaceGuideView") {
|
||||||
|
SUBDIRS += \
|
||||||
CloudUtils \
|
CloudUtils \
|
||||||
DataUtils
|
DataUtils
|
||||||
|
}
|
||||||
|
|
||||||
win32-msvc {
|
win32-msvc:!equals(TARGET_APP, "ParkingSpaceGuideView") {
|
||||||
SUBDIRS += \
|
SUBDIRS += \
|
||||||
CloudView3D \
|
CloudView3D \
|
||||||
CloudView
|
CloudView
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user