Пример #1
0
 /// <summary>
 /// Returns the maximal absolute distance between the components of
 /// the two matrices.
 /// </summary>
 public static __ftype__ DistanceMax(__nmtype__ a, __nmtype__ b)
 {
     return(Fun.Max(     /*# n.ForEach(i => { */
                Fun.Max( /*# m.ForEach(j => { */
                    Fun.Abs(b.M__i____j__ - a.M__i____j__) /*#
                                                            * }, comma); */) /*# }, comma); */));
 }
Пример #2
0
        /// <summary>
        /// Uses the 2 random series (seriesIndex, seriesIndex+1)
        /// </summary>
        public static V3d Spherical(
            IRandomSeries rnds, int seriesIndex)
        {
            double phi = Constant.PiTimesTwo * rnds.UniformDouble(seriesIndex);
            double z   = 1.0 - 2.0 * rnds.UniformDouble(seriesIndex + 1);
            double r   = Fun.Max(1.0 - z * z, 0.0).Sqrt();

            return(new V3d(r * phi.Cos(), r * phi.Sin(), z));
        }
Пример #3
0
        /// <summary>
        /// Stitches the images provided in the 2D array into one large image according to the position in the array.
        /// The array is treated as column-major. Therefore, the array
        /// {{1, 2, 3}}
        /// {{4, 5, 6}}
        /// produces the image
        /// 1 2 3
        /// 4 6 7
        /// Null-items are allowed an result in black spot at the corresponding position.
        /// The color format of all images must be equal and have byte format.
        /// </summary>
        /// <param name="images">The 2D image array that should be stitched.</param>
        /// <returns>Stitched image</returns>
        public static PixImage <T> Stitch <T>(this PixImage <T>[][] images)
        {
            if (images.IsEmptyOrNull())
            {
                return(null);
            }
            // Find largest extensions
            var numRows    = images.Length;
            var numColumns = images.Max(img => img.Length);

            // Find largest X Y
            var sizesX = new int[numColumns].SetByIndex(c => images.Max(ic => (ic[c] == null) ? 0 : ic[c].Size.X));
            var sizesY = images.Map(img => img.Max(img2 => (img2 == null) ? 0 : img2.Size.Y));
            var width  = sizesX.Sum();
            var height = sizesY.Sum();

            // The first image in the array, used to determine the color format
            var fst = images.First(img => img.Length > 0).First(img => img != null);

            if (fst == null)
            {
                Report.Line("Empty image array!");
                return(null);
            }

            // Assure that the color format fits
            if (images.TrueForAny(imgs => imgs.Where(i => i != null).TrueForAny(img => img.Format != fst.Format)))
            {
                Report.Line("Color format not matching!");
                return(null);
            }

            // Allocate new image
            var target = new PixImage <T>(fst.Format, new V2i(width, height));

            for (int r = 0, y = 0; r < numRows; r++)
            {
                for (int c = 0, x = 0; c < Fun.Max(numColumns, images[r].Length); c++)
                {
                    var source = images[r][c];
                    if (source != null)
                    {
                        target.Set(x, y, source);
                    }
                    x += sizesX[c];
                }
                y += sizesY[r];
            }
            return(target);
        }
Пример #4
0
        /// <summary>
        /// UnDistortion of pixel coordinates.
        /// </summary>
        public V2d UndistortPixel(V2d p2, V2i imageSize)
        {
            var maxSize = Fun.Max(imageSize.X, imageSize.Y);
            var y       = (p2.Y - PrincipalPoint.Y * imageSize.Y) / (FocalLength.Y * maxSize);
            var x       = (p2.X - PrincipalPoint.X * imageSize.X - Skew * maxSize * y) / (FocalLength.X * maxSize);

            ComputeUndistortionParamsForCameraPoint(x, y, out double rd, out double tx, out double ty);
            double xd = x * rd + tx;
            double yd = y * rd + ty;

            return(new V2d(
                       FocalLength.X * maxSize * xd + Skew * maxSize * yd + PrincipalPoint.X * imageSize.X,
                       FocalLength.Y * maxSize * yd + PrincipalPoint.Y * imageSize.Y));
        }
Пример #5
0
        /// <summary>
        /// Supplied normal MUST be normalized, uses the 2 random series
        /// (seriesIndex, seriesIndex+1).
        /// </summary>
        public static V3d Lambertian(
            V3d normal, IRandomSeries rnds, int seriesIndex)
        {
            V3d    vec;
            double squareLen;

            do
            {
                double phi = Constant.PiTimesTwo * rnds.UniformDouble(seriesIndex);
                double z   = 1.0 - 2.0 * rnds.UniformDouble(seriesIndex + 1);
                double r   = Fun.Max(1.0 - z * z, 0.0).Sqrt();
                vec       = new V3d(r * phi.Cos(), r * phi.Sin(), z) + normal;
                squareLen = vec.LengthSquared;
            }while (squareLen < 0.000001);

            vec *= 1.0 / squareLen.Sqrt();
            return(vec);
        }
