示例#1
0
        private static Convolution2D Convolute(Convolution2D conv, ToVectorInstructions instr)
        {
            Convolution2D retVal = conv;

            if (retVal.Width != retVal.Height)
            {
                int max = Math.Max(retVal.Width, retVal.Height);
                retVal = Convolutions.ExtendBorders(retVal, max, max);      // make it square
            }

            if (instr.ShouldNormalize)
            {
                retVal = Convolutions.Normalize(retVal);
            }

            if (instr.Convolution != null)
            {
                retVal = Convolutions.Convolute(retVal, instr.Convolution);
            }

            retVal = Convolutions.MaxPool(retVal, instr.ToSize, instr.ToSize);
            retVal = Convolutions.Abs(retVal);

            return(retVal);
        }
示例#2
0
        private static SOMItem GetSOMItem_2D_Gray(VectorND item, ToVectorInstructions instr)
        {
            Convolution2D conv = new Convolution2D(item.VectorArray, instr.FromSizes[0], instr.FromSizes[1], false);

            conv = Convolute(conv, instr);

            return(new SOMItem(item, conv.Values.ToVectorND()));
        }
示例#3
0
        private static SOMItem GetSOMItem_2D_Color(VectorND item, ToVectorInstructions instr)
        {
            int width  = instr.FromSizes[0];
            int height = instr.FromSizes[1];

            #region build arrays

            double[] r = new double[width * height];
            double[] g = new double[width * height];
            double[] b = new double[width * height];

            //double scale = 1d / 255d;
            double scale = 1d;

            for (int y = 0; y < height; y++)
            {
                int yOffsetDest   = y * width;          // offset into the return array
                int yOffsetSource = y * width * 3;

                for (int x = 0; x < width; x++)
                {
                    int xOffsetSource = x * 3;

                    r[yOffsetDest + x] = item[yOffsetSource + xOffsetSource + 0] * scale;
                    g[yOffsetDest + x] = item[yOffsetSource + xOffsetSource + 1] * scale;
                    b[yOffsetDest + x] = item[yOffsetSource + xOffsetSource + 2] * scale;
                }
            }

            #endregion

            Convolution2D convR = Convolute(new Convolution2D(r, width, height, false), instr);
            Convolution2D convG = Convolute(new Convolution2D(g, width, height, false), instr);
            Convolution2D convB = Convolute(new Convolution2D(b, width, height, false), instr);

            #region merge arrays

            double[] merged = new double[convR.Values.Length * 3];

            for (int cntr = 0; cntr < convR.Values.Length; cntr++)
            {
                int index = cntr * 3;
                merged[index + 0] = convR.Values[cntr];
                merged[index + 1] = convG.Values[cntr];
                merged[index + 2] = convB.Values[cntr];
            }

            #endregion

            return(new SOMItem(item, merged.ToVectorND()));
        }
示例#4
0
        private static SOMItem GetSOMItem(VectorND item, ToVectorInstructions instr)
        {
            switch (instr.FromSizes.Length)
            {
            case 1:
                return(GetSOMItem_1D(item, instr));

            case 2:
                if (instr.IsColor2D)
                {
                    return(GetSOMItem_2D_Color(item, instr));
                }
                else
                {
                    return(GetSOMItem_2D_Gray(item, instr));
                }

            default:
                throw new ApplicationException("TODO: handle arbitrary number of dimensions");
            }
        }
示例#5
0
        private static SOMItem GetSOMItem_1D(VectorND item, ToVectorInstructions instr)
        {
            if (instr.FromSizes[0] == instr.ToSize)
            {
                return(new SOMItem(item, item));
            }

            // Create a bezier through the points, then pull points off of that curve.  Unless I read this wrong, this is what bicubic interpolation of images does (I'm just doing 1D instead of 2D)
            Point3D[] points = item.
                               Select(o => new Point3D(o, 0, 0)).
                               ToArray();

            BezierSegment3D[] bezier = BezierUtil.GetBezierSegments(points);

            VectorND resized = BezierUtil.GetPath(instr.ToSize, bezier).
                               Select(o => o.X).
                               ToArray().
                               ToVectorND();

            return(new SOMItem(item, resized));
        }
示例#6
0
        private static Convolution2D Convolute(Convolution2D conv, ToVectorInstructions instr)
        {
            Convolution2D retVal = conv;

            if (retVal.Width != retVal.Height)
            {
                int max = Math.Max(retVal.Width, retVal.Height);
                retVal = Convolutions.ExtendBorders(retVal, max, max);      // make it square
            }

            if (instr.ShouldNormalize)
            {
                retVal = Convolutions.Normalize(retVal);
            }

            if (instr.Convolution != null)
            {
                retVal = Convolutions.Convolute(retVal, instr.Convolution);
            }

            retVal = Convolutions.MaxPool(retVal, instr.ToSize, instr.ToSize);
            retVal = Convolutions.Abs(retVal);

            return retVal;
        }
