Commit 51f455d0 authored by Khaled Mammou's avatar Khaled Mammou Committed by David Flynn
Browse files

m42634/attr: do not vary per point the number of neighbours for prediction

This commit uses a constant (per attribute) number of neighbours in
point attribute prediction, replacing a method where the encoder searches
for an optimal number and signals this on a per point basis.

Extracted-from: http://wg11.sc29.org/svn/repos/MPEG-I/Part5-PointCloudCompression/CE/CE0/CE0.1/trunk@1357


Reintegrated-by: David Flynn's avatar <dflynn@blackberry.com>
parent 796c7578
...@@ -109,6 +109,9 @@ struct PCCPredictor { ...@@ -109,6 +109,9 @@ struct PCCPredictor {
void computeWeights(const size_t neighborCount0) { void computeWeights(const size_t neighborCount0) {
neighborCount = std::min(neighborCount0, maxNeighborCount); neighborCount = std::min(neighborCount0, maxNeighborCount);
if (!neighborCount) {
return;
}
double sum = 0.0; double sum = 0.0;
for (size_t n = 0; n < neighborCount; ++n) { for (size_t n = 0; n < neighborCount; ++n) {
neighbors[n].weight = neighbors[n].invDistance; neighbors[n].weight = neighbors[n].invDistance;
......
...@@ -225,8 +225,7 @@ class PCCTMC3Decoder3 { ...@@ -225,8 +225,7 @@ class PCCTMC3Decoder3 {
} }
} }
int decodeReflectances(PCCBitstream &bitstream, PCCPointSet3 &pointCloud) { int decodeReflectances(PCCBitstream &bitstream, PCCPointSet3 &pointCloud) {
const size_t pointCount = pointCloud.getPointCount(); const size_t pointCount = predictors.size();
assert(pointCount == predictors.size());
uint32_t compressedBitstreamSize = 0; uint32_t compressedBitstreamSize = 0;
PCCReadFromBuffer<uint32_t>(bitstream.buffer, compressedBitstreamSize, bitstream.size); PCCReadFromBuffer<uint32_t>(bitstream.buffer, compressedBitstreamSize, bitstream.size);
...@@ -250,28 +249,20 @@ class PCCTMC3Decoder3 { ...@@ -250,28 +249,20 @@ class PCCTMC3Decoder3 {
bitstream.buffer + bitstream.size); bitstream.buffer + bitstream.size);
arithmeticDecoder.start_decoder(); arithmeticDecoder.start_decoder();
o3dgc::Static_Bit_Model binaryModel0; o3dgc::Static_Bit_Model binaryModel0;
o3dgc::Adaptive_Data_Model neighborCountModel;
neighborCountModel.set_alphabet(uint32_t(numberOfNearestNeighborsInPrediction));
for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) { for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) {
auto &predictor = predictors[predictorIndex]; auto &predictor = predictors[predictorIndex];
uint16_t &reflectance = pointCloud.getReflectance(predictor.index); uint16_t &reflectance = pointCloud.getReflectance(predictor.index);
if (!predictor.neighborCount) { const size_t lodIndex = predictor.levelOfDetailIndex;
reflectance = decodeAbsUInt32(16, arithmeticDecoder, binaryModel0); const int64_t qs = quantizationSteps[lodIndex];
} else { const uint32_t attValue0 = decodeDiff0UInt32(
const size_t neighborCount = arithmeticDecoder.decode(neighborCountModel) + 1; maxAttributeValueDiff0, adaptiveDataModelAlphabetSizeDiff0, arithmeticDecoder,
predictor.computeWeights(neighborCount); multiSymbolModelDiff0, binaryModelDiff0, binaryModel0);
const size_t lodIndex = predictor.levelOfDetailIndex; const int64_t quantPredAttValue = predictor.predictReflectance(pointCloud);
const int64_t qs = quantizationSteps[lodIndex]; const int64_t delta = PCCInverseQuantization(o3dgc::UIntToInt(attValue0), qs);
const uint32_t attValue0 = decodeDiff0UInt32( const int64_t reconstructedQuantAttValue = quantPredAttValue + delta;
maxAttributeValueDiff0, adaptiveDataModelAlphabetSizeDiff0, arithmeticDecoder, reflectance = uint16_t(PCCClip(reconstructedQuantAttValue, int64_t(0),
multiSymbolModelDiff0, binaryModelDiff0, binaryModel0); int64_t(std::numeric_limits<uint16_t>::max())));
const int64_t quantPredAttValue = predictor.predictReflectance(pointCloud);
const int64_t delta = PCCInverseQuantization(o3dgc::UIntToInt(attValue0), qs);
const int64_t reconstructedQuantAttValue = quantPredAttValue + delta;
reflectance = uint16_t(PCCClip(reconstructedQuantAttValue, int64_t(0),
int64_t(std::numeric_limits<uint16_t>::max())));
}
} }
arithmeticDecoder.stop_decoder(); arithmeticDecoder.stop_decoder();
bitstream.size += compressedBitstreamSize; bitstream.size += compressedBitstreamSize;
...@@ -279,8 +270,7 @@ class PCCTMC3Decoder3 { ...@@ -279,8 +270,7 @@ class PCCTMC3Decoder3 {
} }
int decodeColors(PCCBitstream &bitstream, PCCPointSet3 &pointCloud) { int decodeColors(PCCBitstream &bitstream, PCCPointSet3 &pointCloud) {
const size_t pointCount = pointCloud.getPointCount(); const size_t pointCount = predictors.size();
assert(pointCount == predictors.size());
uint32_t compressedBitstreamSize = 0; uint32_t compressedBitstreamSize = 0;
PCCReadFromBuffer<uint32_t>(bitstream.buffer, compressedBitstreamSize, bitstream.size); PCCReadFromBuffer<uint32_t>(bitstream.buffer, compressedBitstreamSize, bitstream.size);
...@@ -322,53 +312,48 @@ class PCCTMC3Decoder3 { ...@@ -322,53 +312,48 @@ class PCCTMC3Decoder3 {
bitstream.buffer + bitstream.size); bitstream.buffer + bitstream.size);
arithmeticDecoder.start_decoder(); arithmeticDecoder.start_decoder();
o3dgc::Static_Bit_Model binaryModel0; o3dgc::Static_Bit_Model binaryModel0;
o3dgc::Adaptive_Data_Model neighborCountModel;
neighborCountModel.set_alphabet(uint32_t(numberOfNearestNeighborsInPrediction));
for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) { for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) {
auto &predictor = predictors[predictorIndex]; auto &predictor = predictors[predictorIndex];
PCCColor3B &color = pointCloud.getColor(predictor.index); PCCColor3B &color = pointCloud.getColor(predictor.index);
if (!predictor.neighborCount) { const PCCColor3B predictedColor = predictor.predictColor(pointCloud);
for (size_t k = 0; k < 3; ++k) { const size_t lodIndex = predictor.levelOfDetailIndex;
color[k] = decodeAbsUInt32(8, arithmeticDecoder, binaryModel0); const int64_t qs = quantizationSteps[lodIndex];
} const uint32_t attValue0 = decodeDiff0UInt32(
} else { maxAttributeValueDiff0, adaptiveDataModelAlphabetSizeDiff0, arithmeticDecoder,
const size_t neighborCount = arithmeticDecoder.decode(neighborCountModel) + 1; multiSymbolModelDiff0, binaryModelDiff0, binaryModel0);
predictor.computeWeights(neighborCount); const uint32_t modelIndex = (attValue0 < PCCTMC3Diff1AdaptiveDataModelCount)
const PCCColor3B predictedColor = predictor.predictColor(pointCloud); ? attValue0
const size_t lodIndex = predictor.levelOfDetailIndex; : PCCTMC3Diff1AdaptiveDataModelCount - 1;
const int64_t qs = quantizationSteps[lodIndex]; const int64_t quantPredAttValue = predictedColor[0];
const uint32_t attValue0 = decodeDiff0UInt32( const int64_t delta = PCCInverseQuantization(o3dgc::UIntToInt(attValue0), qs);
maxAttributeValueDiff0, adaptiveDataModelAlphabetSizeDiff0, arithmeticDecoder, const int64_t reconstructedQuantAttValue = quantPredAttValue + delta;
multiSymbolModelDiff0, binaryModelDiff0, binaryModel0); color[0] = uint8_t(PCCClip(reconstructedQuantAttValue, int64_t(0), int64_t(255)));
const uint32_t modelIndex = (attValue0 < PCCTMC3Diff1AdaptiveDataModelCount)
? attValue0 for (size_t k = 1; k < 3; ++k) {
: PCCTMC3Diff1AdaptiveDataModelCount - 1; const uint32_t attValue = decodeDiff1UInt32(
const int64_t quantPredAttValue = predictedColor[0]; modelIndex, maxAttributeValueDiff1, adaptiveDataModelAlphabetSizeDiff1,
const int64_t delta = PCCInverseQuantization(o3dgc::UIntToInt(attValue0), qs); arithmeticDecoder, multiSymbolModelDiff1, binaryModelDiff1, binaryModel0);
const int64_t quantPredAttValue = predictedColor[k];
const int64_t delta = PCCInverseQuantization(o3dgc::UIntToInt(attValue), qs);
const int64_t reconstructedQuantAttValue = quantPredAttValue + delta; const int64_t reconstructedQuantAttValue = quantPredAttValue + delta;
color[0] = uint8_t(PCCClip(reconstructedQuantAttValue, int64_t(0), int64_t(255))); color[k] = uint8_t(PCCClip(reconstructedQuantAttValue, int64_t(0), int64_t(255)));
for (size_t k = 1; k < 3; ++k) {
const uint32_t attValue = decodeDiff1UInt32(
modelIndex, maxAttributeValueDiff1, adaptiveDataModelAlphabetSizeDiff1,
arithmeticDecoder, multiSymbolModelDiff1, binaryModelDiff1, binaryModel0);
const int64_t quantPredAttValue = predictedColor[k];
const int64_t delta = PCCInverseQuantization(o3dgc::UIntToInt(attValue), qs);
const int64_t reconstructedQuantAttValue = quantPredAttValue + delta;
color[k] = uint8_t(PCCClip(reconstructedQuantAttValue, int64_t(0), int64_t(255)));
}
} }
} }
arithmeticDecoder.stop_decoder(); arithmeticDecoder.stop_decoder();
bitstream.size += compressedBitstreamSize; bitstream.size += compressedBitstreamSize;
return 0; return 0;
} }
void buildPredictors(const PCCPointSet3 &pointCloud) { void buildPredictors(const PCCPointSet3 &pointCloud) {
std::vector<uint32_t> numberOfPointsPerLOD; std::vector<uint32_t> numberOfPointsPerLOD;
std::vector<uint32_t> indexes; std::vector<uint32_t> indexes;
PCCBuildPredictors(pointCloud, numberOfNearestNeighborsInPrediction, levelOfDetailCount, dist2, PCCBuildPredictors(pointCloud, numberOfNearestNeighborsInPrediction, levelOfDetailCount, dist2,
predictors, numberOfPointsPerLOD, indexes); predictors, numberOfPointsPerLOD, indexes);
for (auto &predictor : predictors) {
predictor.computeWeights(numberOfNearestNeighborsInPrediction);
}
} }
int decodeAttributeHeader(const std::string &attributeName, PCCBitstream &bitstream) { int decodeAttributeHeader(const std::string &attributeName, PCCBitstream &bitstream) {
......
...@@ -134,7 +134,6 @@ class PCCTMC3Encoder3 { ...@@ -134,7 +134,6 @@ class PCCTMC3Encoder3 {
return ret; return ret;
} }
buildPredictors(colorParams); buildPredictors(colorParams);
computeColorPredictionWeights(colorParams);
if (int ret = encodeColors(colorParams, bitstream)) { if (int ret = encodeColors(colorParams, bitstream)) {
return ret; return ret;
} }
...@@ -150,7 +149,6 @@ class PCCTMC3Encoder3 { ...@@ -150,7 +149,6 @@ class PCCTMC3Encoder3 {
return ret; return ret;
} }
buildPredictors(reflectanceParams); buildPredictors(reflectanceParams);
computeReflectancePredictionWeights(reflectanceParams);
if (int ret = encodeReflectances(reflectanceParams, bitstream)) { if (int ret = encodeReflectances(reflectanceParams, bitstream)) {
return ret; return ret;
} }
...@@ -192,7 +190,6 @@ class PCCTMC3Encoder3 { ...@@ -192,7 +190,6 @@ class PCCTMC3Encoder3 {
return ret; return ret;
} }
buildPredictors(colorParams); buildPredictors(colorParams);
computeColorPredictionWeights(colorParams);
if (int ret = encodeColors(colorParams, bitstream)) { if (int ret = encodeColors(colorParams, bitstream)) {
return ret; return ret;
} }
...@@ -208,7 +205,6 @@ class PCCTMC3Encoder3 { ...@@ -208,7 +205,6 @@ class PCCTMC3Encoder3 {
return ret; return ret;
} }
buildPredictors(reflectanceParams); buildPredictors(reflectanceParams);
computeReflectancePredictionWeights(reflectanceParams);
if (int ret = encodeReflectances(reflectanceParams, bitstream)) { if (int ret = encodeReflectances(reflectanceParams, bitstream)) {
return ret; return ret;
} }
...@@ -268,8 +264,7 @@ class PCCTMC3Encoder3 { ...@@ -268,8 +264,7 @@ class PCCTMC3Encoder3 {
} }
int encodeReflectances(const PCCAttributeEncodeParamaters &reflectanceParams, int encodeReflectances(const PCCAttributeEncodeParamaters &reflectanceParams,
PCCBitstream &bitstream) { PCCBitstream &bitstream) {
const size_t pointCount = pointCloud.getPointCount(); const size_t pointCount = predictors.size();
assert(pointCount == predictors.size());
uint32_t maxAttributeValueDiff0 = 0; uint32_t maxAttributeValueDiff0 = 0;
for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) { for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) {
const auto &predictor = predictors[predictorIndex]; const auto &predictor = predictors[predictorIndex];
...@@ -305,32 +300,23 @@ class PCCTMC3Encoder3 { ...@@ -305,32 +300,23 @@ class PCCTMC3Encoder3 {
bitstream.buffer + bitstream.size); bitstream.buffer + bitstream.size);
arithmeticEncoder.start_encoder(); arithmeticEncoder.start_encoder();
o3dgc::Static_Bit_Model binaryModel0; o3dgc::Static_Bit_Model binaryModel0;
o3dgc::Adaptive_Data_Model neighborCountModel;
neighborCountModel.set_alphabet(
uint32_t(reflectanceParams.numberOfNearestNeighborsInPrediction));
for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) { for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) {
const auto &predictor = predictors[predictorIndex]; const auto &predictor = predictors[predictorIndex];
if (!predictor.neighborCount) { // no prediction const size_t lodIndex = predictor.levelOfDetailIndex;
encodeAbsUInt32(pointCloud.getReflectance(predictor.index), 16, arithmeticEncoder, const int64_t qs = reflectanceParams.quantizationSteps[lodIndex];
binaryModel0);
} else { const int64_t quantAttValue = pointCloud.getReflectance(predictor.index);
const size_t lodIndex = predictor.levelOfDetailIndex; const int64_t quantPredAttValue = predictor.predictReflectance(pointCloud);
const int64_t qs = reflectanceParams.quantizationSteps[lodIndex]; const int64_t delta = PCCQuantization(quantAttValue - quantPredAttValue, qs);
arithmeticEncoder.encode(uint32_t(predictor.neighborCount - 1), neighborCountModel); const uint32_t attValue0 = uint32_t(o3dgc::IntToUInt(long(delta)));
encodeDiff0UInt32(attValue0, maxAttributeValueDiff0, adaptiveDataModelAlphabetSizeDiff0,
const int64_t quantAttValue = pointCloud.getReflectance(predictor.index); arithmeticEncoder, multiSymbolModelDiff0, binaryModelDiff0, binaryModel0);
const int64_t quantPredAttValue = predictor.predictReflectance(pointCloud);
const int64_t delta = PCCQuantization(quantAttValue - quantPredAttValue, qs); const int64_t reconstructedDelta = PCCInverseQuantization(delta, qs);
const uint32_t attValue0 = uint32_t(o3dgc::IntToUInt(long(delta))); const int64_t reconstructedQuantAttValue = quantPredAttValue + reconstructedDelta;
encodeDiff0UInt32(attValue0, maxAttributeValueDiff0, adaptiveDataModelAlphabetSizeDiff0, const uint16_t reconstructedReflectance = uint16_t(PCCClip(
arithmeticEncoder, multiSymbolModelDiff0, binaryModelDiff0, binaryModel0); reconstructedQuantAttValue, int64_t(0), int64_t(std::numeric_limits<uint16_t>::max())));
pointCloud.setReflectance(predictor.index, reconstructedReflectance);
const int64_t reconstructedDelta = PCCInverseQuantization(delta, qs);
const int64_t reconstructedQuantAttValue = quantPredAttValue + reconstructedDelta;
const uint16_t reconstructedReflectance = uint16_t(PCCClip(
reconstructedQuantAttValue, int64_t(0), int64_t(std::numeric_limits<uint16_t>::max())));
pointCloud.setReflectance(predictor.index, reconstructedReflectance);
}
} }
uint32_t compressedBitstreamSize = arithmeticEncoder.stop_encoder(); uint32_t compressedBitstreamSize = arithmeticEncoder.stop_encoder();
bitstream.size += compressedBitstreamSize; bitstream.size += compressedBitstreamSize;
...@@ -356,8 +342,7 @@ class PCCTMC3Encoder3 { ...@@ -356,8 +342,7 @@ class PCCTMC3Encoder3 {
} }
int encodeColors(const PCCAttributeEncodeParamaters &colorParams, PCCBitstream &bitstream) { int encodeColors(const PCCAttributeEncodeParamaters &colorParams, PCCBitstream &bitstream) {
const size_t pointCount = pointCloud.getPointCount(); const size_t pointCount = predictors.size();
assert(pointCount == predictors.size());
uint32_t maxAttributeValueDiff0 = 0; uint32_t maxAttributeValueDiff0 = 0;
uint32_t maxAttributeValueDiff1 = 0; uint32_t maxAttributeValueDiff1 = 0;
for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) { for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) {
...@@ -422,137 +407,47 @@ class PCCTMC3Encoder3 { ...@@ -422,137 +407,47 @@ class PCCTMC3Encoder3 {
bitstream.buffer + bitstream.size); bitstream.buffer + bitstream.size);
arithmeticEncoder.start_encoder(); arithmeticEncoder.start_encoder();
o3dgc::Static_Bit_Model binaryModel0; o3dgc::Static_Bit_Model binaryModel0;
o3dgc::Adaptive_Data_Model neighborCountModel;
neighborCountModel.set_alphabet(uint32_t(colorParams.numberOfNearestNeighborsInPrediction));
for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) { for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) {
const auto &predictor = predictors[predictorIndex]; const auto &predictor = predictors[predictorIndex];
const PCCColor3B color = pointCloud.getColor(predictor.index); const PCCColor3B color = pointCloud.getColor(predictor.index);
const PCCColor3B predictedColor = predictor.predictColor(pointCloud);
if (!predictor.neighborCount) { // no prediction const size_t lodIndex = predictor.levelOfDetailIndex;
for (size_t k = 0; k < 3; ++k) { const int64_t qs = colorParams.quantizationSteps[lodIndex];
encodeAbsUInt32(color[k], 8, arithmeticEncoder, binaryModel0); const int64_t quantAttValue = color[0];
} const int64_t quantPredAttValue = predictedColor[0];
} else { const int64_t delta = PCCQuantization(quantAttValue - quantPredAttValue, qs);
const PCCColor3B predictedColor = predictor.predictColor(pointCloud); const uint32_t attValue0 = uint32_t(o3dgc::IntToUInt(long(delta)));
const size_t lodIndex = predictor.levelOfDetailIndex; const uint32_t modelIndex = (attValue0 < PCCTMC3Diff1AdaptiveDataModelCount)
const int64_t qs = colorParams.quantizationSteps[lodIndex]; ? attValue0
arithmeticEncoder.encode(uint32_t(predictor.neighborCount - 1), neighborCountModel); : PCCTMC3Diff1AdaptiveDataModelCount - 1;
encodeDiff0UInt32(attValue0, maxAttributeValueDiff0, adaptiveDataModelAlphabetSizeDiff0,
const int64_t quantAttValue = color[0]; arithmeticEncoder, multiSymbolModelDiff0, binaryModelDiff0, binaryModel0);
const int64_t quantPredAttValue = predictedColor[0];
const int64_t reconstructedDelta = PCCInverseQuantization(delta, qs);
const int64_t reconstructedQuantAttValue = quantPredAttValue + reconstructedDelta;
PCCColor3B reconstructedColor;
reconstructedColor[0] =
uint8_t(PCCClip(reconstructedQuantAttValue, int64_t(0), int64_t(255)));
for (size_t k = 1; k < 3; ++k) {
const int64_t quantAttValue = color[k];
const int64_t quantPredAttValue = predictedColor[k];
const int64_t delta = PCCQuantization(quantAttValue - quantPredAttValue, qs); const int64_t delta = PCCQuantization(quantAttValue - quantPredAttValue, qs);
const uint32_t attValue0 = uint32_t(o3dgc::IntToUInt(long(delta)));
const uint32_t modelIndex = (attValue0 < PCCTMC3Diff1AdaptiveDataModelCount)
? attValue0
: PCCTMC3Diff1AdaptiveDataModelCount - 1;
encodeDiff0UInt32(attValue0, maxAttributeValueDiff0, adaptiveDataModelAlphabetSizeDiff0,
arithmeticEncoder, multiSymbolModelDiff0, binaryModelDiff0, binaryModel0);
const int64_t reconstructedDelta = PCCInverseQuantization(delta, qs); const int64_t reconstructedDelta = PCCInverseQuantization(delta, qs);
const int64_t reconstructedQuantAttValue = quantPredAttValue + reconstructedDelta; const int64_t reconstructedQuantAttValue = quantPredAttValue + reconstructedDelta;
PCCColor3B reconstructedColor; const uint32_t attValue1 = uint32_t(o3dgc::IntToUInt(long(delta)));
reconstructedColor[0] = encodeDiff1UInt32(attValue1, modelIndex, maxAttributeValueDiff1,
adaptiveDataModelAlphabetSizeDiff1, arithmeticEncoder,
multiSymbolModelDiff1, binaryModelDiff1, binaryModel0);
reconstructedColor[k] =
uint8_t(PCCClip(reconstructedQuantAttValue, int64_t(0), int64_t(255))); uint8_t(PCCClip(reconstructedQuantAttValue, int64_t(0), int64_t(255)));
for (size_t k = 1; k < 3; ++k) {
const int64_t quantAttValue = color[k];
const int64_t quantPredAttValue = predictedColor[k];
const int64_t delta = PCCQuantization(quantAttValue - quantPredAttValue, qs);
const int64_t reconstructedDelta = PCCInverseQuantization(delta, qs);
const int64_t reconstructedQuantAttValue = quantPredAttValue + reconstructedDelta;
const uint32_t attValue1 = uint32_t(o3dgc::IntToUInt(long(delta)));
encodeDiff1UInt32(attValue1, modelIndex, maxAttributeValueDiff1,
adaptiveDataModelAlphabetSizeDiff1, arithmeticEncoder,
multiSymbolModelDiff1, binaryModelDiff1, binaryModel0);
reconstructedColor[k] =
uint8_t(PCCClip(reconstructedQuantAttValue, int64_t(0), int64_t(255)));
}
pointCloud.setColor(predictor.index, reconstructedColor);
} }
pointCloud.setColor(predictor.index, reconstructedColor);
} }
uint32_t compressedBitstreamSize = arithmeticEncoder.stop_encoder(); uint32_t compressedBitstreamSize = arithmeticEncoder.stop_encoder();
bitstream.size += compressedBitstreamSize; bitstream.size += compressedBitstreamSize;
PCCWriteToBuffer<uint32_t>(compressedBitstreamSize, bitstream.buffer, startSize); PCCWriteToBuffer<uint32_t>(compressedBitstreamSize, bitstream.buffer, startSize);
return 0; return 0;
} }
void computeColorPredictionWeights(const PCCAttributeEncodeParamaters &attributeParams) {
const size_t pointCount = predictors.size();
double bestCost = std::numeric_limits<double>::max();
size_t bestNeighborCount = 1;
for (size_t neighborCount = 1;
neighborCount <= attributeParams.numberOfNearestNeighborsInPrediction; ++neighborCount) {
double cost = 0.0;
for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) {
auto &predictor = predictors[predictorIndex];
if (!predictor.maxNeighborCount) {
continue;
}
predictor.computeWeights(neighborCount);
const PCCColor3B color = pointCloud.getColor(predictor.index);
const PCCColor3B predictedColor = predictor.predictColor(pointCloud);
for (int k = 0; k < 3; ++k) {
const size_t lodIndex = predictor.levelOfDetailIndex;
const int64_t quantAttValue = color[k];
const int64_t quantPredAttValue = predictedColor[k];
const int64_t delta0 = PCCQuantization(
quantAttValue - quantPredAttValue,
int64_t(attributeParams.quantizationSteps[lodIndex]));
const uint32_t delta1 = uint32_t(o3dgc::IntToUInt(long(delta0)));
cost += delta1;
}
}
if (cost < bestCost) {
bestCost = cost;
bestNeighborCount = neighborCount;
}
}
for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) {
auto &predictor = predictors[predictorIndex];
if (!predictor.maxNeighborCount) {
continue;
}
predictor.computeWeights(bestNeighborCount);
}
}
void computeReflectancePredictionWeights(const PCCAttributeEncodeParamaters &attributeParams) {
const size_t pointCount = predictors.size();
double bestCost = std::numeric_limits<double>::max();
size_t bestNeighborCount = 1;
for (size_t neighborCount = 1;
neighborCount <= attributeParams.numberOfNearestNeighborsInPrediction; ++neighborCount) {
double cost = 0.0;
for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) {
auto &predictor = predictors[predictorIndex];
if (!predictor.maxNeighborCount) {
continue;
}
predictor.computeWeights(neighborCount);
const size_t lodIndex = predictor.levelOfDetailIndex;
const int64_t quantAttValue = pointCloud.getReflectance(predictor.index);
const int64_t quantPredAttValue = predictor.predictReflectance(pointCloud);
const int64_t delta0 = PCCQuantization(
quantAttValue - quantPredAttValue,
int64_t(attributeParams.quantizationSteps[lodIndex]));
const uint32_t delta1 = uint32_t(o3dgc::IntToUInt(long(delta0)));
cost += delta1;
}
if (cost < bestCost) {
bestCost = cost;
bestNeighborCount = neighborCount;
}
}
for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) {
auto &predictor = predictors[predictorIndex];
if (!predictor.maxNeighborCount) {
continue;
}
predictor.computeWeights(bestNeighborCount);
}
}
void buildPredictors(const PCCAttributeEncodeParamaters &attributeParams) { void buildPredictors(const PCCAttributeEncodeParamaters &attributeParams) {
std::vector<uint32_t> numberOfPointsPerLOD; std::vector<uint32_t> numberOfPointsPerLOD;
...@@ -560,7 +455,13 @@ class PCCTMC3Encoder3 { ...@@ -560,7 +455,13 @@ class PCCTMC3Encoder3 {
PCCBuildPredictors(pointCloud, attributeParams.numberOfNearestNeighborsInPrediction, PCCBuildPredictors(pointCloud, attributeParams.numberOfNearestNeighborsInPrediction,
attributeParams.levelOfDetailCount, attributeParams.dist2, attributeParams.levelOfDetailCount, attributeParams.dist2,
predictors, numberOfPointsPerLOD, indexes); predictors, numberOfPointsPerLOD, indexes);
for (auto &predictor : predictors) {
predictor.computeWeights(
attributeParams.numberOfNearestNeighborsInPrediction);
}
} }
void reconstructedPointCloud(const PCCTMC3Encoder3Parameters &params, void reconstructedPointCloud(const PCCTMC3Encoder3Parameters &params,
PCCPointSet3 *reconstructedCloud) { PCCPointSet3 *reconstructedCloud) {
if (reconstructedCloud == nullptr) { if (reconstructedCloud == nullptr) {
......
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