Search in sources :

Example 1 with DogArray_I32

use of org.ddogleg.struct.DogArray_I32 in project BoofCV by lessthanoptimal.

the class ComputeMeanTuple_MT_U8 method process.

@Override
public void process(LArrayAccessor<TupleDesc_U8> points, DogArray_I32 assignments, FastAccess<TupleDesc_U8> clusters) {
    // see if it should run the single thread version instead
    if (points.size() < minimumForConcurrent) {
        super.process(points, assignments, clusters);
        return;
    }
    if (assignments.size != points.size())
        throw new IllegalArgumentException("Points and assignments need to be the same size");
    // Compute the sum of all points in each cluster
    BoofConcurrency.loopBlocks(0, points.size(), threadData, (data, idx0, idx1) -> {
        final TupleDesc_U8 tuple = data.point;
        final DogArray<int[]> sums = data.clusterSums;
        sums.resize(clusters.size);
        for (int i = 0; i < sums.size; i++) {
            Arrays.fill(sums.data[i], 0);
        }
        final DogArray_I32 counts = data.counts;
        counts.resize(sums.size, 0);
        for (int pointIdx = idx0; pointIdx < idx1; pointIdx++) {
            points.getCopy(pointIdx, tuple);
            final byte[] point = tuple.data;
            int clusterIdx = assignments.get(pointIdx);
            counts.data[clusterIdx]++;
            int[] sum = sums.get(clusterIdx);
            for (int i = 0; i < point.length; i++) {
                sum[i] += point[i] & 0xFF;
            }
        }
    });
    // Stitch results from threads back together
    counts.reset();
    counts.resize(clusters.size, 0);
    means.resize(clusters.size);
    for (int i = 0; i < clusters.size; i++) {
        Arrays.fill(means.data[i], 0);
    }
    for (int threadIdx = 0; threadIdx < threadData.size(); threadIdx++) {
        ThreadData data = threadData.get(threadIdx);
        for (int clusterIdx = 0; clusterIdx < clusters.size; clusterIdx++) {
            int[] a = data.clusterSums.get(clusterIdx);
            int[] b = means.get(clusterIdx);
            for (int i = 0; i < b.length; i++) {
                b[i] += a[i];
            }
            counts.data[clusterIdx] += data.counts.data[clusterIdx];
        }
    }
    // Divide to get the average value in each cluster
    for (int clusterIdx = 0; clusterIdx < clusters.size; clusterIdx++) {
        int[] sum = means.get(clusterIdx);
        byte[] cluster = clusters.get(clusterIdx).data;
        double divisor = counts.get(clusterIdx);
        for (int i = 0; i < cluster.length; i++) {
            cluster[i] = (byte) (sum[i] / divisor);
        }
    }
}
Also used : TupleDesc_U8(boofcv.struct.feature.TupleDesc_U8) DogArray_I32(org.ddogleg.struct.DogArray_I32)

Example 2 with DogArray_I32

use of org.ddogleg.struct.DogArray_I32 in project BoofCV by lessthanoptimal.

the class TestComputeMedianTuple_MT_B method compare.

