B2G 文件(例如 BLK2GO、BLK2FLY 和 BLK ARC)可以在不先导入文件的情况下处理成 E57。
说明
- 当用户直接把 .b2g 数据作为 E57 导入时,不会应用 Cyclone REGISTER 360 的设置。
- 相反,CLI 使用上一次 BLK 导入的设置进行处理,因此需要先设置好这些参数。
- 使用此命令需要 Cyclone WORKFLOW 许可证。
这些导出的 E57 文件包含:
- 主点云。
- 另一个点云,以点的方式表示轨迹。
- 所有 Pano 影像的位置。
- 沿轨迹的所有 Pano 影像朝向。
- 沿轨迹逐点的法线计算。
- 可将校正影像导出到 E57 文件的选项。
- 这些影像可用于在特定应用中帮助把影像与点云对齐。
- 在 CMD Windows 程序的命令行末尾会加上
recimage。 - 可设置 WayPoint 间隔的选项:
interval=(n),n 为以米为单位的距离。- 示例:
interval=10,这将每隔 10 米创建一个 WayPoint。
- 示例:
- 可根据 GeoTags 创建 WayPoints 的选项:
- 命令为:
geotag-waypoints - 使用此命令将为野外采集的每一张细节影像添加 GeoTags。
工作流与用法:
- 打开 Cyclone REGISTER 360 PLUS。
- 创建一个项目。
- 将任意 B2G 文件拖放到 Cyclone REGISTER 360 PLUS 的导入区域。
- 沿轨迹设置所需的 WayPoint(Pano sphere)创建间隔(右下方面板)。
- 关闭 Cyclone REGISTER 360 PLUS(不要导入数据)。
- 打开一个 CMD 窗口。
- 将路径设置为 Cyclone REGISTER 360 PLUS 的安装目录。
- 输入以下命令:
Register360.exe -b2g2trajectory [b2g directory] [export directory]。- CLI 会把 B2G 处理为 E57 文件。
以下是一个示例输出,展示了从 XML 输出中导出的 E57 对象。请查看 http://www.libe57.org 了解 E57 编码标准:
// into the E57 header goes e57CameraToPano, the "solution"
Eigen::Quaterniond rot(e57CameraToPano.rotation());
imageHeader.pose.rotation.w = rot.w();
imageHeader.pose.rotation.x = rot.x();
imageHeader.pose.rotation.y = rot.y();
imageHeader.pose.rotation.z = rot.z();
imageHeader.pose.translation.x = e57CameraToPano.translation().x();
imageHeader.pose.translation.y = e57CameraToPano.translation().y();
imageHeader.pose.translation.z = e57CameraToPano.translation().z();
// Setup the Name and Description
imageHeader.name= e57::ustring(pImageName);
imageHeader.description = e57::ustring("");
// the image gets its own GUID
String guidStr;
guidStr.Printf(32, "%.16llx", scanId);// Writes 16 hex digits for an 64-bit type
imageHeader.guid = guidStr.c_str();
imageHeader.associatedData3DGuid = mAssociatedData3DGuid.c_str(); // image is associated its scan via the scan's GUID
// Setup the DateTime imageHeader.acquisitionDateTime.SetCurrentGPSTime(); //set current time.
imageHeader.sensorModel = "CycloneRegister360";
// Setup image size
if (!isPanoramic)
{
const double pixel_size = 6.0e-6; // 6 micro-meter (arbitrarily picked number)
imageHeader.pinholeRepresentation.jpegImageSize = compressedSize;
imageHeader.pinholeRepresentation.pngImageSize = 0;
imageHeader.pinholeRepresentation.imageMaskSize = 0;
imageHeader.pinholeRepresentation.imageWidth = (int32_t)width;
imageHeader.pinholeRepresentation.imageHeight = (int32_t)height;
imageHeader.pinholeRepresentation.focalLength = focalInPixels * pixel_size;
imageHeader.pinholeRepresentation.pixelWidth = 1.0 * pixel_size;
imageHeader.pinholeRepresentation.pixelHeight = 1.0 * pixel_size;
imageHeader.pinholeRepresentation.principalPointX = *pCenterInPixels;
imageHeader.pinholeRepresentation.principalPointY = *(pCenterInPixels + 1);
}
else
{
imageHeader.sphericalRepresentation.jpegImageSize = compressedSize;
imageHeader.sphericalRepresentation.pngImageSize = 0;
imageHeader.sphericalRepresentation.imageMaskSize = 0;
imageHeader.sphericalRepresentation.imageWidth = (int32_t)width;
imageHeader.sphericalRepresentation.imageHeight = (int32_t)height;
imageHeader.sphericalRepresentation.pixelWidth = 2.0 * PI / width;
imageHeader.sphericalRepresentation.pixelHeight = 1.0 * PI / height;
}
try
{
// Write the image header
int32_t imageIndex = mpE57Writer->NewImage2D(imageHeader);
// Write the JPEG data
int64_t rVal = mpE57Writer->WriteImage2DData(imageIndex, e57::E57_JPEG_IMAGE,
isPanoramic ? e57::E57_SPHERICAL : e57::E57_PINHOLE,
(void*)pCompressedData, 0, compressedSize);
}