Commit 01ce36e3 authored by Khaled Mammou's avatar Khaled Mammou Committed by David Flynn
Browse files

m42634/quant: change dead-zone from configurable to proportional

This commit removes the ability to control the quantization dead-zone
parameters since they have always been identical to the step size.

Rather than hard-coding the dead-zone size parameter to be the same as
the step size, this commit:

 - Sets the dead-zone to be ±(2 * stepsize / 3) rather than ±stepsize

 - Does not narrow the interval following the dead-zone.

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 b4106fb4
......@@ -6,6 +6,5 @@ positionQuantizationScale: 0.0045
levelOfDetailCount: 5
dist2: 85 21 5 1 0
quantizationSteps: 0 1 2 4 4
quantizationDeadZoneSizes: 0 1 2 4 4
searchRange: 0
attribute: reflectance
......@@ -6,6 +6,5 @@ positionQuantizationScale: 0.011
levelOfDetailCount: 6
dist2: 508 127 32 8 2 0
quantizationSteps: 0 1 2 4 4 4
quantizationDeadZoneSizes: 0 1 2 4 4 4
searchRange: 0
attribute: reflectance
......@@ -6,6 +6,5 @@ positionQuantizationScale: 0.05
levelOfDetailCount: 6
dist2: 10486 2621 655 164 41 0
quantizationSteps: 0 1 2 4 4 4
quantizationDeadZoneSizes: 0 1 2 4 4 4
searchRange: 0
attribute: reflectance
......@@ -6,6 +6,5 @@ positionQuantizationScale: 0.275
levelOfDetailCount: 6
dist2: 317194 79299 19825 4956 1239 0
quantizationSteps: 0 1 2 4 4 4
quantizationDeadZoneSizes: 0 1 2 4 4 4
searchRange: 0
attribute: reflectance
......@@ -130,33 +130,22 @@ struct PCCPredictor {
levelOfDetailIndex = lodIndex;
}
};
inline int64_t PCCQuantization(const int64_t value, const int64_t qs, const int64_t deadZone) {
inline int64_t PCCQuantization(const int64_t value, const int64_t qs) {
const int64_t shift = (qs / 3);
if (!qs) {
return value;
} else {
const int64_t qs2 = qs / 2;
if (value > deadZone) {
return (value - deadZone + qs2) / qs + 1;
} else if (value < -deadZone) {
return (value + deadZone - qs2) / qs - 1;
} else {
return int64_t(0);
}
}
}
inline int64_t PCCInverseQuantization(const int64_t value, const int64_t qs, int64_t deadZone) {
if (!qs) {
return value;
} else {
if (value > 0) {
return (value - 1) * qs + deadZone;
} else if (value < 0) {
return (value + 1) * qs - deadZone;
} else {
return int64_t(0);
}
if (value >= 0) {
return (value + shift) / qs;
}
return -((shift - value) / qs);
}
inline int64_t PCCInverseQuantization(const int64_t value, const int64_t qs) {
return qs == 0 ? value : (value * qs);
}
inline void PCCBuildPredictors(const PCCPointSet3 &pointCloud,
const size_t numberOfNearestNeighborsInPrediction,
const size_t levelOfDetailCount, const std::vector<size_t> &dist2,
......
......@@ -66,7 +66,6 @@ class PCCTMC3Decoder3 {
levelOfDetailCount = 0;
dist2.clear();
quantizationSteps.clear();
quantizationDeadZoneSizes.clear();
predictors.clear();
}
int decompressWithLosslessGeometry(PCCBitstream &bitstream, PCCPointSet3 &pointCloud) {
......@@ -264,12 +263,11 @@ class PCCTMC3Decoder3 {
predictor.computeWeights(neighborCount);
const size_t lodIndex = predictor.levelOfDetailIndex;
const int64_t qs = quantizationSteps[lodIndex];
const int64_t dz = quantizationDeadZoneSizes[lodIndex];
const uint32_t attValue0 = decodeDiff0UInt32(
maxAttributeValueDiff0, adaptiveDataModelAlphabetSizeDiff0, arithmeticDecoder,
multiSymbolModelDiff0, binaryModelDiff0, binaryModel0);
const int64_t quantPredAttValue = predictor.predictReflectance(pointCloud);
const int64_t delta = PCCInverseQuantization(o3dgc::UIntToInt(attValue0), qs, dz);
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())));
......@@ -340,7 +338,6 @@ class PCCTMC3Decoder3 {
const PCCColor3B predictedColor = predictor.predictColor(pointCloud);
const size_t lodIndex = predictor.levelOfDetailIndex;
const int64_t qs = quantizationSteps[lodIndex];
const int64_t dz = quantizationDeadZoneSizes[lodIndex];
const uint32_t attValue0 = decodeDiff0UInt32(
maxAttributeValueDiff0, adaptiveDataModelAlphabetSizeDiff0, arithmeticDecoder,
multiSymbolModelDiff0, binaryModelDiff0, binaryModel0);
......@@ -348,7 +345,7 @@ class PCCTMC3Decoder3 {
? attValue0
: PCCTMC3Diff1AdaptiveDataModelCount - 1;
const int64_t quantPredAttValue = predictedColor[0];
const int64_t delta = PCCInverseQuantization(o3dgc::UIntToInt(attValue0), qs, dz);
const int64_t delta = PCCInverseQuantization(o3dgc::UIntToInt(attValue0), qs);
const int64_t reconstructedQuantAttValue = quantPredAttValue + delta;
color[0] = uint8_t(PCCClip(reconstructedQuantAttValue, int64_t(0), int64_t(255)));
......@@ -357,7 +354,7 @@ class PCCTMC3Decoder3 {
modelIndex, maxAttributeValueDiff1, adaptiveDataModelAlphabetSizeDiff1,
arithmeticDecoder, multiSymbolModelDiff1, binaryModelDiff1, binaryModel0);
const int64_t quantPredAttValue = predictedColor[k];
const int64_t delta = PCCInverseQuantization(o3dgc::UIntToInt(attValue), qs, dz);
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)));
}
......@@ -397,12 +394,6 @@ class PCCTMC3Decoder3 {
quantizationSteps[lodIndex] = qs;
}
quantizationDeadZoneSizes.resize(levelOfDetailCount);
for (size_t lodIndex = 0; lodIndex < levelOfDetailCount; ++lodIndex) {
uint16_t dz = 0;
PCCReadFromBuffer<uint16_t>(bitstream.buffer, dz, bitstream.size);
quantizationDeadZoneSizes[lodIndex] = dz;
}
return 0;
}
......@@ -781,7 +772,6 @@ class PCCTMC3Decoder3 {
std::vector<PCCPredictor> predictors;
std::vector<size_t> dist2;
std::vector<int64_t> quantizationSteps;
std::vector<int64_t> quantizationDeadZoneSizes;
PCCVector3D minPositions;
PCCBox3<uint32_t> boundingBox;
double positionQuantizationScale;
......
......@@ -60,7 +60,6 @@ struct PCCAttributeEncodeParamaters {
size_t searchRange;
std::vector<size_t> dist2;
std::vector<size_t> quantizationSteps;
std::vector<size_t> quantizationDeadZoneSizes;
};
struct PCCTMC3Encoder3Parameters {
......@@ -317,17 +316,16 @@ class PCCTMC3Encoder3 {
} else {
const size_t lodIndex = predictor.levelOfDetailIndex;
const int64_t qs = reflectanceParams.quantizationSteps[lodIndex];
const int64_t dz = reflectanceParams.quantizationDeadZoneSizes[lodIndex];
arithmeticEncoder.encode(uint32_t(predictor.neighborCount - 1), neighborCountModel);
const int64_t quantAttValue = pointCloud.getReflectance(predictor.index);
const int64_t quantPredAttValue = predictor.predictReflectance(pointCloud);
const int64_t delta = PCCQuantization(quantAttValue - quantPredAttValue, qs, dz);
const int64_t delta = PCCQuantization(quantAttValue - quantPredAttValue, qs);
const uint32_t attValue0 = uint32_t(o3dgc::IntToUInt(long(delta)));
encodeDiff0UInt32(attValue0, maxAttributeValueDiff0, adaptiveDataModelAlphabetSizeDiff0,
arithmeticEncoder, multiSymbolModelDiff0, binaryModelDiff0, binaryModel0);
const int64_t reconstructedDelta = PCCInverseQuantization(delta, qs, dz);
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())));
......@@ -354,10 +352,6 @@ class PCCTMC3Encoder3 {
const uint32_t qs = uint32_t(attributeParams.quantizationSteps[lodIndex]);
PCCWriteToBuffer<uint32_t>(qs, bitstream.buffer, bitstream.size);
}
for (size_t lodIndex = 0; lodIndex < attributeParams.levelOfDetailCount; ++lodIndex) {
const uint16_t dz = uint16_t(attributeParams.quantizationDeadZoneSizes[lodIndex]);
PCCWriteToBuffer<uint16_t>(dz, bitstream.buffer, bitstream.size);
}
return 0;
}
......@@ -442,12 +436,11 @@ class PCCTMC3Encoder3 {
const PCCColor3B predictedColor = predictor.predictColor(pointCloud);
const size_t lodIndex = predictor.levelOfDetailIndex;
const int64_t qs = colorParams.quantizationSteps[lodIndex];
const int64_t dz = colorParams.quantizationDeadZoneSizes[lodIndex];
arithmeticEncoder.encode(uint32_t(predictor.neighborCount - 1), neighborCountModel);
const int64_t quantAttValue = color[0];
const int64_t quantPredAttValue = predictedColor[0];
const int64_t delta = PCCQuantization(quantAttValue - quantPredAttValue, qs, dz);
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
......@@ -455,7 +448,7 @@ class PCCTMC3Encoder3 {
encodeDiff0UInt32(attValue0, maxAttributeValueDiff0, adaptiveDataModelAlphabetSizeDiff0,
arithmeticEncoder, multiSymbolModelDiff0, binaryModelDiff0, binaryModel0);
const int64_t reconstructedDelta = PCCInverseQuantization(delta, qs, dz);
const int64_t reconstructedDelta = PCCInverseQuantization(delta, qs);
const int64_t reconstructedQuantAttValue = quantPredAttValue + reconstructedDelta;
PCCColor3B reconstructedColor;
reconstructedColor[0] =
......@@ -463,8 +456,8 @@ class PCCTMC3Encoder3 {
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, dz);
const int64_t reconstructedDelta = PCCInverseQuantization(delta, qs, dz);
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,
......@@ -501,10 +494,10 @@ class PCCTMC3Encoder3 {
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]),
int64_t(attributeParams.quantizationDeadZoneSizes[lodIndex]));
const int64_t delta0 = PCCQuantization(
quantAttValue - quantPredAttValue,
int64_t(attributeParams.quantizationSteps[lodIndex]));
const uint32_t delta1 = uint32_t(o3dgc::IntToUInt(long(delta0)));
cost += delta1;
}
......@@ -541,8 +534,9 @@ class PCCTMC3Encoder3 {
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]),
int64_t(attributeParams.quantizationDeadZoneSizes[lodIndex]));
quantAttValue - quantPredAttValue,
int64_t(attributeParams.quantizationSteps[lodIndex]));
const uint32_t delta1 = uint32_t(o3dgc::IntToUInt(long(delta0)));
cost += delta1;
}
......
......@@ -197,10 +197,6 @@ bool ParseParameters(int argc, char *argv[], Parameters &params) {
params_attr.quantizationSteps, {},
"Attribute's list of quantization step sizes (one for each LoD)")
("quantizationDeadZoneSizes",
params_attr.quantizationDeadZoneSizes, {},
"Attribute's list of dead-zone sizes (one for each LoD)")
("dist2", params_attr.dist2, {},
"Attribute's list of squared distances (one for each LoD)")
;
......@@ -220,7 +216,7 @@ bool ParseParameters(int argc, char *argv[], Parameters &params) {
}
// sanity checks
// - validate that quantizationSteps, quantizationDeadZoneSizes, dist2
// - validate that quantizationSteps, dist2
// of each attribute contain levelOfDetailCount elements.
for (const auto &attr : params.encodeParameters.attributeEncodeParameters) {
int lod = attr.second.levelOfDetailCount;
......@@ -231,9 +227,6 @@ bool ParseParameters(int argc, char *argv[], Parameters &params) {
if (attr.second.quantizationSteps.size() != lod) {
err.error() << attr.first << ".quantizationSteps does not have " << lod << " entries\n";
}
if (attr.second.quantizationDeadZoneSizes.size() != lod) {
err.error() << attr.first << ".quantizationDeadZoneSizes does not have " << lod << " entries\n";
}
}
// check required arguments are specified
......@@ -302,11 +295,6 @@ bool ParseParameters(int argc, char *argv[], Parameters &params) {
cout << qs << " ";
}
cout << endl;
cout << "\t\t quantizationDeadZoneSizes ";
for (const auto dz : attributeEncodeParameters.second.quantizationDeadZoneSizes) {
cout << dz << " ";
}
cout << endl;
}
cout << endl;
} else {
......
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