Commit d013293e authored by Khaled Mammou's avatar Khaled Mammou
Browse files

TMC3v0 for quantized point clouds

git-svn-id: http://wg11.sc29.org/svn/repos/MPEG-I/Part5-PointCloudCompression/TM/TMC3/trunk@1262 94298a81-5874-47c9-aab8-bfb24faeed7f
parent 352913c2
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
...@@ -85,7 +85,7 @@ inline bool PCCTransfertColors(const PCCPointSet3 &source, const int32_t searchR ...@@ -85,7 +85,7 @@ inline bool PCCTransfertColors(const PCCPointSet3 &source, const int32_t searchR
const double H = double(colors2.size()); const double H = double(colors2.size());
const PCCVector3D centroid1(color1[0], color1[1], color1[2]); const PCCVector3D centroid1(color1[0], color1[1], color1[2]);
PCCVector3D centroid2(0.0); PCCVector3D centroid2(0.0);
for (const auto color2 : colors2) { for (const auto& color2 : colors2) {
for (size_t k = 0; k < 3; ++k) { for (size_t k = 0; k < 3; ++k) {
centroid2[k] += color2[k]; centroid2[k] += color2[k];
} }
...@@ -93,7 +93,7 @@ inline bool PCCTransfertColors(const PCCPointSet3 &source, const int32_t searchR ...@@ -93,7 +93,7 @@ inline bool PCCTransfertColors(const PCCPointSet3 &source, const int32_t searchR
centroid2 /= H; centroid2 /= H;
double D2 = 0.0; double D2 = 0.0;
for (const auto color2 : colors2) { for (const auto& color2 : colors2) {
for (size_t k = 0; k < 3; ++k) { for (size_t k = 0; k < 3; ++k) {
const double d2 = centroid2[k] - color2[k]; const double d2 = centroid2[k] - color2[k];
D2 += d2 * d2; D2 += d2 * d2;
...@@ -141,7 +141,7 @@ inline bool PCCTransfertColors(const PCCPointSet3 &source, const int32_t searchR ...@@ -141,7 +141,7 @@ inline bool PCCTransfertColors(const PCCPointSet3 &source, const int32_t searchR
e1 *= rTarget; e1 *= rTarget;
double e2 = 0.0; double e2 = 0.0;
for (const auto color2 : colors2) { for (const auto& color2 : colors2) {
for (size_t k = 0; k < 3; ++k) { for (size_t k = 0; k < 3; ++k) {
const double d = color[k] - color2[k]; const double d = color[k] - color2[k];
e2 += d * d; e2 += d * d;
......
...@@ -141,7 +141,7 @@ inline int64_t PCCInverseQuantization(const int64_t value, const int64_t qs, int ...@@ -141,7 +141,7 @@ inline int64_t PCCInverseQuantization(const int64_t value, const int64_t qs, int
inline void PCCBuildPredictors(const PCCPointSet3 &pointCloud, inline void PCCBuildPredictors(const PCCPointSet3 &pointCloud,
const size_t numberOfNearestNeighborsInPrediction, const size_t numberOfNearestNeighborsInPrediction,
const size_t levelOfDetailCount, const std::vector<size_t> &dist2, const size_t levelOfDetailCount, const std::vector<size_t> &dist2,
const double dist2Scale, std::vector<PCCPredictor> &predictors, std::vector<PCCPredictor> &predictors,
std::vector<uint32_t> &numberOfPointsPerLOD, std::vector<uint32_t> &numberOfPointsPerLOD,
std::vector<uint32_t> &indexes) { std::vector<uint32_t> &indexes) {
const size_t pointCount = pointCloud.getPointCount(); const size_t pointCount = pointCloud.getPointCount();
...@@ -164,7 +164,7 @@ inline void PCCBuildPredictors(const PCCPointSet3 &pointCloud, ...@@ -164,7 +164,7 @@ inline void PCCBuildPredictors(const PCCPointSet3 &pointCloud,
for (size_t lodIndex = 0; lodIndex < levelOfDetailCount && indexes.size() < pointCount; for (size_t lodIndex = 0; lodIndex < levelOfDetailCount && indexes.size() < pointCount;
++lodIndex) { ++lodIndex) {
const bool filterByDistance = (lodIndex + 1) != levelOfDetailCount; const bool filterByDistance = (lodIndex + 1) != levelOfDetailCount;
const double minDist2 = dist2[lodIndex] * dist2Scale; const double minDist2 = dist2[lodIndex];
nNQuery.radius = minDist2; nNQuery.radius = minDist2;
size_t balanceTargetPointCount = initialBalanceTargetPointCount; size_t balanceTargetPointCount = initialBalanceTargetPointCount;
for (uint32_t current = 0; current < pointCount; ++current) { for (uint32_t current = 0; current < pointCount; ++current) {
......
...@@ -47,7 +47,6 @@ ...@@ -47,7 +47,6 @@
#include "PCCTMC3Common.h" #include "PCCTMC3Common.h"
#include "ArithmeticCodec.h" #include "ArithmeticCodec.h"
namespace pcc { namespace pcc {
class PCCTMC3Decoder3 { class PCCTMC3Decoder3 {
...@@ -103,7 +102,7 @@ class PCCTMC3Decoder3 { ...@@ -103,7 +102,7 @@ class PCCTMC3Decoder3 {
if (int ret = decodeAttributeHeader("color", bitstream)) { if (int ret = decodeAttributeHeader("color", bitstream)) {
return ret; return ret;
} }
buildPredictors(pointCloud, 0.001); buildPredictors(pointCloud);
if (int ret = decodeColors(bitstream, pointCloud)) { if (int ret = decodeColors(bitstream, pointCloud)) {
return ret; return ret;
} }
...@@ -117,7 +116,7 @@ class PCCTMC3Decoder3 { ...@@ -117,7 +116,7 @@ class PCCTMC3Decoder3 {
if (int ret = decodeAttributeHeader("reflectance", bitstream)) { if (int ret = decodeAttributeHeader("reflectance", bitstream)) {
return ret; return ret;
} }
buildPredictors(pointCloud, 0.001); buildPredictors(pointCloud);
if (int ret = decodeReflectances(bitstream, pointCloud)) { if (int ret = decodeReflectances(bitstream, pointCloud)) {
return ret; return ret;
} }
...@@ -126,7 +125,7 @@ class PCCTMC3Decoder3 { ...@@ -126,7 +125,7 @@ class PCCTMC3Decoder3 {
} }
return 0; return 0;
} }
int decompress(PCCBitstream &bitstream, PCCPointSet3 &pointCloud) { int decompress(PCCBitstream &bitstream, PCCPointSet3 &pointCloud, const bool roundOutputPositions) {
init(); init();
uint32_t magicNumber = 0; uint32_t magicNumber = 0;
uint32_t formatVersion = 0; uint32_t formatVersion = 0;
...@@ -178,8 +177,7 @@ class PCCTMC3Decoder3 { ...@@ -178,8 +177,7 @@ class PCCTMC3Decoder3 {
std::cout << "reflectances bitstream size " << reflectancesSize << " B" << std::endl; std::cout << "reflectances bitstream size " << reflectancesSize << " B" << std::endl;
} }
inverseQuantization(pointCloud); inverseQuantization(pointCloud, roundOutputPositions);
return 0; return 0;
} }
...@@ -368,11 +366,11 @@ class PCCTMC3Decoder3 { ...@@ -368,11 +366,11 @@ class PCCTMC3Decoder3 {
bitstream.size += compressedBitstreamSize; bitstream.size += compressedBitstreamSize;
return 0; return 0;
} }
void buildPredictors(const PCCPointSet3 &pointCloud, const double dist2Scale = 1.0) { 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,
dist2Scale, predictors, numberOfPointsPerLOD, indexes); predictors, numberOfPointsPerLOD, indexes);
} }
int decodeAttributeHeader(const std::string &attributeName, PCCBitstream &bitstream) { int decodeAttributeHeader(const std::string &attributeName, PCCBitstream &bitstream) {
...@@ -525,16 +523,25 @@ class PCCTMC3Decoder3 { ...@@ -525,16 +523,25 @@ class PCCTMC3Decoder3 {
bitstream.size += compressedBitstreamSize; bitstream.size += compressedBitstreamSize;
return 0; return 0;
} }
void inverseQuantization(PCCPointSet3 &pointCloud) { void inverseQuantization(PCCPointSet3 &pointCloud, const bool roundOutputPositions) {
const size_t pointCount = pointCloud.getPointCount(); const size_t pointCount = pointCloud.getPointCount();
const double invScale = 1.0 / positionQuantizationScale; const double invScale = 1.0 / positionQuantizationScale;
for (size_t i = 0; i < pointCount; ++i) {
auto &point = pointCloud[i]; if (roundOutputPositions) {
for (size_t k = 0; k < 3; ++k) { for (size_t i = 0; i < pointCount; ++i) {
point[k] = point[k] * invScale + minPositions[k]; auto &point = pointCloud[i];
// point[k] = std::round(point[k] * invScale + minPositions[k]); for (size_t k = 0; k < 3; ++k) {
point[k] = std::round(point[k] * invScale + minPositions[k]);
}
}
} else {
for (size_t i = 0; i < pointCount; ++i) {
auto &point = pointCloud[i];
for (size_t k = 0; k < 3; ++k) {
point[k] = point[k] * invScale + minPositions[k];
}
}
} }
}
} }
private: private:
......
...@@ -156,7 +156,7 @@ class PCCTMC3Encoder3 { ...@@ -156,7 +156,7 @@ class PCCTMC3Encoder3 {
if (int ret = encodeAttributeHeader(colorParams, "color", bitstream)) { if (int ret = encodeAttributeHeader(colorParams, "color", bitstream)) {
return ret; return ret;
} }
buildPredictors(colorParams, 0.001); buildPredictors(colorParams);
computeColorPredictionWeights(colorParams); computeColorPredictionWeights(colorParams);
if (int ret = encodeColors(colorParams, bitstream)) { if (int ret = encodeColors(colorParams, bitstream)) {
return ret; return ret;
...@@ -172,7 +172,7 @@ class PCCTMC3Encoder3 { ...@@ -172,7 +172,7 @@ class PCCTMC3Encoder3 {
if (int ret = encodeAttributeHeader(reflectanceParams, "reflectance", bitstream)) { if (int ret = encodeAttributeHeader(reflectanceParams, "reflectance", bitstream)) {
return ret; return ret;
} }
buildPredictors(reflectanceParams, 0.001); buildPredictors(reflectanceParams);
computeReflectancePredictionWeights(reflectanceParams); computeReflectancePredictionWeights(reflectanceParams);
if (int ret = encodeReflectances(reflectanceParams, bitstream)) { if (int ret = encodeReflectances(reflectanceParams, bitstream)) {
return ret; return ret;
...@@ -531,11 +531,13 @@ class PCCTMC3Encoder3 { ...@@ -531,11 +531,13 @@ class PCCTMC3Encoder3 {
cost += delta1; cost += delta1;
} }
} }
if (cost < bestCost) { if (cost < bestCost) {
bestCost = cost; bestCost = cost;
bestNeighborCount = neighborCount; bestNeighborCount = neighborCount;
} }
} }
for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) { for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) {
auto &predictor = predictors[predictorIndex]; auto &predictor = predictors[predictorIndex];
if (!predictor.maxNeighborCount) { if (!predictor.maxNeighborCount) {
...@@ -566,7 +568,6 @@ class PCCTMC3Encoder3 { ...@@ -566,7 +568,6 @@ class PCCTMC3Encoder3 {
const uint32_t delta1 = uint32_t(o3dgc::IntToUInt(long(delta0))); const uint32_t delta1 = uint32_t(o3dgc::IntToUInt(long(delta0)));
cost += delta1; cost += delta1;
} }
if (cost < bestCost) { if (cost < bestCost) {
bestCost = cost; bestCost = cost;
bestNeighborCount = neighborCount; bestNeighborCount = neighborCount;
...@@ -581,12 +582,11 @@ class PCCTMC3Encoder3 { ...@@ -581,12 +582,11 @@ class PCCTMC3Encoder3 {
} }
} }
void buildPredictors(const PCCAttributeEncodeParamaters &attributeParams, void buildPredictors(const PCCAttributeEncodeParamaters &attributeParams) {
const double dist2Scale = 1.0) {
std::vector<uint32_t> numberOfPointsPerLOD; std::vector<uint32_t> numberOfPointsPerLOD;
std::vector<uint32_t> indexes; std::vector<uint32_t> indexes;
PCCBuildPredictors(pointCloud, attributeParams.numberOfNearestNeighborsInPrediction, PCCBuildPredictors(pointCloud, attributeParams.numberOfNearestNeighborsInPrediction,
attributeParams.levelOfDetailCount, attributeParams.dist2, dist2Scale, attributeParams.levelOfDetailCount, attributeParams.dist2,
predictors, numberOfPointsPerLOD, indexes); predictors, numberOfPointsPerLOD, indexes);
} }
void reconstructedPointCloud(const PCCTMC3Encoder3Parameters &params, void reconstructedPointCloud(const PCCTMC3Encoder3Parameters &params,
...@@ -616,8 +616,7 @@ class PCCTMC3Encoder3 { ...@@ -616,8 +616,7 @@ class PCCTMC3Encoder3 {
const auto quantizedPoint = pointCloud[i]; const auto quantizedPoint = pointCloud[i];
auto &point = (*reconstructedCloud)[i]; auto &point = (*reconstructedCloud)[i];
for (size_t k = 0; k < 3; ++k) { for (size_t k = 0; k < 3; ++k) {
point[k] = quantizedPoint[k] * invScale + minPositions[k]; point[k] = quantizedPoint[k] * invScale + minPositions[k];
// point[k] = std::round(quantizedPoint[k] * invScale + minPositions[k]);
} }
if (pointCloud.hasColors()) { if (pointCloud.hasColors()) {
reconstructedCloud->setColor(i, pointCloud.getColor(i)); reconstructedCloud->setColor(i, pointCloud.getColor(i));
......
...@@ -125,6 +125,8 @@ bool ParseParameters(int argc, char *argv[], Parameters &params) { ...@@ -125,6 +125,8 @@ bool ParseParameters(int argc, char *argv[], Parameters &params) {
if (++i < argc) params.encodeParameters.positionQuantizationScale = atof(argv[i]); if (++i < argc) params.encodeParameters.positionQuantizationScale = atof(argv[i]);
} else if (!strcmp(argv[i], "--mergeDuplicatedPoints")) { } else if (!strcmp(argv[i], "--mergeDuplicatedPoints")) {
if (++i < argc) params.encodeParameters.mergeDuplicatedPoints = atoi(argv[i]) != 0; if (++i < argc) params.encodeParameters.mergeDuplicatedPoints = atoi(argv[i]) != 0;
} else if (!strcmp(argv[i], "--roundOutputPositions")) {
if (++i < argc) params.roundOutputPositions = atoi(argv[i]) != 0;
} }
} }
...@@ -150,7 +152,7 @@ bool ParseParameters(int argc, char *argv[], Parameters &params) { ...@@ -150,7 +152,7 @@ bool ParseParameters(int argc, char *argv[], Parameters &params) {
<< endl; << endl;
cout << "\t positionQuantizationScale " << params.encodeParameters.positionQuantizationScale cout << "\t positionQuantizationScale " << params.encodeParameters.positionQuantizationScale
<< endl; << endl;
for (const auto attributeEncodeParameters : params.encodeParameters.attributeEncodeParameters) { for (const auto & attributeEncodeParameters : params.encodeParameters.attributeEncodeParameters) {
cout << "\t " << attributeEncodeParameters.first << endl; cout << "\t " << attributeEncodeParameters.first << endl;
cout << "\t\t numberOfNearestNeighborsInPrediction " cout << "\t\t numberOfNearestNeighborsInPrediction "
<< attributeEncodeParameters.second.numberOfNearestNeighborsInPrediction << endl; << attributeEncodeParameters.second.numberOfNearestNeighborsInPrediction << endl;
...@@ -175,6 +177,8 @@ bool ParseParameters(int argc, char *argv[], Parameters &params) { ...@@ -175,6 +177,8 @@ bool ParseParameters(int argc, char *argv[], Parameters &params) {
cout << endl; cout << endl;
} }
cout << endl; cout << endl;
} else {
cout << "\t roundOutputPositions " << params.roundOutputPositions << endl;
} }
const bool test1 = const bool test1 =
...@@ -270,7 +274,7 @@ int Decompress(const Parameters &params) { ...@@ -270,7 +274,7 @@ int Decompress(const Parameters &params) {
pointCloud.removeColors(); pointCloud.removeColors();
} }
if ((params.mode == CODEC_MODE_DECODE && decoder.decompress(bitstream, pointCloud)) || if ((params.mode == CODEC_MODE_DECODE && decoder.decompress(bitstream, pointCloud, params.roundOutputPositions)) ||
(params.mode == CODEC_MODE_DECODE_LOSSLESS_GEOMETRY && (params.mode == CODEC_MODE_DECODE_LOSSLESS_GEOMETRY &&
decoder.decompressWithLosslessGeometry(bitstream, pointCloud))) { decoder.decompressWithLosslessGeometry(bitstream, pointCloud))) {
cout << "Error: can't decompress point cloud!" << endl; cout << "Error: can't decompress point cloud!" << endl;
......
...@@ -71,11 +71,13 @@ struct Parameters { ...@@ -71,11 +71,13 @@ struct Parameters {
std::string reconstructedDataPath; std::string reconstructedDataPath;
size_t colorTransform; size_t colorTransform;
size_t mode; size_t mode;
bool roundOutputPositions;
pcc::PCCTMC3Encoder3Parameters encodeParameters; pcc::PCCTMC3Encoder3Parameters encodeParameters;
Parameters(void) { Parameters(void) {
mode = CODEC_MODE_ENCODE; mode = CODEC_MODE_ENCODE;
colorTransform = COLOR_TRANSFORM_RGB_TO_YCBCR; colorTransform = COLOR_TRANSFORM_RGB_TO_YCBCR;
roundOutputPositions = false;
} }
}; };
......
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