@Test
void compare() {
    int DOF = 510;
    int numClusters = 4;
    // Create a list of random points
    List<TupleDesc_B> list = new ArrayList<>();
    var assignments = new DogArray_I32(1000);
    for (int i = 0; i < 1000; i++) {
        assignments.add(rand.nextInt(numClusters));
        var t = new TupleDesc_B(DOF);
        for (int j = 0; j < t.data.length; j++) {
            t.data[j] = rand.nextInt();
        }
        list.add(t);
    }
    var points = new ListAccessor<>(list, (src, dst) -> dst.setTo(src), TupleDesc_B.class);
    var clustersSingle = new DogArray<>(() -> new TupleDesc_B(DOF));
    var clustersMulti = new DogArray<>(() -> new TupleDesc_B(DOF));
    clustersSingle.resize(numClusters);
    clustersMulti.resize(numClusters);
    var single = new ComputeMedianTuple_B(DOF);
    var multi = new ComputeMedianTuple_MT_B(DOF);
    single.process(points, assignments, clustersSingle);
    multi.process(points, assignments, clustersMulti);
    assertEquals(clustersSingle.size, clustersMulti.size);
    for (int i = 0; i < numClusters; i++) {
        assertArrayEquals(clustersSingle.get(i).data, clustersMulti.get(i).data);
    }
}
Also used : ListAccessor(org.ddogleg.clustering.misc.ListAccessor) TupleDesc_B(boofcv.struct.feature.TupleDesc_B) ArrayList(java.util.ArrayList) DogArray_I32(org.ddogleg.struct.DogArray_I32) DogArray(org.ddogleg.struct.DogArray) Test(org.junit.jupiter.api.Test)

Example 3 with DogArray_I32

use of org.ddogleg.struct.DogArray_I32 in project BoofCV by lessthanoptimal.

the class TestRecognitionVocabularyTreeNister2006 method describe.

@Test
void describe() {
    HierarchicalVocabularyTree<Point2D_F64> tree = create2x2Tree();
    // Add a few features at the leaves
    List<Point2D_F64> imageFeatures = new ArrayList<>();
    for (int i = 0; i < 3; i++) {
        imageFeatures.add(new Point2D_F64(-5, -1));
        imageFeatures.add(new Point2D_F64(5, -1));
    }
    // TF-IDF descriptor
    var descWeights = new DogArray_F32();
    var descWords = new DogArray_I32();
    var alg = new RecognitionVocabularyTreeNister2006<Point2D_F64>();
    alg.initializeTree(tree);
    alg.describe(imageFeatures, descWeights, descWords);
    // See if the description is as expected
    assertEquals(4, descWeights.size());
    assertEquals(4, descWords.size());
    // All the expected nodes should have values
    float f1 = descWeights.get(descWords.indexOf(1));
    float f2 = descWeights.get(descWords.indexOf(2));
    float f3 = descWeights.get(descWords.indexOf(3));
    float f5 = descWeights.get(descWords.indexOf(5));
    assertTrue(f1 > 0 && f2 > 0 && f3 > 0 && f5 > 0);
    assertTrue(f1 < f2);
    assertTrue(f3 < f5);
    // L2-norm should be 1.0
    float norm = (float) Math.sqrt(f1 * f1 + f2 * f2 + f3 * f3 + f5 * f5);
    assertEquals(1.0f, norm, UtilEjml.TEST_F32);
}
Also used : Point2D_F64(georegression.struct.point.Point2D_F64) ArrayList(java.util.ArrayList) DogArray_I32(org.ddogleg.struct.DogArray_I32) DogArray_F32(org.ddogleg.struct.DogArray_F32) Test(org.junit.jupiter.api.Test)

Example 4 with DogArray_I32

use of org.ddogleg.struct.DogArray_I32 in project BoofCV by lessthanoptimal.

the class TestComputeMeanTuple_MT_F64 method compare.

@Test
void compare() {
    int DOF = 31;
    int numClusters = 4;
    // Create a list of random points
    List<TupleDesc_F64> list = new ArrayList<>();
    var assignments = new DogArray_I32(1000);
    for (int i = 0; i < 1000; i++) {
        assignments.add(rand.nextInt(numClusters));
        var t = new TupleDesc_F64(DOF);
        for (int j = 0; j < DOF; j++) {
            t.data[j] = rand.nextDouble();
        }
        list.add(t);
    }
    var points = new ListAccessor<>(list, (src, dst) -> dst.setTo(src), TupleDesc_F64.class);
    var clustersSingle = new DogArray<>(() -> new TupleDesc_F64(DOF));
    var clustersMulti = new DogArray<>(() -> new TupleDesc_F64(DOF));
    clustersSingle.resize(numClusters);
    clustersMulti.resize(numClusters);
    var single = new ComputeMeanTuple_F64();
    var multi = new ComputeMeanTuple_MT_F64(DOF);
    single.process(points, assignments, clustersSingle);
    multi.process(points, assignments, clustersMulti);
    assertEquals(clustersSingle.size, clustersMulti.size);
    for (int i = 0; i < numClusters; i++) {
        assertArrayEquals(clustersSingle.get(i).data, clustersMulti.get(i).data, UtilEjml.TEST_F64);
    }
}
Also used : ListAccessor(org.ddogleg.clustering.misc.ListAccessor) TupleDesc_F64(boofcv.struct.feature.TupleDesc_F64) ArrayList(java.util.ArrayList) DogArray_I32(org.ddogleg.struct.DogArray_I32) DogArray(org.ddogleg.struct.DogArray) Test(org.junit.jupiter.api.Test)

