예제 #1
0
        public void ConnectNeuronAcrossGaps(PixelState[,] pixels, int[,] pixel2Neuron,
                                            Dictionary <int, Neuron> neuronDict, int width, int height, double gapSeparation)
        {
            int searchHalfWidth = (int)(gapSeparation + 0.5);

            for (int i = 0; i < synapseDict.Count; i++)
            {
                Synapse s = synapseDict[i];
                int     x = s.XCenterOfMass;
                int     y = s.YCenterOfMass;

                // look at all pixels within a square centered around this synapse center-of-mass,
                // but only halfway around, starting straight up and going clockwise) around the
                // current pixel for other neurons. do not look in a full circle since then
                // we would end up with two connections for each pair of synapses (one in
                // either direction)

                List <int> neuronsProcessed = new List <int>();;

                int xDelta, yDelta;

                for (xDelta = 0; xDelta <= searchHalfWidth; xDelta++)
                {
                    for (yDelta = -searchHalfWidth; yDelta <= searchHalfWidth; yDelta++)
                    {
                        if ((0 < xDelta) || (yDelta < 0))
                        {
                            ConnectSynapseToSynapsesSource(pixels, pixel2Neuron, neuronDict,
                                                           width, height, gapSeparation, x, y, x + xDelta, y + yDelta, neuronsProcessed);
                        }
                    }
                }
            }
        }
예제 #2
0
        public void ConnectSynapseToSynapsesDestination(PixelState[,] pixels, int height, double gapSeperation,
                                                        int xSource, int ySource)
        {
            for (int i = 0; i < synapseDict.Count; i++)
            {
                Synapse s            = synapseDict[i];
                int     xDestination = s.XCenterOfMass;
                int     yDestination = s.YCenterOfMass;
                double  seperation   = Math.Sqrt((xDestination - xSource) * (xDestination - xSource) +
                                                 (yDestination - ySource) * (yDestination - ySource));

                if (seperation <= gapSeperation)
                {
                    // draw a line from the source to the destination. we sacrifice efficiency for
                    // simplicity, and do not use the Bresenham line-drawing algorithm (this is
                    // a one-time cost and at most there should be less than a few hundred
                    // pixels drawn in total)
                    int    nSteps = 1 + (int)(seperation / 0.5);
                    double xDelta = (double)(xDestination - xSource) / (double)nSteps;
                    double yDelta = (double)(yDestination - ySource) / (double)nSteps;
                    double x = xSource + xDelta, y = ySource + yDelta;

                    for (int j = 0; j < nSteps; j++)
                    {
                        // any pixel within a half pixel of (x,y) will be turned on

                        int xLine = (int)x;
                        int yLine = (int)y;
                        if (Math.Sqrt((x - xLine) * (x - xLine) + (y - yLine) * (y - yLine)) < 0.5)
                        {
                            pixels[xLine, yLine] = PixelState.PixelOn;
                        }
                        xLine += 1;
                        if (Math.Sqrt((x - xLine) * (x - xLine) + (y - yLine) * (y - yLine)) < 0.5)
                        {
                            pixels[xLine, yLine] = PixelState.PixelOn;
                        }
                        yLine += 1;
                        if (Math.Sqrt((x - xLine) * (x - xLine) + (y - yLine) * (y - yLine)) < 0.5)
                        {
                            pixels[xLine, yLine] = PixelState.PixelOn;
                        }
                        xLine -= 1;
                        if (Math.Sqrt((x - xLine) * (x - xLine) + (y - yLine) * (y - yLine)) < 0.5)
                        {
                            pixels[xLine, yLine] = PixelState.PixelOn;
                        }

                        x += xDelta;
                        y += yDelta;
                    }
                }
            }
        }
예제 #3
0
        public Synapse AddSynapse()
        {
            Synapse synapse = new Synapse(synapseDict);

            return synapse;
        }