Пример #6
0
        /// <summary>
        /// Project a point from camera space into image space according to the intrinsic camera parameters.
        /// This documents the camera model.
        /// </summary>
        public V2d ProjectToImage(V3d p, V2d imageSize)
        {
            // projection
            double x = p.X / p.Z;
            double y = p.Y / p.Z;

            // undo distortion here
            ComputeUndistortionParamsForCameraPoint(x, y, out double rd, out double tx, out double ty);

            // undistorted point:
            double xd = x * rd + tx;
            double yd = y * rd + ty;

            double maxSize = Fun.Max(imageSize.X, imageSize.Y);

            // point in image:
            return(new V2d(
                       FocalLength.X * maxSize * xd + Skew * maxSize * yd + PrincipalPoint.X * imageSize.X,
                       FocalLength.Y * maxSize * yd + PrincipalPoint.Y * imageSize.Y));
        }
Пример #7
0
        /// <summary>
        /// Compute the Delaunay triangluation of the supplied points. Note that
        /// the supplied point array must be by 3 larger than the actual number of
        /// points.
        /// </summary>
        private static void Triangulate2d(V2d[] pa,
                                          out Triangle1i[] ta, out int triangleCount)
        {
            int vc    = pa.Length - 4;
            int tcMax = 2 * vc + 2; // sharp upper bound with no degenerates
            int ecMax = 6 * vc - 3; // sharp bound: last step replaces all tris

            ta = new Triangle1i[tcMax];
            var ra = new double[tcMax];
            var ca = new V2d[tcMax];
            var ea = new Line1i[ecMax];

            // -------------------------------------- set up the supertriangle
            ta[0] = new Triangle1i(vc, vc + 2, vc + 1);
            ra[0] = -1.0;
            ta[1] = new Triangle1i(vc, vc + 3, vc + 2);
            ra[1] = -1.0;
            int tc = 2, cc = 0; // triangle count, complete count

            // ------------- superquad vertices at the end of vertex array
            var box = new Box2d(pa.Take(vc)).EnlargedBy(0.1);
            V2d center = box.Center, size = box.Size;

            pa[vc + 0] = box.Min;
            pa[vc + 1] = new V2d(box.Min.X, box.Max.Y);
            pa[vc + 2] = box.Max;
            pa[vc + 3] = new V2d(box.Max.X, box.Min.Y);

            // ------------------------------ include the points one at a time
            for (int i = 0; i < vc; i++)
            {
                V2d p  = pa[i];
                int ec = 0;

                /*
                 * if the point lies inside the circumcircle then the triangle
                 * is removed and its edges are added to the edge array
                 */
                for (int ti = cc; ti < tc; ti++)
                {
                    var    tr = ta[ti];
                    double r2 = ra[ti];
                    if (r2 < 0.0)
                    {
                        Triangle2d.ComputeCircumCircleSquared(
                            pa[tr.I0], pa[tr.I1], pa[tr.I2],
                            out center, out r2);
                        ra[ti] = r2; ca[ti] = center;
                    }
                    else
                    {
                        center = ca[ti];
                    }

                    // ---------------- include this if points are sorted by X
                    if (center.X < p.X && (p.X - center.X).Square() > r2)
                    {
                        Fun.Swap(ref ta[ti], ref ta[cc]);
                        ra[ti] = ra[cc]; ca[ti] = ca[cc];
                        ++cc; continue;
                    }
                    if (Vec.DistanceSquared(p, center) <= r2)
                    {
                        int nec = ec + 3;
                        if (nec >= ecMax)
                        {
                            ecMax = Fun.Max(nec, (int)(1.1 * (double)ecMax));
                            Array.Resize(ref ea, ecMax);
                        }
                        ea[ec]   = tr.Line01; ea[ec + 1] = tr.Line12; ea[ec + 2] = tr.Line20;
                        --tc; ec = nec;
                        ta[ti]   = ta[tc]; ra[ti] = ra[tc]; ca[ti] = ca[tc];
                        --ti;
                    }
                }

                // ---------------------------------------- tag multiple edges
                for (int ei = 0; ei < ec - 1; ei++)
                {
                    for (int ej = ei + 1; ej < ec; ej++)
                    {
                        if (ea[ei].I0 == ea[ej].I1 && ea[ei].I1 == ea[ej].I0)
                        {
                            ea[ei] = Line1i.Invalid; ea[ej] = Line1i.Invalid;
                        }
                    }
                }

                // ------------------ form new triangles for the current point
                for (int ei = 0; ei < ec; ei++)
                {
                    var e = ea[ei];
                    if (e.I0 < 0 || e.I1 < 0)
                    {
                        continue;    // skip tagged edges
                    }
                    if (tc >= tcMax) // necessary for degenerate cases
                    {
                        tcMax = Fun.Max(tcMax + 1, (int)(1.1 * (double)tcMax));
                        Array.Resize(ref ta, tcMax);
                        Array.Resize(ref ra, tcMax);
                        Array.Resize(ref ca, tcMax);
                    }
                    ta[tc]   = new Triangle1i(e.I0, e.I1, i);
                    ra[tc++] = -1.0;
                }
            }

            // ------------------ remove triangles with supertriangle vertices
            for (int ti = 0; ti < tc; ti++)
            {
                if (ta[ti].I0 >= vc || ta[ti].I1 >= vc || ta[ti].I2 >= vc)
                {
                    ta[ti--] = ta[--tc];
                }
            }

            triangleCount = tc;
        }