Example 5 with DogArray_I32

use of org.ddogleg.struct.DogArray_I32 in project BoofCV by lessthanoptimal.

the class ComputeMedianTuple_MT_B method countBitsInEachCluster.

@Override
protected void countBitsInEachCluster(LArrayAccessor<TupleDesc_B> points, DogArray_I32 assignments) {
    if (points.size() < minimumForConcurrent) {
        super.countBitsInEachCluster(points, assignments);
        return;
    }
    int numClusters = super.assignmentCounts.size;
    // Compute the sum of all points in each cluster
    BoofConcurrency.loopBlocks(0, points.size(), threadData, (data, idx0, idx1) -> {
        final TupleDesc_B tuple = data.point;
        final DogArray<int[]> bitCounts = data.bitCounts;
        final DogArray_I32 assignmentCounts = data.assignmentCounts;
        assignmentCounts.resetResize(numClusters, 0);
        bitCounts.resize(numClusters);
        for (int i = 0; i < bitCounts.size; i++) {
            Arrays.fill(bitCounts.data[i], 0);
        }
        // Compute the sum of all points in each cluster
        for (int pointIdx = idx0; pointIdx < idx1; pointIdx++) {
            // See which cluster this point was assigned to and increment its counter
            int clusterIdx = assignments.get(pointIdx);
            assignmentCounts.data[clusterIdx]++;
            points.getCopy(pointIdx, tuple);
            // Increment the counter for each "true" bit in the tuple
            int[] bitCount = bitCounts.get(clusterIdx);
            int bit = 0;
            while (bit + 32 < dof) {
                // Unroll for speed
                int value = tuple.data[bit / 32];
                if ((value & 0x00000001) != 0)
                    bitCount[bit]++;
                if ((value & 0x00000002) != 0)
                    bitCount[bit + 1]++;
                if ((value & 0x00000004) != 0)
                    bitCount[bit + 2]++;
                if ((value & 0x00000008) != 0)
                    bitCount[bit + 3]++;
                if ((value & 0x00000010) != 0)
                    bitCount[bit + 4]++;
                if ((value & 0x00000020) != 0)
                    bitCount[bit + 5]++;
                if ((value & 0x00000040) != 0)
                    bitCount[bit + 6]++;
                if ((value & 0x00000080) != 0)
                    bitCount[bit + 7]++;
                if ((value & 0x00000100) != 0)
                    bitCount[bit + 8]++;
                if ((value & 0x00000200) != 0)
                    bitCount[bit + 9]++;
                if ((value & 0x00000400) != 0)
                    bitCount[bit + 10]++;
                if ((value & 0x00000800) != 0)
                    bitCount[bit + 11]++;
                if ((value & 0x00001000) != 0)
                    bitCount[bit + 12]++;
                if ((value & 0x00002000) != 0)
                    bitCount[bit + 13]++;
                if ((value & 0x00004000) != 0)
                    bitCount[bit + 14]++;
                if ((value & 0x00008000) != 0)
                    bitCount[bit + 15]++;
                if ((value & 0x00010000) != 0)
                    bitCount[bit + 16]++;
                if ((value & 0x00020000) != 0)
                    bitCount[bit + 17]++;
                if ((value & 0x00040000) != 0)
                    bitCount[bit + 18]++;
                if ((value & 0x00080000) != 0)
                    bitCount[bit + 19]++;
                if ((value & 0x00100000) != 0)
                    bitCount[bit + 20]++;
                if ((value & 0x00200000) != 0)
                    bitCount[bit + 21]++;
                if ((value & 0x00400000) != 0)
                    bitCount[bit + 22]++;
                if ((value & 0x00800000) != 0)
                    bitCount[bit + 23]++;
                if ((value & 0x01000000) != 0)
                    bitCount[bit + 24]++;
                if ((value & 0x02000000) != 0)
                    bitCount[bit + 25]++;
                if ((value & 0x04000000) != 0)
                    bitCount[bit + 26]++;
                if ((value & 0x08000000) != 0)
                    bitCount[bit + 27]++;
                if ((value & 0x10000000) != 0)
                    bitCount[bit + 28]++;
                if ((value & 0x20000000) != 0)
                    bitCount[bit + 29]++;
                if ((value & 0x40000000) != 0)
                    bitCount[bit + 30]++;
                if ((value & 0x80000000) != 0)
                    bitCount[bit + 31]++;
                bit += 32;
            }
            // handle the remainder if it doesn't align with 32-bit integers
            for (; bit < dof; bit++) {
                if (!tuple.isBitTrue(bit))
                    continue;
                bitCount[bit]++;
            }
        }
    });
    // stitch all the threads back together
    for (int threadIdx = 0; threadIdx < threadData.size(); threadIdx++) {
        ThreadData data = threadData.get(threadIdx);
        for (int clusterIdx = 0; clusterIdx < numClusters; clusterIdx++) {
            super.assignmentCounts.data[clusterIdx] += data.assignmentCounts.data[clusterIdx];
            int[] allCounts = super.bitCounts.get(clusterIdx);
            int[] threadCounts = data.bitCounts.get(clusterIdx);
            for (int bitIdx = 0; bitIdx < dof; bitIdx++) {
                allCounts[bitIdx] += threadCounts[bitIdx];
            }
        }
    }
}
Also used : TupleDesc_B(boofcv.struct.feature.TupleDesc_B) DogArray_I32(org.ddogleg.struct.DogArray_I32)

