Ejemplo n.º 1
0
                public IEnumerator EncodeFragments(MemoryRef <Binary> binary, TaggedInterval[] intervals, FragmentFactory factory, string fragmentTypeName, Action <ProgressInfo> progressFeedback)
                {
                    progressFeedback.Invoke(new ProgressInfo()
                    {
                        title    = $"Start {fragmentTypeName} fragment encoder",
                        progress = 0.0f
                    });
                    //
                    // Prologue
                    //

                    int metricIndex = settings.metricIndex;

                    var numFeatures = factory.GetNumFeatures(ref binary.Ref, metricIndex);

                    var numQuantizedFeatures = factory.GetNumQuantizedFeatures(ref binary.Ref, metricIndex);

                    var numNormalizedFeatures = factory.GetNumNormalizedFeatures(ref binary.Ref, metricIndex);

                    var numTransformedFeatures = numFeatures - numQuantizedFeatures - numNormalizedFeatures;

                    numFragments = 0;

                    foreach (var interval in intervals)
                    {
                        numFragments += interval.numFrames;
                    }

                    //
                    // Generate fragments
                    //

                    FragmentArray fragmentArray = FragmentArray.Create(metricIndex, numFragments, numFeatures);

                    int writeIndex = 0;

                    foreach (var interval in intervals)
                    {
                        int segmentIndex = interval.segmentIndex;

                        Assert.IsTrue(
                            interval.firstFrame >=
                            interval.segment.destination.FirstFrame);

                        Assert.IsTrue(
                            interval.onePastLastFrame <=
                            interval.segment.destination.OnePastLastFrame);

                        int relativeFirstFrame =
                            interval.firstFrame -
                            interval.segment.destination.FirstFrame;

                        int numFrames = interval.numFrames;

                        for (int i = 0; i < numFrames; ++i)
                        {
                            int frameIndex = relativeFirstFrame + i;

                            var timeIndex =
                                TimeIndex.Create(
                                    segmentIndex, frameIndex);

                            var samplingTime =
                                SamplingTime.Create(timeIndex);


                            fragmentArray.samplingTimes[writeIndex++] = samplingTime;
                        }
                    }

                    Assert.IsTrue(writeIndex == numFragments);

                    progressFeedback.Invoke(new ProgressInfo()
                    {
                        title    = $"Create {fragmentTypeName} fragments",
                        progress = 0.0f
                    });

                    ICreateFragmentsJob createFragmentsJob    = factory.PrepareFragmentCreateJob(ref fragmentArray, ref binary.Ref);
                    JobHandle           createFragmentsHandle = createFragmentsJob.Schedule();

                    yield return(null);

                    if (bCancel)
                    {
                        createFragmentsHandle.Complete();
                        fragmentArray.Dispose();
                        yield break;
                    }

                    createFragmentsHandle.Complete();

                    progressFeedback.Invoke(new ProgressInfo()
                    {
                        title    = $"Quantize {fragmentTypeName} fragments",
                        progress = 0.0f
                    });

                    //
                    // Generate feature quantizers
                    //

                    quantizers =
                        new NativeArray <Quantizer>(
                            numQuantizedFeatures, Allocator.Persistent);

                    ComputeQuantizersJob computeQuantizersJob = new ComputeQuantizersJob()
                    {
                        fragmentArray = fragmentArray,
                        quantizers    = Quantizers
                    };

                    JobHandle computeQuantizersHandle = computeQuantizersJob.Schedule(numQuantizedFeatures, 1);

                    computeQuantizersHandle.Complete();


                    //
                    // Quantize magnitudes and normalize fragments
                    //

                    int numQuantizedValues = numFragments * numQuantizedFeatures;

                    quantizedValues =
                        new NativeArray <byte>(
                            numQuantizedValues, Allocator.Persistent);

                    NormalizeFeaturesJob normalizeFeaturesJob = new NormalizeFeaturesJob()
                    {
                        numQuantizedFeatures = numQuantizedFeatures,
                        quantizers           = Quantizers,
                        quantizedValues      = new MemoryArray <byte>(QuantizedValues),
                        fragmentArray        = fragmentArray
                    };

                    JobHandle normalizeFeaturesHandle = normalizeFeaturesJob.Schedule(numFragments, 1);

                    normalizeFeaturesHandle.Complete();

                    //
                    // Generate bounding boxes for feature normalization
                    //

                    boundingBoxes =
                        new NativeArray <BoundingBox>(
                            numTransformedFeatures, Allocator.Persistent);

                    ComputeBoundingBoxesJob computeBoundingBoxesJob = new ComputeBoundingBoxesJob()
                    {
                        fragmentArray          = fragmentArray,
                        numTransformedFeatures = numTransformedFeatures,
                        transformedIndex       = numFeatures - numTransformedFeatures,
                        boundingBoxes          = BoundingBoxes
                    };

                    JobHandle computeBoundingBoxesHandle = computeBoundingBoxesJob.Schedule(numTransformedFeatures, 1);

                    computeBoundingBoxesHandle.Complete();

                    //
                    // Normalize fragments
                    //

                    NormalizeFragmentsJob normalizeFragmentsJob = new NormalizeFragmentsJob()
                    {
                        numTransformedFeatures = numTransformedFeatures,
                        transformedIndex       = numFeatures - numTransformedFeatures,
                        boundingBoxes          = BoundingBoxes,
                        fragmentArray          = fragmentArray
                    };

                    JobHandle normalizeFragmentsHandle = normalizeFragmentsJob.Schedule(numFragments, 1);

                    normalizeFragmentsHandle.Complete();


                    //
                    // Product Quantization
                    //

                    progressFeedback.Invoke(new ProgressInfo()
                    {
                        title    = $"Prepare training {fragmentTypeName} fragments",
                        progress = 0.0f
                    });

                    yield return(null);

                    if (bCancel)
                    {
                        fragmentArray.Dispose();
                        yield break;
                    }

                    int numCodes = numFragments * numFeatures;

                    int numCodeWords = numFeatures * Binary.CodeBook.kNumCodeValues;

                    codes = new NativeArray <byte>(numCodes, Allocator.Persistent);

                    codeWords = new NativeArray <float3>(numCodeWords, Allocator.Persistent);

                    var pqs = ProductQuantizer.Settings.Default;

                    pqs.numAttempts          = settings.numAttempts;
                    pqs.numIterations        = settings.numIterations;
                    pqs.minimumNumberSamples = settings.minimumNumberSamples;
                    pqs.maximumNumberSamples = settings.maximumNumberSamples;

                    using (var pq = new ProductQuantizer(numFeatures * 3, numFeatures, pqs))
                    {
                        using (ProductQuantizer.TrainingData trainingData = pq.ScheduleTraining(ref fragmentArray))
                        {
                            float progression = 0.0f;
                            do
                            {
                                progression = trainingData.FrameUpdate();

                                progressFeedback.Invoke(new ProgressInfo()
                                {
                                    title    = $"Train {fragmentTypeName} fragments",
                                    progress = progression
                                });

                                yield return(null);

                                if (bCancel)
                                {
                                    trainingData.ForceCompleteCurrentBatch();
                                    fragmentArray.Dispose();
                                    yield break;
                                }
                            }while (progression < 1.0f);

                            trainingData.ForceCompleteCurrentBatch();
                        }

                        progressFeedback.Invoke(new ProgressInfo()
                        {
                            title    = $"Compute {fragmentTypeName} codes",
                            progress = 0.0f
                        });
                        pq.ComputeCodes(ref fragmentArray, Codes);

                        Assert.IsTrue(pq.centroids.Length == numCodeWords * 3);

                        for (int i = 0; i < numCodeWords; ++i)
                        {
                            float x = pq.centroids[i * 3 + 0];
                            float y = pq.centroids[i * 3 + 1];
                            float z = pq.centroids[i * 3 + 2];

                            var centroid = new float3(x, y, z);

                            var words = CodeWords;
                            words[i] = centroid;
                        }
                    }

                    fragmentArray.Dispose();
                }
Ejemplo n.º 2
0
 public ICreateFragmentsJob PrepareFragmentCreateJob(ref FragmentArray fragmentArray, ref Binary binary)
 {
     return(CreateTrajectoryFragmentsJob.Prepare(ref fragmentArray, ref binary));
 }