示例#7
0
 /// <param name="itemDimensions">
 /// The width, height, depth, etc of each item
 /// </param>
 /// <param name="convolution">
 /// This gives a chance to run an edge detect, or some other convolution
 /// TODO: Support convolutions that can handle arbitrary dimensions
 /// </param>
 /// <param name="shouldNormalize">
 /// Forces all inputs to go between 0 and 1.
 /// NOTE: Only do this if the inputs come from varied sources
 /// </param>
 /// <param name="dupeDistance">
 /// If two items are closer together than this, they will be treated like they are the same.
 /// NOTE: If all the inputs are 0 to 1 (or even -1 to 1), then the default value should be fine.  But if the
 /// inputs have larger values (like 0 to 255), you would want a larger min value
 /// </param>
 public SOMList(int[] itemDimensions, ConvolutionBase2D convolution = null, bool shouldNormalize = false, bool discardDupes = true, double dupeDistance = .001, bool isColor2D = false)
 {
     _instructions    = new ToVectorInstructions(itemDimensions, GetResize(itemDimensions), convolution, shouldNormalize, isColor2D);
     _dupeDistSquared = dupeDistance * dupeDistance;
 }
示例#8
0
        private static SOMItem GetSOMItem_2D_Gray(double[] item, ToVectorInstructions instr)
        {
            Convolution2D conv = new Convolution2D(item, instr.FromSizes[0], instr.FromSizes[1], false);

            conv = Convolute(conv, instr);

            return new SOMItem(item, conv.Values);
        }
示例#9
0
        private static SOMItem GetSOMItem_2D_Color(double[] item, ToVectorInstructions instr)
        {
            int width = instr.FromSizes[0];
            int height = instr.FromSizes[1];

            #region build arrays

            double[] r = new double[width * height];
            double[] g = new double[width * height];
            double[] b = new double[width * height];

            //double scale = 1d / 255d;
            double scale = 1d;

            for (int y = 0; y < height; y++)
            {
                int yOffsetDest = y * width;		// offset into the return array
                int yOffsetSource = y * width * 3;

                for (int x = 0; x < width; x++)
                {
                    int xOffsetSource = x * 3;

                    r[yOffsetDest + x] = item[yOffsetSource + xOffsetSource + 0] * scale;
                    g[yOffsetDest + x] = item[yOffsetSource + xOffsetSource + 1] * scale;
                    b[yOffsetDest + x] = item[yOffsetSource + xOffsetSource + 2] * scale;
                }
            }

            #endregion

            Convolution2D convR = Convolute(new Convolution2D(r, width, height, false), instr);
            Convolution2D convG = Convolute(new Convolution2D(g, width, height, false), instr);
            Convolution2D convB = Convolute(new Convolution2D(b, width, height, false), instr);

            #region merge arrays

            double[] merged = new double[convR.Values.Length * 3];

            for (int cntr = 0; cntr < convR.Values.Length; cntr++)
            {
                int index = cntr * 3;
                merged[index + 0] = convR.Values[cntr];
                merged[index + 1] = convG.Values[cntr];
                merged[index + 2] = convB.Values[cntr];
            }

            #endregion

            return new SOMItem(item, merged);
        }
示例#10
0
        private static SOMItem GetSOMItem_1D(double[] item, ToVectorInstructions instr)
        {
            if (instr.FromSizes[0] == instr.ToSize)
            {
                return new SOMItem(item, item);
            }

            // Create a bezier through the points, then pull points off of that curve.  Unless I read this wrong, this is what bicubic interpolation of images does (I'm just doing 1D instead of 2D)
            Point3D[] points = item.
                Select(o => new Point3D(o, 0, 0)).
                ToArray();

            BezierSegment3D[] bezier = BezierUtil.GetBezierSegments(points);

            double[] resized = BezierUtil.GetPath(instr.ToSize, bezier).
                Select(o => o.X).
                ToArray();

            return new SOMItem(item, resized);
        }
示例#11
0
        private static SOMItem GetSOMItem(double[] item, ToVectorInstructions instr)
        {
            switch (instr.FromSizes.Length)
            {
                case 1:
                    return GetSOMItem_1D(item, instr);

                case 2:
                    if (instr.IsColor2D) return GetSOMItem_2D_Color(item, instr);
                    else return GetSOMItem_2D_Gray(item, instr);

                default:
                    throw new ApplicationException("TODO: handle arbitrary number of dimensions");
            }
        }
示例#12
0
 /// <param name="itemDimensions">
 /// The width, height, depth, etc of each item
 /// </param>
 /// <param name="convolution">
 /// This gives a chance to run an edge detect, or some other convolution
 /// TODO: Support convolutions that can handle arbitrary dimensions
 /// </param>
 /// <param name="shouldNormalize">
 /// Forces all inputs to go between 0 and 1.
 /// NOTE: Only do this if the inputs come from varied sources
 /// </param>
 /// <param name="dupeDistance">
 /// If two items are closer together than this, they will be treated like they are the same.
 /// NOTE: If all the inputs are 0 to 1 (or even -1 to 1), then the default value should be fine.  But if the
 /// inputs have larger values (like 0 to 255), you would want a larger min value
 /// </param>
 public SOMList(int[] itemDimensions, ConvolutionBase2D convolution = null, bool shouldNormalize = false, bool discardDupes = true, double dupeDistance = .001, bool isColor2D = false)
 {
     _instructions = new ToVectorInstructions(itemDimensions, GetResize(itemDimensions), convolution, shouldNormalize, isColor2D);
     _dupeDistSquared = dupeDistance * dupeDistance;
 }