```This commit introduces the rahtLeafDecimationDepth parameter to allow
chroma sub-sampling by decimating the coefficients in the bottom n
levels of the tree.

The default value of 3 provides chroma sub-sampling by a factor of 2
in each dimension.```
parent 4a6b1a3d
 ... ... @@ -154,6 +154,7 @@ int AttributeDecoder::decodeHeader( transformType = TransformType(transType); PCCReadFromBuffer(bitstream.buffer, depthRaht, bitstream.size); PCCReadFromBuffer(bitstream.buffer, binaryLevelThresholdRaht, bitstream.size); PCCReadFromBuffer(bitstream.buffer, quantizationStepRaht, bitstream.size); return 0; } ... ... @@ -294,8 +295,9 @@ void AttributeDecoder::decodeReflectancesRaht( // Re-obtain weights at the decoder by calling RAHT without any attributes. float *weight = new float[voxelCount]; int *binaryLayer = new int[voxelCount]; regionAdaptiveHierarchicalTransform( mortonCode, nullptr, weight, 0, voxelCount, depthRaht); mortonCode, nullptr, weight, binaryLayer, 0, voxelCount, depthRaht); // Sort integerized attributes by weight std::vector sortedWeight(voxelCount); ... ... @@ -336,6 +338,7 @@ void AttributeDecoder::decodeReflectancesRaht( } // De-allocate arrays. delete[] binaryLayer; delete[] mortonCode; delete[] attributes; delete[] integerizedAttributes; ... ... @@ -375,8 +378,9 @@ void AttributeDecoder::decodeColorsRaht( // Re-obtain weights at the decoder by calling RAHT without any attributes. float *weight = new float[voxelCount]; int *binaryLayer = new int[voxelCount]; regionAdaptiveHierarchicalTransform( mortonCode, nullptr, weight, 0, voxelCount, depthRaht); mortonCode, nullptr, weight, binaryLayer, 0, voxelCount, depthRaht); // Sort integerized attributes by weight std::vector sortedWeight(voxelCount); ... ... @@ -392,9 +396,15 @@ void AttributeDecoder::decodeColorsRaht( for (int n = 0; n < voxelCount; ++n) { const uint32_t attValue0 = decoder.decode0(); sortedIntegerizedAttributes[n] = o3dgc::UIntToInt(attValue0); for (int d = 1; d < 3; ++d) { const uint32_t attValue1 = decoder.decode1(); sortedIntegerizedAttributes[voxelCount * d + n] = o3dgc::UIntToInt(attValue1); if (binaryLayer[sortedWeight[n].index] >= binaryLevelThresholdRaht) { for (int d = 1; d < 3; ++d) { const uint32_t attValue1 = decoder.decode1(); sortedIntegerizedAttributes[voxelCount * d + n] = o3dgc::UIntToInt(attValue1); } } else { for (int d = 1; d < 3; d++) { sortedIntegerizedAttributes[voxelCount * d + n] = 0; } } } ... ... @@ -432,6 +442,7 @@ void AttributeDecoder::decodeColorsRaht( } // De-allocate arrays. delete[] binaryLayer; delete[] mortonCode; delete[] attributes; delete[] integerizedAttributes; ... ...
 ... ... @@ -99,6 +99,7 @@ private: size_t levelOfDetailCount; uint32_t quantizationStepRaht; uint8_t depthRaht; uint8_t binaryLevelThresholdRaht; TransformType transformType; }; ... ...
 ... ... @@ -155,6 +155,10 @@ int AttributeEncoder::encodeHeader( PCCWriteToBuffer( uint8_t(attributeParams.depthRaht), bitstream.buffer, bitstream.size); PCCWriteToBuffer( uint8_t(attributeParams.binaryLevelThresholdRaht), bitstream.buffer, bitstream.size); PCCWriteToBuffer( uint32_t(attributeParams.quantizationStepRaht), bitstream.buffer, bitstream.size); ... ... @@ -317,6 +321,7 @@ void AttributeEncoder::encodeReflectancesTransformRaht( int *integerizedAttributes = new int[voxelCount]; int *sortedIntegerizedAttributes = new int[voxelCount]; float *weight = new float[voxelCount]; int *binaryLayer = new int[voxelCount]; // Populate input arrays. for (int n = 0; n < voxelCount; n++) { ... ... @@ -326,8 +331,9 @@ void AttributeEncoder::encodeReflectancesTransformRaht( // Transform. regionAdaptiveHierarchicalTransform( mortonCode, attributes, weight, mortonCode, attributes, weight, binaryLayer, 1, voxelCount, reflectanceParams.depthRaht); // Quantize. for (int n = 0; n < voxelCount; n++) { integerizedAttributes[n] = ... ... @@ -354,7 +360,9 @@ void AttributeEncoder::encodeReflectancesTransformRaht( } // Re-obtain weights at the decoder by calling Raht without any attributes. regionAdaptiveHierarchicalTransform( mortonCode, nullptr, weight, 0, voxelCount, reflectanceParams.depthRaht); mortonCode, nullptr, weight, binaryLayer, 0, voxelCount, reflectanceParams.depthRaht); // Sort integerized attributes by weight. for (int n = 0; n < voxelCount; n++) { sortedWeight[n].weight = weight[n]; ... ... @@ -381,6 +389,7 @@ void AttributeEncoder::encodeReflectancesTransformRaht( } // De-allocate arrays. delete[] binaryLayer; delete[] mortonCode; delete[] attributes; delete[] integerizedAttributes; ... ... @@ -420,6 +429,7 @@ void AttributeEncoder::encodeColorsTransformRaht( int *integerizedAttributes = new int[attribCount * voxelCount]; int *sortedIntegerizedAttributes = new int[attribCount * voxelCount]; float *weight = new float[voxelCount]; int *binaryLayer = new int[voxelCount]; // Populate input arrays. for (int n = 0; n < voxelCount; n++) { ... ... @@ -432,8 +442,9 @@ void AttributeEncoder::encodeColorsTransformRaht( // Transform. regionAdaptiveHierarchicalTransform( mortonCode, attributes, weight, mortonCode, attributes, weight, binaryLayer, attribCount, voxelCount, colorParams.depthRaht); // Quantize. for (int n = 0; n < voxelCount; n++) { for (int k = 0; k < attribCount; k++) { ... ... @@ -463,17 +474,25 @@ void AttributeEncoder::encodeColorsTransformRaht( assert(detail < std::numeric_limits::max()); const uint32_t attValue0 = uint32_t(detail); encoder.encode0(attValue0); for (int d = 1; d < 3; ++d) { const int64_t detail = o3dgc::IntToUInt(sortedIntegerizedAttributes[voxelCount * d + n]); assert(detail < std::numeric_limits::max()); const uint32_t attValue1 = uint32_t(detail); encoder.encode1(attValue1); if (binaryLayer[sortedWeight[n].index] >= colorParams.binaryLevelThresholdRaht) { for (int d = 1; d < 3; ++d) { const int64_t detail = o3dgc::IntToUInt(sortedIntegerizedAttributes[voxelCount * d + n]); assert(detail < std::numeric_limits::max()); const uint32_t attValue1 = uint32_t(detail); encoder.encode1(attValue1); } } else { for (int d = 1; d < 3; d++) { sortedIntegerizedAttributes[voxelCount * d + n] = 0; } } } // Re-obtain weights at the decoder by calling RAHT without any attributes. regionAdaptiveHierarchicalTransform( mortonCode, nullptr, weight, 0, voxelCount, colorParams.depthRaht); mortonCode, nullptr, weight, binaryLayer, 0, voxelCount, colorParams.depthRaht); // Sort integerized attributes by weight. for (int n = 0; n < voxelCount; n++) { sortedWeight[n].weight = weight[n]; ... ... @@ -510,6 +529,7 @@ void AttributeEncoder::encodeColorsTransformRaht( } // De-allocate arrays. delete[] binaryLayer; delete[] mortonCode; delete[] attributes; delete[] integerizedAttributes; ... ...
 ... ... @@ -58,6 +58,7 @@ struct PCCAttributeEncodeParamaters { size_t searchRange; int quantizationStepRaht; int depthRaht; int binaryLevelThresholdRaht; TransformType transformType; std::vector dist2; std::vector quantizationSteps; ... ...
 ... ... @@ -61,7 +61,7 @@ namespace pcc { * sorting or bucketing for entropy coding. */ void regionAdaptiveHierarchicalTransform( long long *mortonCode, float *attributes, float *weight, long long *mortonCode, float *attributes, float *weight, int *binaryLayer, int attribCount, int voxelCount, int depth) { // Prologue, common to both RAHT and IRAHT: ... ... @@ -170,7 +170,10 @@ void regionAdaptiveHierarchicalTransform( float *x1 = new float[attribCount]; // Initialize weights. for (int n = 0; n < voxelCount; n++) weight[n] = 1.0f; for (int n = 0; n < voxelCount; n++) { weight[n] = 1.0f; binaryLayer[n] = 0; } // Process one level at a time, from leaves (b=0) to root (b=3*depth-1). for (int b = 0; b < 3 * depth; b++) { ... ... @@ -204,6 +207,8 @@ void regionAdaptiveHierarchicalTransform( weight[i0] = (w0 + w1); weight[i1] = (w0 + w1); binaryLayer[i0] = b + 1; n++; // skip over right sibling } } ... ...
 ... ... @@ -67,7 +67,7 @@ struct MortonCodeWithIndex { }; void regionAdaptiveHierarchicalTransform( long long *mortonCode, float *attributes, float *weight, long long *mortonCode, float *attributes, float *weight, int *binaryLayer, int attribCount, int voxelCount, int depth); void regionAdaptiveHierarchicalInverseTransform( ... ...
 ... ... @@ -205,6 +205,11 @@ bool ParseParameters(int argc, char *argv[], Parameters ¶ms) { " 0: Nearest neighbour prediction with integer lifting transform\n" " 1: Region Adaptive Hierarchical Transform (RAHT)") ("rahtLeafDecimationDepth", params_attr.binaryLevelThresholdRaht, 3, "Sets coefficients to zero in the bottom n levels of RAHT tree. " "Used for chroma-subsampling in attribute=color only.") ("rahtQuantizationStep", params_attr.quantizationStepRaht, 1, "Quantization step size used in RAHT") ... ...
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
{"ft_lang_label":"__label__en","ft_lang_prob":0.74724525,"math_prob":0.9796684,"size":414,"snap":"2023-40-2023-50","text_gpt3_token_len":104,"char_repetition_ratio":0.10243902,"word_repetition_ratio":0.0,"special_character_ratio":0.19082126,"punctuation_ratio":0.045454547,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.9520223,"pos_list":[0],"im_url_duplicate_count":[null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2023-09-27T03:07:57Z\",\"WARC-Record-ID\":\"<urn:uuid:e6f7dfc3-e7c8-4116-b8f8-cd7ec762cdd7>\",\"Content-Length\":\"477315\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:897a64be-4fe8-43cc-9c39-eb26b2930252>\",\"WARC-Concurrent-To\":\"<urn:uuid:f083019f-eb40-4a09-aa39-e8a11ac0a1ab>\",\"WARC-IP-Address\":\"157.159.160.111\",\"WARC-Target-URI\":\"http://mpegx.int-evry.fr/software/satoru.kuma/MPEG129-m52280/-/commit/34da2afb2514819e6b8bdfde776335178f6f142f\",\"WARC-Payload-Digest\":\"sha1:F5QQSXHNAMR2BL34PWBKGCU2LR652EE4\",\"WARC-Block-Digest\":\"sha1:JFMBDNTLCTTDPPUQHDDBYIVOZ3QUAQ6A\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2023/CC-MAIN-2023-40/CC-MAIN-2023-40_segments_1695233510238.65_warc_CC-MAIN-20230927003313-20230927033313-00580.warc.gz\"}"}