예제 #4
0
        private void RecursivelySetPixel2Neuron(PixelState[,] pixels, int[,] pixel2Neuron, int x, int y, int width, int height, Neuron activeNeuron, Synapse activeSynapse, int level)
        {
            // if this pixel should belong to a neuron, then assign it to the active neuron.
            // if there is no active neuron (activeNeuron is null), then create one
            int xDelta, yDelta;

            // do not set this pixel if it is not on, or if it has already been assigned
            // to a neuron
            if ((pixels[x, y] != PixelState.PixelOn) || (pixel2Neuron[x, y] != -1))
                return;

            // this pixel needs to be assigned to a neuron
            if (activeNeuron == null)
            {
                activeNeuron = new Neuron(neuronDict);
            }

            pixel2Neuron[x, y] = activeNeuron.Index;

            // does this pixel need to be assigned to a synapse? look at eight
            // nearest neighbors
            bool needSynapse = false;
            for (xDelta = -1; !needSynapse && (xDelta <= 1); xDelta++)
                for (yDelta = -1; !needSynapse && (yDelta <= 1); yDelta++)
                    if ((xDelta != 0) || (yDelta != 0))
                    {
                        int xNeighbor = x + xDelta;
                        int yNeighbor = y + yDelta;
                        if ((0 <= xNeighbor) && (xNeighbor < width) &&
                          (0 <= yNeighbor) && (yNeighbor < height))
                        {
                            if ((pixels[xNeighbor, yNeighbor] != PixelState.PixelOff) &&
                              (pixels[xNeighbor, yNeighbor] != PixelState.PixelOn))
                            {
                                needSynapse = true;
                            }
                        }
                    }

            // assign to synapse, creating a new one if necessary
            if (needSynapse)
            {
                if (activeSynapse == null)
                {
                    activeSynapse = activeNeuron.AddSynapse();
                }
                activeSynapse.addPixel(x, y);
            }
            else
                activeSynapse = null;

            // limit the levels of recursion since Microsoft Windows will run out of stack
            // space. specifically, the default stack size of one megabyte only handles
            // 5700 levels of recursion here, and a stack size of two megabytes only
            // handles 11000 levels of recursion. extreme amounts of recursion happen in
            // images with extreme numbers of lines
            if (level < removalMaxRecursion)
            {
                // also set the eight nearest neighbors
                for (xDelta = -1; xDelta <= 1; xDelta++)
                    for (yDelta = -1; yDelta <= 1; yDelta++)
                        if ((xDelta != 0) || (yDelta != 0))
                        {
                            int xNeighbor = x + xDelta;
                            int yNeighbor = y + yDelta;
                            if ((0 <= xNeighbor) && (xNeighbor < width) &&
                              (0 <= yNeighbor) && (yNeighbor < height))
                            {
                                RecursivelySetPixel2Neuron(pixels, pixel2Neuron, xNeighbor, yNeighbor, width, height, activeNeuron, activeSynapse, level + 1);
                            }
                        }
            }
        }
예제 #5
0
        public Synapse AddSynapse()
        {
            Synapse synapse = new Synapse(synapseDict);

            return(synapse);
        }
예제 #6
0
        private void RecursivelySetPixel2Neuron(PixelState[,] pixels, int[,] pixel2Neuron, int x, int y, int width, int height, Neuron activeNeuron, Synapse activeSynapse, int level)
        {
            // if this pixel should belong to a neuron, then assign it to the active neuron.
            // if there is no active neuron (activeNeuron is null), then create one
            int xDelta, yDelta;

            // do not set this pixel if it is not on, or if it has already been assigned
            // to a neuron
            if ((pixels[x, y] != PixelState.PixelOn) || (pixel2Neuron[x, y] != -1))
            {
                return;
            }

            // this pixel needs to be assigned to a neuron
            if (activeNeuron == null)
            {
                activeNeuron = new Neuron(neuronDict);
            }

            pixel2Neuron[x, y] = activeNeuron.Index;

            // does this pixel need to be assigned to a synapse? look at eight
            // nearest neighbors
            bool needSynapse = false;

            for (xDelta = -1; !needSynapse && (xDelta <= 1); xDelta++)
            {
                for (yDelta = -1; !needSynapse && (yDelta <= 1); yDelta++)
                {
                    if ((xDelta != 0) || (yDelta != 0))
                    {
                        int xNeighbor = x + xDelta;
                        int yNeighbor = y + yDelta;
                        if ((0 <= xNeighbor) && (xNeighbor < width) &&
                            (0 <= yNeighbor) && (yNeighbor < height))
                        {
                            if ((pixels[xNeighbor, yNeighbor] != PixelState.PixelOff) &&
                                (pixels[xNeighbor, yNeighbor] != PixelState.PixelOn))
                            {
                                needSynapse = true;
                            }
                        }
                    }
                }
            }

            // assign to synapse, creating a new one if necessary
            if (needSynapse)
            {
                if (activeSynapse == null)
                {
                    activeSynapse = activeNeuron.AddSynapse();
                }
                activeSynapse.addPixel(x, y);
            }
            else
            {
                activeSynapse = null;
            }

            // limit the levels of recursion since Microsoft Windows will run out of stack
            // space. specifically, the default stack size of one megabyte only handles
            // 5700 levels of recursion here, and a stack size of two megabytes only
            // handles 11000 levels of recursion. extreme amounts of recursion happen in
            // images with extreme numbers of lines
            if (level < removalMaxRecursion)
            {
                // also set the eight nearest neighbors
                for (xDelta = -1; xDelta <= 1; xDelta++)
                {
                    for (yDelta = -1; yDelta <= 1; yDelta++)
                    {
                        if ((xDelta != 0) || (yDelta != 0))
                        {
                            int xNeighbor = x + xDelta;
                            int yNeighbor = y + yDelta;
                            if ((0 <= xNeighbor) && (xNeighbor < width) &&
                                (0 <= yNeighbor) && (yNeighbor < height))
                            {
                                RecursivelySetPixel2Neuron(pixels, pixel2Neuron, xNeighbor, yNeighbor, width, height, activeNeuron, activeSynapse, level + 1);
                            }
                        }
                    }
                }
            }
        }