2023 B2G to E57
B2G files such as BLK2GO, BLK2FLY, and BLK ARC can be processed into an E57 without importing the file first. However, the CLI uses settings from the last BLK import for processing, so these need to be set first in Cyclone REGISTER 360. A Cyclone WORKFLOW license is required to use this command.
These exported E57 files contain:
The main point cloud.
Another point cloud represents the trajectory as points.
All Pano image locations.
All Pano image orientations along the trajectory.
Normal calculations per point along the trajectory.
Option to export rectified images to the E57 file.
These images can be used to help align images to the point cloud for certain applications.
recimage and is added to the end of the command line inside of the CMD windows program.
Option to set WayPoint interval.
interval=(n), n being the distance in meters.
Example: interval=10, this would create a WayPoint every 10 meters.
Option to create WayPoints from GeoTags
The command is: geotag-waypoints
Using this command will add GeoTags for every detailed image captured in the field.
Workflow and usage:
Open Cyclone REGISTER 360 PLUS.
Create a project.
Drag and drop any B2G file in the Import area of Cyclone REGISTER 360 PLUS.
Set the desired Waypoint (Pano sphere) creation interval along the trajectory (lower right pane).
Close Cyclone REGISTER 360 PLUS, (do not import the data).
Open up a CMD window.
Set the path to the install directory of Cyclone REGISTER 360 PLUS.
Type in the following commands:
Register360.exe -b2g2trajectory [b2g directory] [export directory].
The CLI will process the B2G into an E57 file.
Here is an example output showing the exported objects in the E57 from an XML output. Please review http://www.libe57.org for E57 coding standards:
// 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 is 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);
}