Commit 3c9e671c authored by Valery Valentin's avatar Valery Valentin Committed by David Flynn
Browse files

attr/m46188: decimation based LoD generation

This LoD generation (subsampling) method uses the Morton-based ordering
of points that is used to determine prediction neighbours.  Each LoD
level comprises 3/4 of the points of the previous.
parent 05526a18
......@@ -33,9 +33,10 @@ categories:
- positionQuantizationScaleAdjustsDist2: 1
- dist2: ${seq_dist2}
- lodBinaryTree: 0
- lodDecimation: 0
-
- !conditional '"${group}" =~ m{^cat3}'
- lodBinaryTree: 1
- lodDecimation: 1
##
# attribute coding -- reflectance
......
......@@ -42,9 +42,10 @@ categories:
- positionQuantizationScaleAdjustsDist2: 1
- dist2: ${seq_dist2}
- lodBinaryTree: 0
- lodDecimation: 0
-
- !conditional '"${group}" =~ m{^cat3}'
- lodBinaryTree: 1
- lodDecimation: 1
##
# attribute coding -- reflectance
......
......@@ -33,9 +33,10 @@ categories:
- numberOfNearestNeighborsInPrediction: 3
- levelOfDetailCount: ${seq_lod}
- lodBinaryTree: 0
- lodDecimation: 0
-
- !conditional '"${group}" =~ m{^cat3}'
- lodBinaryTree: 1
- lodDecimation: 1
- positionQuantizationScaleAdjustsDist2: 1
- dist2: ${seq_dist2}
......
......@@ -254,6 +254,14 @@ Range for nearest neighbour search.
Maximum number of nearest neighbour candidates used in direct
attribute prediction.
### `--lodDecimation=0|1`
Controls the level-of-detail generation method:
| Value | Description |
|:-----:| ------------------------------- |
| 0 | Euclidean distance thresholding |
| 1 | Decimation by 1:3 |
### `--levelOfDetailCount=INT-VALUE`
Attribute's number of levels of detail.
......
......@@ -277,9 +277,10 @@ AttributeDecoder::decodeReflectancesPred(
predictors, indexesLOD);
} else {
buildPredictorsFast(
pointCloud, aps.dist2, aps.num_detail_levels,
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range,
predictors, numberOfPointsPerLOD, indexesLOD);
pointCloud, aps.lod_decimation_enabled_flag, aps.dist2,
aps.num_detail_levels, aps.num_pred_nearest_neighbours,
aps.search_range, aps.search_range, predictors, numberOfPointsPerLOD,
indexesLOD);
}
} else {
buildLevelOfDetailBinaryTree(pointCloud, numberOfPointsPerLOD, indexesLOD);
......@@ -373,9 +374,10 @@ AttributeDecoder::decodeColorsPred(
predictors, indexesLOD);
} else {
buildPredictorsFast(
pointCloud, aps.dist2, aps.num_detail_levels,
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range,
predictors, numberOfPointsPerLOD, indexesLOD);
pointCloud, aps.lod_decimation_enabled_flag, aps.dist2,
aps.num_detail_levels, aps.num_pred_nearest_neighbours,
aps.search_range, aps.search_range, predictors, numberOfPointsPerLOD,
indexesLOD);
}
} else {
buildLevelOfDetailBinaryTree(pointCloud, numberOfPointsPerLOD, indexesLOD);
......@@ -576,9 +578,9 @@ AttributeDecoder::decodeColorsLift(
if (!aps.lod_binary_tree_enabled_flag) {
buildPredictorsFast(
pointCloud, aps.dist2, aps.num_detail_levels,
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range,
predictors, numberOfPointsPerLOD, indexesLOD);
pointCloud, aps.lod_decimation_enabled_flag, aps.dist2,
aps.num_detail_levels, aps.num_pred_nearest_neighbours, aps.search_range,
aps.search_range, predictors, numberOfPointsPerLOD, indexesLOD);
} else {
buildLevelOfDetailBinaryTree(pointCloud, numberOfPointsPerLOD, indexesLOD);
computePredictors(
......@@ -659,9 +661,9 @@ AttributeDecoder::decodeReflectancesLift(
if (!aps.lod_binary_tree_enabled_flag) {
buildPredictorsFast(
pointCloud, aps.dist2, aps.num_detail_levels,
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range,
predictors, numberOfPointsPerLOD, indexesLOD);
pointCloud, aps.lod_decimation_enabled_flag, aps.dist2,
aps.num_detail_levels, aps.num_pred_nearest_neighbours, aps.search_range,
aps.search_range, predictors, numberOfPointsPerLOD, indexesLOD);
} else {
buildLevelOfDetailBinaryTree(pointCloud, numberOfPointsPerLOD, indexesLOD);
computePredictors(
......
......@@ -482,9 +482,10 @@ AttributeEncoder::encodeReflectancesPred(
predictors, indexesLOD);
} else {
buildPredictorsFast(
pointCloud, aps.dist2, aps.num_detail_levels,
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range,
predictors, numberOfPointsPerLOD, indexesLOD);
pointCloud, aps.lod_decimation_enabled_flag, aps.dist2,
aps.num_detail_levels, aps.num_pred_nearest_neighbours,
aps.search_range, aps.search_range, predictors, numberOfPointsPerLOD,
indexesLOD);
}
} else {
buildLevelOfDetailBinaryTree(pointCloud, numberOfPointsPerLOD, indexesLOD);
......@@ -679,9 +680,10 @@ AttributeEncoder::encodeColorsPred(
predictors, indexesLOD);
} else {
buildPredictorsFast(
pointCloud, aps.dist2, aps.num_detail_levels,
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range,
predictors, numberOfPointsPerLOD, indexesLOD);
pointCloud, aps.lod_decimation_enabled_flag, aps.dist2,
aps.num_detail_levels, aps.num_pred_nearest_neighbours,
aps.search_range, aps.search_range, predictors, numberOfPointsPerLOD,
indexesLOD);
}
} else {
buildLevelOfDetailBinaryTree(pointCloud, numberOfPointsPerLOD, indexesLOD);
......@@ -969,9 +971,9 @@ AttributeEncoder::encodeColorsLift(
if (!aps.lod_binary_tree_enabled_flag) {
buildPredictorsFast(
pointCloud, aps.dist2, aps.num_detail_levels,
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range,
predictors, numberOfPointsPerLOD, indexesLOD);
pointCloud, aps.lod_decimation_enabled_flag, aps.dist2,
aps.num_detail_levels, aps.num_pred_nearest_neighbours, aps.search_range,
aps.search_range, predictors, numberOfPointsPerLOD, indexesLOD);
} else {
buildLevelOfDetailBinaryTree(pointCloud, numberOfPointsPerLOD, indexesLOD);
computePredictors(
......@@ -1074,9 +1076,9 @@ AttributeEncoder::encodeReflectancesLift(
if (!aps.lod_binary_tree_enabled_flag) {
buildPredictorsFast(
pointCloud, aps.dist2, aps.num_detail_levels,
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range,
predictors, numberOfPointsPerLOD, indexesLOD);
pointCloud, aps.lod_decimation_enabled_flag, aps.dist2,
aps.num_detail_levels, aps.num_pred_nearest_neighbours, aps.search_range,
aps.search_range, predictors, numberOfPointsPerLOD, indexesLOD);
} else {
buildLevelOfDetailBinaryTree(pointCloud, numberOfPointsPerLOD, indexesLOD);
computePredictors(
......
......@@ -579,7 +579,7 @@ computeNearestNeighbors(
//---------------------------------------------------------------------------
inline void
subsample(
subsampleByDistance(
const PCCPointSet3& pointCloud,
const std::vector<MortonCodeWithIndex>& packedVoxel,
const std::vector<uint32_t>& input,
......@@ -613,6 +613,44 @@ subsample(
//---------------------------------------------------------------------------
inline void
subsampleByDecimation(
const std::vector<uint32_t>& input,
std::vector<uint32_t>& retained,
std::vector<uint32_t>& indexes)
{
static const int kLodUniformQuant = 4;
const int indexCount = int(input.size());
for (int i = 0; i < indexCount; ++i) {
if (i % kLodUniformQuant == 0)
retained.push_back(input[i]);
else
indexes.push_back(input[i]);
}
}
//---------------------------------------------------------------------------
inline void
subsample(
bool useDecimation,
const PCCPointSet3& pointCloud,
const std::vector<MortonCodeWithIndex>& packedVoxel,
const std::vector<uint32_t>& input,
const double radius2,
const int32_t searchRange,
std::vector<uint32_t>& retained,
std::vector<uint32_t>& indexes)
{
if (useDecimation)
subsampleByDecimation(input, retained, indexes);
else
subsampleByDistance(
pointCloud, packedVoxel, input, radius2, searchRange, retained, indexes);
}
//---------------------------------------------------------------------------
inline void
computeMortonCodes(
const PCCPointSet3& pointCloud,
......@@ -799,6 +837,7 @@ computePredictors(
inline void
buildPredictorsFast(
const PCCPointSet3& pointCloud,
bool lod_decimation_enabled_flag,
const std::vector<int64_t>& dist2,
const int32_t levelOfDetailCount,
const int32_t numberOfNearestNeighborsInPrediction,
......@@ -843,8 +882,8 @@ buildPredictorsFast(
} else {
const double radius2 = dist2[lodIndex];
subsample(
pointCloud, packedVoxel, input, radius2, searchRange1, retained,
indexes);
lod_decimation_enabled_flag, pointCloud, packedVoxel, input, radius2,
searchRange1, retained, indexes);
}
const int32_t endIndex = indexes.size();
......
......@@ -430,6 +430,12 @@ ParseParameters(int argc, char* argv[], Parameters& params)
" 0: distance based subsampling\n"
" 1: binary tree")
("lodDecimation",
params_attr.aps.lod_decimation_enabled_flag, false,
"Controls LoD generation method:\n"
" 0: distance based subsampling\n"
" 1: decimation by 1:3")
("max_num_direct_predictors",
params_attr.aps.max_num_direct_predictors, 3,
"Maximum number of nearest neighbour candidates used in direct"
......
......@@ -233,6 +233,7 @@ struct AttributeParameterSet {
//--- lifting/predicting transform parameters
bool lod_binary_tree_enabled_flag;
bool lod_decimation_enabled_flag;
int num_pred_nearest_neighbours;
int max_num_direct_predictors;
int adaptive_prediction_threshold;
......
......@@ -262,6 +262,7 @@ write(const AttributeParameterSet& aps)
bs.writeUe(aps.num_pred_nearest_neighbours);
bs.writeUe(aps.max_num_direct_predictors);
bs.writeUe(aps.search_range);
bs.write(aps.lod_decimation_enabled_flag);
bs.write(aps.lod_binary_tree_enabled_flag);
bs.writeUe(aps.num_detail_levels);
......@@ -311,6 +312,7 @@ parseAps(const PayloadBuffer& buf)
bs.readUe(&aps.num_pred_nearest_neighbours);
bs.readUe(&aps.max_num_direct_predictors);
bs.readUe(&aps.search_range);
bs.read(&aps.lod_decimation_enabled_flag);
bs.read(&aps.lod_binary_tree_enabled_flag);
aps.num_detail_levels = int(bs.readUe());
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment