Пример #1
0
        public void TestPixelTransferWithTransform2(bool useBilinear)
        {
            var imgPath = System.IO.Path.Combine(TestContext.CurrentContext.TestDirectory, "Resources", "dog.jpeg");

            var img = Graphics.Bitmaps.MemoryBitmap <BGR24> .Load(imgPath);

            if (!img.AsSpanBitmap().TryGetAsSpanTensor(out var src))
            {
                throw new InvalidOperationException();
            }

            var dst  = new SpanTensor2 <BGR24>(384, 384);
            var dst2 = new SpanTensor2 <System.Numerics.Vector3>(384, 384);

            var srcX =
                System.Numerics.Matrix3x2.CreateScale(0.4f)
                * System.Numerics.Matrix3x2.CreateRotation(0.3f);

            srcX.Translation = new System.Numerics.Vector2(15, 35);

            var time = System.Diagnostics.Stopwatch.StartNew();

            dst.AsTensorBitmap(Imaging.ColorEncoding.Undefined).FillPixels(src.AsBitmapSampler(Imaging.ColorEncoding.BGR), (srcX, MultiplyAdd.Identity, useBilinear));
            time.Stop();
            TestContext.WriteLine($"{time.Elapsed.TotalMilliseconds}");

            time = System.Diagnostics.Stopwatch.StartNew();
            dst2.AsTensorBitmap(Imaging.ColorEncoding.Undefined).FillPixels(src.AsBitmapSampler(Imaging.ColorEncoding.BGR), (srcX, MultiplyAdd.Identity, useBilinear));
            time.Stop();
            TestContext.WriteLine($"{time.Elapsed.TotalMilliseconds}");

            dst.AttachToCurrentTest($"tensorTransform-{useBilinear}.png");
        }
        public static TensorIndices2 IndexOfMax <T>(this SpanTensor2 <T> tensor, IComparer <T> comparer = null)
            where T : unmanaged, IEquatable <T>
        {
            var span = tensor._Buffer;

            if (span.Length == 0)
            {
                return(TensorIndices2.Invalid);
            }

            if (comparer == null)
            {
                comparer = Comparer <T> .Default;
            }

            T   max = span[0];
            var idx = 0;

            for (int i = 1; i < span.Length; ++i)
            {
                var item = span[i];
                if (comparer.Compare(max, item) > 0)
                {
                    max = item; idx = i;
                }
            }

            return(tensor._Dimensions.GetDecomposedIndex(idx));
        }
Пример #3
0
        public void TestPixelTransferWithTransform1()
        {
            var src = new SpanTensor2 <BGR24>(16, 16);
            var dst = new SpanTensor2 <BGR24>(50, 50);

            for (int y = 0; y < src.Dimensions[0]; y++)
            {
                var row = src[y];

                for (int x = 0; x < src.Dimensions[1]; x++)
                {
                    row[x] = (y * 16, x * 16, x + y * 2);
                }
            }

            var srcX =
                System.Numerics.Matrix3x2.CreateScale(1)
                * System.Numerics.Matrix3x2.CreateRotation(0.3f);

            srcX.Translation = new System.Numerics.Vector2(-15, -35);

            dst.AsTensorBitmap(Imaging.ColorEncoding.Undefined).FillPixels(src.AsBitmapSampler(Imaging.ColorEncoding.BGR), (srcX, MultiplyAdd.Identity));

            // dst.FitPixels(src, MultiplyAdd.Identity, true);

            dst.AttachToCurrentTest("tensorTransform.png");
        }
        public static TensorIndices2 IndexOf <T>(this SpanTensor2 <T> tensor, T value)
            where T : unmanaged, IEquatable <T>
        {
            var idx = tensor._Buffer.IndexOf(value);

            if (idx < 0)
            {
                return(TensorSize2.Invalid);
            }
            return(tensor._Dimensions.GetDecomposedIndex(idx));
        }
Пример #5
0
        public void PointCloudFitting()
        {
            // https://github.com/ClayFlannigan/icp/blob/master/icp.py

            // create original point cloud
            var ppp0 = new Vector3[16];
            var rnd  = new Random(117);

            for (int i = 0; i < ppp0.Length; ++i)
            {
                var x = (float)rnd.NextDouble() * 16 - 8;
                var y = (float)rnd.NextDouble() * 16 - 8;
                var z = (float)rnd.NextDouble() * 16 - 8;
                ppp0[i] = new Vector3(x, y, z);
            }

            // create rotated point clound
            var rot = Matrix4x4.CreateFromYawPitchRoll(1, 2, 3);

            Matrix4x4.Invert(rot, out Matrix4x4 irot);

            var ppp1 = new Vector3[ppp0.Length];

            for (int i = 0; i < ppp0.Length; ++i)
            {
                ppp1[i] = Vector3.Transform(ppp0[i], rot);
            }

            // original point cloud tensor
            var t0  = SpanTensor.Wrap(ppp0);
            var t0t = new SpanTensor2 <float>(t0.Dimensions[1], t0.Dimensions[0]);

            SpanTensor.Transpose(t0, t0t);

            // rotated point cloud tensor
            var t1  = SpanTensor.Wrap(ppp1);
            var t1t = new SpanTensor2 <float>(t1.Dimensions[1], t1.Dimensions[0]);

            SpanTensor.Transpose(t1, t1t);

            // multiplied
            var combined = new SpanTensor2 <float>(3, 3);

            SpanTensor.MatrixMultiply(t1t, t0, combined);

            // decomposition
            var v = new SpanTensor2 <float>(3, 3);
            var w = new float[3];

            combined.SVD(w, v);
        }
Пример #6
0
        public void CopyTo <Tout>(SpanTensor2 <Tout> masterOut, TensorSize2 kernelSize, Kernel2Copy <T, Tout> kernel, TensorIndices2 margin = default)
            where Tout : unmanaged
        {
            var tmpSrc = new SpanTensor2 <T>(kernelSize);
            var tmpDst = new SpanTensor2 <Tout>(kernelSize);

            var stepSize = kernelSize - margin - margin;

            for (int i0 = 0; i0 < masterOut.Dimensions[0]; i0 += stepSize[0])
            {
                for (int i1 = 0; i1 < masterOut.Dimensions[1]; i1 += stepSize[1])
                {
                    var offset = new TensorIndices2(i0, i1);
                    this.CopyTo(offset, tmpSrc, default, kernelSize);
Пример #7
0
        public static void SetGrayPixels(SpanTensor2 <Single> dst, PointerBitmap src, Single offset, Single scale)
        {
            if (src.Size != dst.BitmapSize)
            {
                throw new ArgumentException(nameof(dst.BitmapSize));
            }

            var dstSpan = dst.AsSpanBitmap();
            var srcSpan = src.AsSpanBitmap();

            if (srcSpan.PixelFormat.ByteCount == 1)
            {
                SpanBitmap.CopyPixels(srcSpan.OfType <Byte>(), dstSpan, (offset, scale), (0, 1));
            }
        }
        public static TensorIndices2 IndexOf <T>(this SpanTensor2 <T> tensor, Predicate <T> predicate)
            where T : unmanaged, IEquatable <T>
        {
            var span = tensor._Buffer;

            for (int i = 0; i < span.Length; ++i)
            {
                if (predicate(span[i]))
                {
                    return(tensor._Dimensions.GetDecomposedIndex(i));
                }
            }

            return(TensorIndices2.Invalid);
        }
Пример #9
0
        public void CopyTo(TensorIndices2 srcOffset, SpanTensor2 <T> dst, TensorIndices2 dstOffset, TensorSize2 size)
        {
            size = TensorSize2.Min(size, TensorSize2.ExclusiveUnion(this.Dimensions, ref srcOffset, dst.Dimensions, ref dstOffset));

            for (int i0 = 0; i0 < size[0]; ++i0)
            {
                var srcSpan = this[srcOffset[0] + i0].Span.Slice(srcOffset[1]);
                var dstSpan = dst[dstOffset[0] + i0].Span.Slice(dstOffset[1]);

                var l1 = Math.Min(srcSpan.Length, dstSpan.Length);
                l1 = Math.Min(l1, size[1]);

                srcSpan.Slice(0, l1).CopyTo(dstSpan);
            }
        }
 public static void ApplySoftMax(this SpanTensor2 <float> tensor)
 {
     SpanTensor.ApplySoftMax(tensor.Span);
 }
Пример #11
0
        public static int SVD(this SpanTensor2 <float> a, float[] w, SpanTensor2 <float> v)
        {
            int   flag, jj, l = 0, nm = 0;
            float c, f, h, s, x, y, z;
            float anorm = 0f, g = 0f, scale = 0f;


            int m = a.Dimensions[0]; // not sure if it's 0 or 1
            int n = a.Dimensions[1]; // not sure if it's 0 or 1


            if (m < n)
            {
                // fprintf(stderr, "#rows must be > #cols \n");
                return(0);
            }

            var rv1 = new float[n]; // use stackalloc

            /* Householder reduction to bidiagonal form */
            for (int i = 0; i < n; i++)
            {
                /* left-hand reduction */
                l      = i + 1;
                rv1[i] = scale * g;
                g      = s = scale = 0f;

                if (i < m)
                {
                    for (int k = i; k < m; k++)
                    {
                        scale += Math.Abs(a[k, i]);
                    }

                    if (scale != 0)
                    {
                        for (int k = i; k < m; k++)
                        {
                            a[k, i] = (a[k, i] / scale);
                            s      += (a[k, i] * a[k, i]);
                        }
                        f       = a[i, i];
                        g       = -_Sign((float)Math.Sqrt(s), f);
                        h       = f * g - s;
                        a[i, i] = (f - g);
                        if (i != n - 1)
                        {
                            for (int j = l; j < n; j++)
                            {
                                s = 0;
                                for (int k = i; k < m; k++)
                                {
                                    s += (a[k, i] * a[k, j]);
                                }
                                f = s / h;
                                for (int k = i; k < m; k++)
                                {
                                    a[k, j] += (f * a[k, i]);
                                }
                            }
                        }
                        for (int k = i; k < m; k++)
                        {
                            a[k, i] = (a[k, i] * scale);
                        }
                    }
                }
                w[i] = (scale * g);

                /* right-hand reduction */
                g = s = scale = 0f;
                if (i < m && i != n - 1)
                {
                    for (int k = l; k < n; k++)
                    {
                        scale += Math.Abs(a[i, k]);
                    }

                    if (scale != 0)
                    {
                        for (int k = l; k < n; k++)
                        {
                            a[i, k] = (a[i, k] / scale);
                            s      += (a[i, k] * a[i, k]);
                        }
                        f       = a[i, l];
                        g       = -_Sign((float)Math.Sqrt(s), f);
                        h       = f * g - s;
                        a[i, l] = (f - g);
                        for (int k = l; k < n; k++)
                        {
                            rv1[k] = a[i, k] / h;
                        }
                        if (i != m - 1)
                        {
                            for (int j = l; j < m; j++)
                            {
                                s = 0;
                                for (int k = l; k < n; k++)
                                {
                                    s += (a[j, k] * a[i, k]);
                                }
                                for (int k = l; k < n; k++)
                                {
                                    a[j, k] += s * rv1[k];
                                }
                            }
                        }
                        for (int k = l; k < n; k++)
                        {
                            a[i, k] = (a[i, k] * scale);
                        }
                    }
                }
                anorm = Math.Max(anorm, (Math.Abs(w[i]) + Math.Abs(rv1[i])));
            }

            /* accumulate the right-hand transformation */
            for (int i = n - 1; i >= 0; i--)
            {
                if (i < n - 1)
                {
                    if (g != 0)
                    {
                        for (int j = l; j < n; j++)
                        {
                            v[j, i] = ((a[i, j] / a[i, l]) / g);
                        }
                        /* double division to avoid underflow */
                        for (int j = l; j < n; j++)
                        {
                            s = 0;
                            for (int k = l; k < n; k++)
                            {
                                s += (a[i, k] * v[k, j]);
                            }
                            for (int k = l; k < n; k++)
                            {
                                v[k, j] += (s * v[k, i]);
                            }
                        }
                    }
                    for (int j = l; j < n; j++)
                    {
                        v[i, j] = v[j, i] = 0f;
                    }
                }
                v[i, i] = 1f;
                g       = rv1[i];
                l       = i;
            }

            /* accumulate the left-hand transformation */
            for (int i = n - 1; i >= 0; i--)
            {
                l = i + 1;
                g = w[i];
                if (i < n - 1)
                {
                    for (int j = l; j < n; j++)
                    {
                        a[i, j] = 0f;
                    }
                }
                if (g != 0)
                {
                    g = 1f / g;
                    if (i != n - 1)
                    {
                        for (int j = l; j < n; j++)
                        {
                            s = 0;
                            for (int k = l; k < m; k++)
                            {
                                s += (a[k, i] * a[k, j]);
                            }
                            f = (s / a[i, i]) * g;
                            for (int k = i; k < m; k++)
                            {
                                a[k, j] += (f * a[k, i]);
                            }
                        }
                    }
                    for (int j = i; j < m; j++)
                    {
                        a[j, i] = (a[j, i] * g);
                    }
                }
                else
                {
                    for (int j = i; j < m; j++)
                    {
                        a[j, i] = 0f;
                    }
                }
                ++a[i, i];
            }

            /* diagonalize the bidiagonal form */
            for (int k = n - 1; k >= 0; k--)
            {                             /* loop over singular values */
                for (int its = 0; its < 30; its++)
                {                         /* loop over allowed iterations */
                    flag = 1;
                    for (l = k; l >= 0; l--)
                    {                     /* test for splitting */
                        nm = l - 1;
                        if (Math.Abs(rv1[l]) + anorm == anorm)
                        {
                            flag = 0; break;
                        }
                        if (Math.Abs(w[nm]) + anorm == anorm)
                        {
                            break;
                        }
                    }
                    if (flag != 0)
                    {
                        c = 0f;
                        s = 1f;
                        for (int i = l; i <= k; i++)
                        {
                            f = s * rv1[i];
                            if (Math.Abs(f) + anorm != anorm)
                            {
                                g    = w[i];
                                h    = _Pythagoras(f, g);
                                w[i] = h;
                                h    = 1f / h;
                                c    = g * h;
                                s    = -f * h;
                                for (int j = 0; j < m; j++)
                                {
                                    y        = a[j, nm];
                                    z        = a[j, i];
                                    a[j, nm] = y * c + z * s;
                                    a[j, i]  = z * c - y * s;
                                }
                            }
                        }
                    }

                    z = w[k];

                    if (l == k)
                    {                  /* convergence */
                        if (z < 0f)
                        {              /* make singular value nonnegative */
                            w[k] = -z;
                            for (int j = 0; j < n; j++)
                            {
                                v[j, k] = (-v[j, k]);
                            }
                        }
                        break;
                    }

                    if (its >= 30)
                    {
                        // fprintf(stderr, "No convergence after 30,000! iterations \n");
                        return(0);
                    }

                    /* shift from bottom 2 x 2 minor */
                    x  = w[l];
                    nm = k - 1;
                    y  = w[nm];
                    g  = rv1[nm];
                    h  = rv1[k];
                    f  = ((y - z) * (y + z) + (g - h) * (g + h)) / (2f * h * y);
                    g  = _Pythagoras(f, 1f);
                    f  = ((x - z) * (x + z) + h * ((y / (f + _Sign(g, f))) - h)) / x;

                    /* next QR transformation */
                    c = s = 1f;
                    for (int j = l; j <= nm; j++)
                    {
                        int i = j + 1;
                        g = rv1[i];
                        y = w[i];
                        h = s * g;
                        g = c * g;

                        z      = _Pythagoras(f, h);
                        rv1[j] = z;
                        c      = f / z;
                        s      = h / z;
                        f      = x * c + g * s;
                        g      = g * c - x * s;
                        h      = y * s;
                        y     *= c;

                        for (jj = 0; jj < n; jj++)
                        {
                            x        = v[jj, j];
                            z        = v[jj, i];
                            v[jj, j] = x * c + z * s;
                            v[jj, i] = z * c - x * s;
                        }

                        z    = _Pythagoras(f, h);
                        w[j] = z;
                        if (z != 0)
                        {
                            z = 1f / z; c = f * z; s = h * z;
                        }
                        f = (c * g) + (s * y);
                        x = (c * y) - (s * g);

                        for (jj = 0; jj < m; jj++)
                        {
                            y        = a[jj, j];
                            z        = a[jj, i];
                            a[jj, j] = y * c + z * s;
                            a[jj, i] = z * c - y * s;
                        }
                    }

                    rv1[l] = 0f;
                    rv1[k] = f;
                    w[k]   = x;
                }
            }

            return(1);
        }