Skip to content

Commit 7ccb497

Browse files
author
Louis Fréneau
committed
Improve intermediate map exportation
- Intermediate attribute maps use packed RGB instead of planar
1 parent 62be89b commit 7ccb497

File tree

1 file changed

+76
-40
lines changed

1 file changed

+76
-40
lines changed

src/lib/utils/fileExport.cpp

Lines changed: 76 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,6 @@ namespace {
7070
// {102, 204, 204}
7171
// }};
7272

73-
74-
7573
// NOLINTNEXTLINE(cert-err58-cpp,bugprone-throwing-static-initialization)
7674
const std::array<Vector3<uint8_t>, 114> patchColors = {{
7775
// Red color is for points not being part of a patch before the 2D projection.
@@ -196,6 +194,52 @@ void exportImage(const std::string& filePath, const std::vector<uint8_t>& image,
196194
}
197195
}
198196

197+
void exportImageRepacked(const std::string& filePath, const std::vector<uint8_t>& imagePlanar,
198+
const std::vector<uint8_t>& imagePlanarL2 = {}) {
199+
createDirs(filePath);
200+
201+
const size_t channelSize = imagePlanar.size() / 3;
202+
std::vector<uint8_t> image(3 * channelSize); // Repacked image
203+
for (size_t i = 0; i < channelSize; ++i) {
204+
image[i * 3] = imagePlanar[i];
205+
image[i * 3 + 1] = imagePlanar[i + channelSize];
206+
image[i * 3 + 2] = imagePlanar[i + 2 * channelSize];
207+
}
208+
209+
const std::streamsize streamSize = static_cast<std::streamsize>(image.size());
210+
211+
std::ofstream yuvFile(filePath, std::ios::binary);
212+
if (!yuvFile.is_open()) {
213+
throw std::runtime_error("Unable to open file: " + filePath);
214+
}
215+
216+
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) : lf Accepted for I/O operations
217+
yuvFile.write(reinterpret_cast<const char*>(image.data()), streamSize);
218+
if (!yuvFile) {
219+
throw std::runtime_error("Error while writing to file: " + filePath);
220+
}
221+
222+
if (!imagePlanarL2.empty()) {
223+
std::vector<uint8_t> imageL2(3 * channelSize); // Repacked image
224+
for (size_t i = 0; i < channelSize; ++i) {
225+
imageL2[i * 3] = imagePlanarL2[i];
226+
imageL2[i * 3 + 1] = imagePlanarL2[i + channelSize];
227+
imageL2[i * 3 + 2] = imagePlanarL2[i + 2 * channelSize];
228+
}
229+
230+
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) : lf Accepted for I/O operations
231+
yuvFile.write(reinterpret_cast<const char*>(imageL2.data()), streamSize);
232+
if (!yuvFile) {
233+
throw std::runtime_error("Error while writing L2 to file: " + filePath);
234+
}
235+
}
236+
237+
yuvFile.close();
238+
if (!yuvFile) {
239+
throw std::runtime_error("Error while closing file: " + filePath);
240+
}
241+
}
242+
199243
void exportBitstream(const std::string& filePath, const std::vector<uint8_t>& bitstream) {
200244
createDirs(filePath);
201245
const std::streamsize streamSize = static_cast<std::streamsize>(bitstream.size());
@@ -297,10 +341,10 @@ void exportPointCloudInitialSegmentation(const std::shared_ptr<Frame>& frame, co
297341
exportPointCloud(outputPath, pointsGeometry, attributes);
298342
}
299343

300-
void exportPointCloudSubslices(const std::shared_ptr<Frame>& frame, const std::vector<Vector3<typeGeometryInput>>& pointsGeometry,const std::vector<Vector3<uint8_t>>& attributes,
301-
const std::string& axisStr) {
302-
Logger::log<LogLevel::TRACE>(
303-
"EXPORT FILE", "Export intermediate point cloud after " + axisStr + " axis slicing for frame " + std::to_string(frame->frameId) + ".\n");
344+
void exportPointCloudSubslices(const std::shared_ptr<Frame>& frame, const std::vector<Vector3<typeGeometryInput>>& pointsGeometry,
345+
const std::vector<Vector3<uint8_t>>& attributes, const std::string& axisStr) {
346+
Logger::log<LogLevel::TRACE>("EXPORT FILE", "Export intermediate point cloud after " + axisStr + " axis slicing for frame " +
347+
std::to_string(frame->frameId) + ".\n");
304348

305349
const std::string outputPath = p_->intermediateFilesDir + "/0-" + axisStr + "Slicing/SLICING_" + axisStr + "_f" +
306350
zeroPad(frame->frameNumber, 3) + "_vox" + std::to_string(p_->geoBitDepthVoxelized) + ".ply";
@@ -309,7 +353,7 @@ void exportPointCloudSubslices(const std::shared_ptr<Frame>& frame, const std::v
309353
}
310354

311355
void exportPointCloudPPIAttributionSlicing(const std::shared_ptr<Frame>& frame, const std::vector<Vector3<typeGeometryInput>>& pointsGeometry,
312-
const std::vector<size_t>& pointsPPIs) {
356+
const std::vector<size_t>& pointsPPIs) {
313357
Logger::log<LogLevel::TRACE>(
314358
"EXPORT FILE", "Export intermediate point cloud after refine segmentation for frame " + std::to_string(frame->frameId) + ".\n");
315359

@@ -339,10 +383,10 @@ void exportPointCloudRefineSegmentation(const std::shared_ptr<Frame>& frame, con
339383
}
340384

341385
void exportPointCloudPatchSegmentationColor(const std::shared_ptr<Frame>& frame) {
342-
Logger::log<LogLevel::TRACE>(
343-
"EXPORT FILE", "Export re-colored intermediate point cloud after patch segmentation for frame " + std::to_string(frame->frameId) + ".\n");
344-
const std::string outputPath = p_->intermediateFilesDir + "/05-patchSegmentationColor/PATCH-SEGMENTATION-COLOR_f" + zeroPad(frame->frameNumber, 3) +
345-
"_vox" + std::to_string(p_->geoBitDepthInput) + ".ply";
386+
Logger::log<LogLevel::TRACE>("EXPORT FILE", "Export re-colored intermediate point cloud after patch segmentation for frame " +
387+
std::to_string(frame->frameId) + ".\n");
388+
const std::string outputPath = p_->intermediateFilesDir + "/05-patchSegmentationColor/PATCH-SEGMENTATION-COLOR_f" +
389+
zeroPad(frame->frameNumber, 3) + "_vox" + std::to_string(p_->geoBitDepthInput) + ".ply";
346390

347391
std::vector<Vector3<uint8_t>> attributes(frame->pointsGeometry.size());
348392
std::vector<bool> pointColored(frame->pointsGeometry.size(), false);
@@ -381,18 +425,16 @@ void exportPointCloudPatchSegmentationColor(const std::shared_ptr<Frame>& frame)
381425
}
382426

383427
void exportPointCloudPatchSegmentationBorder(const std::shared_ptr<Frame>& frame) {
384-
Logger::log<LogLevel::TRACE>(
385-
"EXPORT FILE", "Export intermediate point cloud with patch border after patch segmentation for frame " +
386-
std::to_string(frame->frameId) + ".\n");
428+
Logger::log<LogLevel::TRACE>("EXPORT FILE", "Export intermediate point cloud with patch border after patch segmentation for frame " +
429+
std::to_string(frame->frameId) + ".\n");
387430

388-
const std::string outputPath = p_->intermediateFilesDir +
389-
"/05-patchSegmentationBorder/PATCH-SEGMENTATION-BORDER_f" +
390-
zeroPad(frame->frameNumber, 3) + "_vox" + std::to_string(p_->geoBitDepthInput) + ".ply";
431+
const std::string outputPath = p_->intermediateFilesDir + "/05-patchSegmentationBorder/PATCH-SEGMENTATION-BORDER_f" +
432+
zeroPad(frame->frameNumber, 3) + "_vox" + std::to_string(p_->geoBitDepthInput) + ".ply";
391433

392434
std::vector<Vector3<uint8_t>> attributes(frame->pointsGeometry.size());
393435
std::vector<bool> pointColored(frame->pointsGeometry.size(), false);
394436

395-
const Vector3<uint8_t> borderColor = {42, 85, 185}; // couleur pour les bords
437+
const Vector3<uint8_t> borderColor = {42, 85, 185}; // couleur pour les bords
396438

397439
for (const auto& patch : frame->patchList) {
398440
const auto color = patchColors[patch.patchIndex_ % patchColors.size()];
@@ -412,13 +454,12 @@ void exportPointCloudPatchSegmentationBorder(const std::shared_ptr<Frame>& frame
412454
isBorder = true;
413455
} else {
414456
// Vérifie si un voisin a une valeur vide
415-
const int du[4] = { -1, 1, 0, 0 };
416-
const int dv[4] = { 0, 0, -1, 1 };
457+
const int du[4] = {-1, 1, 0, 0};
458+
const int dv[4] = {0, 0, -1, 1};
417459
for (int k = 0; k < 4; ++k) {
418460
int uu = static_cast<int>(u) + du[k];
419461
int vv = static_cast<int>(v) + dv[k];
420-
if (uu < 0 || vv < 0 || uu >= static_cast<int>(width) || vv >= static_cast<int>(height))
421-
continue;
462+
if (uu < 0 || vv < 0 || uu >= static_cast<int>(width) || vv >= static_cast<int>(height)) continue;
422463
const size_t neighborPos = vv * width + uu;
423464
if (patch.depthL1_[neighborPos] == g_infiniteDepth) {
424465
isBorder = true;
@@ -455,18 +496,17 @@ void exportPointCloudPatchSegmentationBorder(const std::shared_ptr<Frame>& frame
455496
}
456497

457498
void exportPointCloudPatchSegmentationBorderBlank(const std::shared_ptr<Frame>& frame) {
458-
Logger::log<LogLevel::TRACE>(
459-
"EXPORT FILE", "Export intermediate point cloud with patch border (blank) after patch segmentation for frame " +
460-
std::to_string(frame->frameId) + ".\n");
499+
Logger::log<LogLevel::TRACE>("EXPORT FILE",
500+
"Export intermediate point cloud with patch border (blank) after patch segmentation for frame " +
501+
std::to_string(frame->frameId) + ".\n");
461502

462-
const std::string outputPath = p_->intermediateFilesDir +
463-
"/05-patchSegmentationBorderBlank/PATCH-SEGMENTATION-BORDER-BLANK_f" +
464-
zeroPad(frame->frameNumber, 3) + "_vox" + std::to_string(p_->geoBitDepthInput) + ".ply";
503+
const std::string outputPath = p_->intermediateFilesDir + "/05-patchSegmentationBorderBlank/PATCH-SEGMENTATION-BORDER-BLANK_f" +
504+
zeroPad(frame->frameNumber, 3) + "_vox" + std::to_string(p_->geoBitDepthInput) + ".ply";
465505

466506
std::vector<Vector3<uint8_t>> attributes(frame->pointsGeometry.size());
467507
std::vector<bool> pointColored(frame->pointsGeometry.size(), false);
468508

469-
const Vector3<uint8_t> borderColor = {42, 85, 185}; // couleur pour les bords
509+
const Vector3<uint8_t> borderColor = {42, 85, 185}; // couleur pour les bords
470510

471511
for (const auto& patch : frame->patchList) {
472512
const auto color = patchColors[patch.patchIndex_ % patchColors.size()];
@@ -486,13 +526,12 @@ void exportPointCloudPatchSegmentationBorderBlank(const std::shared_ptr<Frame>&
486526
isBorder = true;
487527
} else {
488528
// Vérifie si un voisin a une valeur vide
489-
const int du[4] = { -1, 1, 0, 0 };
490-
const int dv[4] = { 0, 0, -1, 1 };
529+
const int du[4] = {-1, 1, 0, 0};
530+
const int dv[4] = {0, 0, -1, 1};
491531
for (int k = 0; k < 4; ++k) {
492532
int uu = static_cast<int>(u) + du[k];
493533
int vv = static_cast<int>(v) + dv[k];
494-
if (uu < 0 || vv < 0 || uu >= static_cast<int>(width) || vv >= static_cast<int>(height))
495-
continue;
534+
if (uu < 0 || vv < 0 || uu >= static_cast<int>(width) || vv >= static_cast<int>(height)) continue;
496535
const size_t neighborPos = vv * width + uu;
497536
if (patch.depthL1_[neighborPos] == g_infiniteDepth) {
498537
isBorder = true;
@@ -527,7 +566,6 @@ void exportPointCloudPatchSegmentationBorderBlank(const std::shared_ptr<Frame>&
527566
exportPointCloud(outputPath, frame->pointsGeometry, attributes);
528567
}
529568

530-
531569
void exportImageOccupancy(const std::shared_ptr<Frame>& frame) {
532570
Logger::log<LogLevel::TRACE>("EXPORT FILE", "Export intermediate occupancy map for frame " + std::to_string(frame->frameId) + ".\n");
533571

@@ -590,9 +628,9 @@ void exportImageAttribute(const std::shared_ptr<Frame>& frame) {
590628
const std::string outputPath = p_->intermediateFilesDir + "/08-attribute/ATTRIBUTE_f" + zeroPad(frame->frameNumber, 3) + "_RGB444_" +
591629
std::to_string(p_->mapWidth) + "x" + std::to_string(frame->mapHeight) + ".rgb";
592630
if (p_->doubleLayer) {
593-
exportImage(outputPath, frame->attributeMapL1, frame->attributeMapL2);
631+
exportImageRepacked(outputPath, frame->attributeMapL1, frame->attributeMapL2);
594632
} else {
595-
exportImage(outputPath, frame->attributeMapL1);
633+
exportImageRepacked(outputPath, frame->attributeMapL1);
596634
}
597635
}
598636

@@ -668,10 +706,9 @@ void exportGeometryBitstream(const std::shared_ptr<uvgvpcc_enc::GOF>& gof, const
668706
exportBitstream(outputPath, bitstream);
669707
}
670708

671-
//TODO(lf): currently the file is open and close for every log line...
709+
// TODO(lf): currently the file is open and close for every log line...
672710
void exportAtlasInformation(const size_t& gofId, const std::string& logLine) {
673-
const std::string filePath = p_->intermediateFilesDir +
674-
"/16-atlasInformation/ATLAS_g" + zeroPad(gofId, 3) + ".txt";
711+
const std::string filePath = p_->intermediateFilesDir + "/16-atlasInformation/ATLAS_g" + zeroPad(gofId, 3) + ".txt";
675712

676713
createDirs(filePath);
677714

@@ -691,5 +728,4 @@ void exportAtlasInformation(const size_t& gofId, const std::string& logLine) {
691728
}
692729
}
693730

694-
695731
} // namespace FileExport

0 commit comments

Comments
 (0)