Aggregations

DogArray_I32 (org.ddogleg.struct.DogArray_I32)192 Test (org.junit.jupiter.api.Test)73 Point2D_I32 (georegression.struct.point.Point2D_I32)24 ArrayList (java.util.ArrayList)21 Point2D_F64 (georegression.struct.point.Point2D_F64)17 DogArray (org.ddogleg.struct.DogArray)17 TupleDesc_F64 (boofcv.struct.feature.TupleDesc_F64)15 GrayS32 (boofcv.struct.image.GrayS32)10 VerbosePrint (org.ddogleg.struct.VerbosePrint)7 View (boofcv.alg.structure.PairwiseImageGraph.View)6 AssociatedIndex (boofcv.struct.feature.AssociatedIndex)6 GrayI (boofcv.struct.image.GrayI)5 Point3D_F64 (georegression.struct.point.Point3D_F64)5 GrowArray (pabeles.concurrency.GrowArray)5 DetectDescribePoint (boofcv.abst.feature.detdesc.DetectDescribePoint)4 BTrack (boofcv.alg.sfm.d3.structure.VisOdomBundleAdjustment.BTrack)4 AssociatedTripleIndex (boofcv.struct.feature.AssociatedTripleIndex)4 SceneObservations (boofcv.abst.geo.bundle.SceneObservations)3 SceneWorkingGraph (boofcv.alg.structure.SceneWorkingGraph)3 ConfigAssociateGreedy (boofcv.factory.feature.associate.ConfigAssociateGreedy)3