public ProcessingImage filter(ProcessingImage inputImage)
        {
            ProcessingImage outputImage = new ProcessingImage();

            outputImage.copyAttributesAndAlpha(inputImage);
            outputImage.addWatermark(String.Format("conv watermark, dim: {0}", dim));

            float[,] convMatrix = new float[dim, dim];

            for (int i = 0; i < dim; i++)
            {
                for (int j = 0; j < dim; j++)
                {
                    convMatrix[i, j] = (float)(1.0 / (dim * dim));
                }
            }

            if (inputImage.grayscale)
            {
                byte[,] outputGray = new byte[inputImage.getSizeY(), inputImage.getSizeX()];
                byte[,] inputGray  = inputImage.getGray();

                for (int y = dim / 2; y < inputImage.getSizeY() - dim / 2; y++)
                {
                    for (int x = dim / 2; x < inputImage.getSizeX() - dim / 2; x++)
                    {
                        outputGray[y, x] = applyConv(x, y, inputGray, convMatrix);
                    }
                }
                outputImage.setGray(outputGray);
            }
            else
            {
                byte[,] outputRed   = new byte[inputImage.getSizeY(), inputImage.getSizeX()];
                byte[,] outputGreen = new byte[inputImage.getSizeY(), inputImage.getSizeX()];
                byte[,] outputBlue  = new byte[inputImage.getSizeY(), inputImage.getSizeX()];
                byte[,] inputRed    = inputImage.getRed();
                byte[,] inputGreen  = inputImage.getGreen();
                byte[,] inputBlue   = inputImage.getBlue();


                for (int y = dim / 2; y < inputImage.getSizeY() - dim / 2; y++)
                {
                    for (int x = dim / 2; x < inputImage.getSizeX() - dim / 2; x++)
                    {
                        outputRed[y, x]   = applyConv(x, y, inputRed, convMatrix);
                        outputGreen[y, x] = applyConv(x, y, inputGreen, convMatrix);
                        outputBlue[y, x]  = applyConv(x, y, inputBlue, convMatrix);
                    }
                }

                outputImage.setRed(outputRed);
                outputImage.setGreen(outputGreen);
                outputImage.setBlue(outputBlue);
            }

            return(outputImage);
        }
        public ProcessingImage filter(ProcessingImage inputImage)
        {
            ProcessingImage outputImage = new ProcessingImage();

            outputImage.copyAttributesAndAlpha(inputImage);
            outputImage.addWatermark(String.Format("sobel watermark"));
            const int dim = 3;

            float[,] convMatrixGx = new float[dim, dim] {
                { 1, 0, -1 },
                { 2, 0, -2 },
                { 1, 0, -1 }
            };

            float[,] convMatrixGy = new float[dim, dim]
            {
                { 1, 2, 1 },
                { 0, 0, 0 },
                { -1, -2, -1 }
            };

            byte[,] inputLuminance = inputImage.getLuminance();

            byte[,] outputGray = new byte[inputImage.getSizeY() - (dim - 1), inputImage.getSizeX() - (dim - 1)];

            for (int y = dim / 2; y < inputImage.getSizeY() - dim / 2; y++)
            {
                for (int x = dim / 2; x < inputImage.getSizeX() - dim / 2; x++)
                {
                    float resx = applyConv(x, y, inputLuminance, convMatrixGx);
                    float resy = applyConv(x, y, inputLuminance, convMatrixGy);

                    double r = Math.Sqrt((resx * resx) + (resy * resy));
                    if (r < 0)
                    {
                        r = 0;
                    }
                    if (r > 255)
                    {
                        r = 255;
                    }

                    outputGray[y - dim / 2, x - dim / 2] = (byte)r;
                }
            }

            outputImage.setSizeX(inputImage.getSizeX() - (dim - 1));
            outputImage.setSizeY(inputImage.getSizeY() - (dim - 1));
            outputImage.setGray(outputGray);

            return(outputImage);
        }
Exemple #3
0
        public ProcessingImage filter(ProcessingImage inputImage)
        {
            ProcessingImage outputImage = new ProcessingImage();

            outputImage.copyAttributesAndAlpha(inputImage);
            outputImage.addWatermark("blur watermark: media aritmetica in cruce (sus, jo, centru, stanga, dreapta)");

            if (inputImage.grayscale)
            {
                byte[,] outputGray = new byte[inputImage.getSizeY(), inputImage.getSizeX()];
                byte[,] inputGray  = inputImage.getGray();

                for (int y = 1; y < inputImage.getSizeY() - 1; y++)
                {
                    for (int x = 1; x < inputImage.getSizeX() - 1; x++)
                    {
                        outputGray[y, x] = (byte)((
                                                      inputGray[y - 1, x] +
                                                      +inputGray[y, x - 1] + inputGray[y, x] * 0 + inputGray[y, x + 1] +
                                                      inputGray[y + 1, x]
                                                      ) / 5);
                    }
                }
                outputImage.setGray(outputGray);
            }
            else
            {
                byte[,] outputRed   = new byte[inputImage.getSizeY(), inputImage.getSizeX()];
                byte[,] outputGreen = new byte[inputImage.getSizeY(), inputImage.getSizeX()];
                byte[,] outputBlue  = new byte[inputImage.getSizeY(), inputImage.getSizeX()];
                byte[,] inputRed    = inputImage.getRed();
                byte[,] inputGreen  = inputImage.getGreen();
                byte[,] inputBlue   = inputImage.getBlue();


                for (int y = 1; y < inputImage.getSizeY() - 1; y++)
                {
                    for (int x = 1; x < inputImage.getSizeX() - 1; x++)
                    {
                        outputRed[y, x] = (byte)((
                                                     inputRed[y - 1, x] +
                                                     +inputRed[y, x - 1] + inputRed[y, x] * 0 + inputRed[y, x + 1] +
                                                     inputRed[y + 1, x]
                                                     ) / 5);
                        outputGreen[y, x] = (byte)((
                                                       inputGreen[y - 1, x] +
                                                       +inputGreen[y, x - 1] + inputGreen[y, x] * 0 + inputGreen[y, x + 1] +
                                                       inputGreen[y + 1, x]
                                                       ) / 5);
                        outputBlue[y, x] = (byte)((
                                                      inputBlue[y - 1, x] +
                                                      +inputBlue[y, x - 1] + inputBlue[y, x] * 0 + inputBlue[y, x + 1] +
                                                      inputBlue[y + 1, x]
                                                      ) / 5);
                    }
                }

                outputImage.setRed(outputRed);
                outputImage.setGreen(outputGreen);
                outputImage.setBlue(outputBlue);
            }

            return(outputImage);
        }
Exemple #4
0
        public ProcessingImage filter(ProcessingImage inputImage)
        {
            ProcessingImage outputImage = new ProcessingImage();

            outputImage.copyAttributesAndAlpha(inputImage);
            outputImage.addWatermark(String.Format("canny watermark"));

            float[,] gaussianMatrix = generateGaussianMatrix();

            byte[,] inputLuminance = inputImage.getLuminance();

            float[,] outputImageGauss = new float[inputImage.getSizeY() - (gaussDim - 1), inputImage.getSizeX() - (gaussDim - 1)];

            /////////////////////////////////// input image -> GAUSS -> output image Gauss
            for (int y = gaussDim / 2; y < inputImage.getSizeY() - gaussDim / 2; y++)
            {
                for (int x = gaussDim / 2; x < inputImage.getSizeX() - gaussDim / 2; x++)
                {
                    float r = applyConv(x, y, inputLuminance, gaussianMatrix);

                    /*if (r < 0) r = 0;
                     * if (r > 255) r = 255;*/

                    outputImageGauss[y - gaussDim / 2, x - gaussDim / 2] = r;
                }
            }

            /////////////////////////////////// output image Gauss -> SOBEL -> output image Sobel
            const int sobelDim = 3;

            float[,] convMatrixGx = new float[sobelDim, sobelDim] {
                { 1, 0, -1 },
                { 2, 0, -2 },
                { 1, 0, -1 }
            };

            float[,] convMatrixGy = new float[sobelDim, sobelDim]
            {
                { 1, 2, 1 },
                { 0, 0, 0 },
                { -1, -2, -1 }
            };

            float[,] outputImageSobel         = new float[outputImageGauss.GetLength(0) - (sobelDim - 1), outputImageGauss.GetLength(1) - (sobelDim - 1)];
            DIRECTION[,] outputImageDirection = new DIRECTION[outputImageGauss.GetLength(0) - (sobelDim - 1), outputImageGauss.GetLength(1) - (sobelDim - 1)];
            for (int y = sobelDim / 2; y < outputImageGauss.GetLength(0) - sobelDim / 2; y++)
            {
                for (int x = sobelDim / 2; x < outputImageGauss.GetLength(1) - sobelDim / 2; x++)
                {
                    float resx = applyConv(x, y, outputImageGauss, convMatrixGx);
                    float resy = applyConv(x, y, outputImageGauss, convMatrixGy);

                    double r = Math.Sqrt((resx * resx) + (resy * resy));

                    /*if (r < 0) r = 0;
                     * if (r > 255) r = 255;*/

                    outputImageSobel[y - sobelDim / 2, x - sobelDim / 2]     = (float)r;
                    outputImageDirection[y - sobelDim / 2, x - sobelDim / 2] = radiansToDirection(Math.Atan2(resy, resx));
                }
            }

            /////////////////////////////////// output image Sobel & direction -> non maximum suppression -> outputImageNMS float
            float[,] floatOutputImageNms = new float[outputImageSobel.GetLength(0), outputImageSobel.GetLength(1)];
            for (int y = 0; y < outputImageSobel.GetLength(0); y++)
            {
                for (int x = 0; x < outputImageSobel.GetLength(1); x++)
                {
                    switch (outputImageDirection[y, x])
                    {
                    case DIRECTION.HORIZONTAL:
                        if (x >= 1 && x < outputImageSobel.GetLength(1) - 1 &&
                            outputImageSobel[y, x] > outputImageSobel[y, x - 1] &&
                            outputImageSobel[y, x] >= outputImageSobel[y, x + 1])
                        {
                            floatOutputImageNms[y, x] = outputImageSobel[y, x];
                        }
                        break;

                    case DIRECTION.LEFT45:
                        //case DIRECTION.RIGHT45:
                        if (x >= 1 && x < outputImageSobel.GetLength(1) - 1 &&
                            y >= 1 && y < outputImageSobel.GetLength(0) - 1 &&
                            outputImageSobel[y, x] >= outputImageSobel[y - 1, x + 1] &&
                            outputImageSobel[y, x] > outputImageSobel[y + 1, x - 1])
                        {
                            floatOutputImageNms[y, x] = outputImageSobel[y, x];
                        }
                        break;

                    case DIRECTION.VERTICAL:
                        if (y >= 1 && y < outputImageSobel.GetLength(0) - 1 &&
                            outputImageSobel[y, x] > outputImageSobel[y - 1, x] &&
                            outputImageSobel[y, x] >= outputImageSobel[y + 1, x])
                        {
                            floatOutputImageNms[y, x] = outputImageSobel[y, x];
                        }
                        break;

                    //case DIRECTION.LEFT45:
                    case DIRECTION.RIGHT45:
                        if (x >= 1 && x < outputImageSobel.GetLength(1) - 1 &&
                            y >= 1 && y < outputImageSobel.GetLength(0) - 1 &&
                            outputImageSobel[y, x] > outputImageSobel[y - 1, x - 1] &&
                            outputImageSobel[y, x] >= outputImageSobel[y + 1, x + 1])
                        {
                            floatOutputImageNms[y, x] = outputImageSobel[y, x];
                        }
                        break;
                    }
                }
            }

            /////////////////////////////////// output image non maximum suppression float -> acceptance matrix & byte outputNms
            bool[,] acceptanceMatrix = new bool[floatOutputImageNms.GetLength(0), floatOutputImageNms.GetLength(1)];
            byte[,] outputImageNms   = new byte[floatOutputImageNms.GetLength(0), floatOutputImageNms.GetLength(1)];

            for (int y = 0; y < floatOutputImageNms.GetLength(0); y++)
            {
                for (int x = 0; x < floatOutputImageNms.GetLength(1); x++)
                {
                    float r = floatOutputImageNms[y, x];
                    if (r > 255)
                    {
                        r = 255;
                    }

                    if (r < 0)
                    {
                        r = 0;
                    }

                    outputImageNms[y, x]   = (byte)r;
                    acceptanceMatrix[y, x] = outputImageNms[y, x] >= highThreshold;
                }
            }

            Queue <KeyValuePair <int, int> > neighbors = new Queue <KeyValuePair <int, int> >();

            for (int y = 0; y < outputImageNms.GetLength(0); y++)
            {
                for (int x = 0; x < outputImageNms.GetLength(1); x++)
                {
                    if (acceptanceMatrix[y, x])
                    {
                        if (y >= 1 &&
                            outputImageNms[y - 1, x] >= lowThreshold && outputImageNms[y - 1, x] < highThreshold) // up
                        {
                            neighbors.Enqueue(new KeyValuePair <int, int>(y - 1, x));
                        }

                        if (y < outputImageNms.GetLength(0) - 1 &&
                            outputImageNms[y + 1, x] >= lowThreshold && outputImageNms[y + 1, x] < highThreshold) // down
                        {
                            neighbors.Enqueue(new KeyValuePair <int, int>(y + 1, x));
                        }

                        if (x < outputImageNms.GetLength(1) - 1 &&
                            outputImageNms[y, x + 1] >= lowThreshold && outputImageNms[y, x + 1] < highThreshold) // right
                        {
                            neighbors.Enqueue(new KeyValuePair <int, int>(y, x + 1));
                        }

                        if (x >= 1 &&
                            outputImageNms[y, x - 1] >= lowThreshold && outputImageNms[y, x - 1] < highThreshold) // left
                        {
                            neighbors.Enqueue(new KeyValuePair <int, int>(y, x - 1));
                        }

                        if (y >= 1 && x < outputImageNms.GetLength(1) - 1 &&
                            outputImageNms[y - 1, x + 1] >= lowThreshold && outputImageNms[y - 1, x + 1] < highThreshold) //right-up
                        {
                            neighbors.Enqueue(new KeyValuePair <int, int>(y - 1, x + 1));
                        }

                        if (x >= 1 && y >= 1 &&
                            outputImageNms[y - 1, x - 1] >= lowThreshold && outputImageNms[y - 1, x - 1] < highThreshold) // left-up
                        {
                            neighbors.Enqueue(new KeyValuePair <int, int>(y - 1, x - 1));
                        }

                        if (y < outputImageNms.GetLength(0) - 1 && x >= 1 &&
                            outputImageNms[y + 1, x - 1] >= lowThreshold && outputImageNms[y + 1, x - 1] < highThreshold) // left-down
                        {
                            neighbors.Enqueue(new KeyValuePair <int, int>(y + 1, x - 1));
                        }

                        if (x < outputImageNms.GetLength(1) - 1 && y < outputImageNms.GetLength(0) - 1 &&
                            outputImageNms[y + 1, x + 1] >= lowThreshold && outputImageNms[y + 1, x + 1] < highThreshold) // right-down
                        {
                            neighbors.Enqueue(new KeyValuePair <int, int>(y + 1, x + 1));
                        }
                    }
                }
            }

            while (neighbors.Count > 0)
            {
                KeyValuePair <int, int> xy = neighbors.Dequeue();
                int y = xy.Key;
                int x = xy.Value;
                if (!acceptanceMatrix[y, x])
                {
                    acceptanceMatrix[y, x] = true;

                    if (y >= 1 &&
                        outputImageNms[y - 1, x] >= lowThreshold && outputImageNms[y - 1, x] < highThreshold) // up
                    {
                        neighbors.Enqueue(new KeyValuePair <int, int>(y - 1, x));
                    }

                    if (y < outputImageNms.GetLength(0) - 1 &&
                        outputImageNms[y + 1, x] >= lowThreshold && outputImageNms[y + 1, x] < highThreshold) // down
                    {
                        neighbors.Enqueue(new KeyValuePair <int, int>(y + 1, x));
                    }

                    if (x < outputImageNms.GetLength(1) - 1 &&
                        outputImageNms[y, x + 1] >= lowThreshold && outputImageNms[y, x + 1] < highThreshold) // right
                    {
                        neighbors.Enqueue(new KeyValuePair <int, int>(y, x + 1));
                    }

                    if (x >= 1 &&
                        outputImageNms[y, x - 1] >= lowThreshold && outputImageNms[y, x - 1] < highThreshold) // left
                    {
                        neighbors.Enqueue(new KeyValuePair <int, int>(y, x - 1));
                    }

                    if (y >= 1 && x < outputImageNms.GetLength(1) - 1 &&
                        outputImageNms[y - 1, x + 1] >= lowThreshold && outputImageNms[y - 1, x + 1] < highThreshold) //right-up
                    {
                        neighbors.Enqueue(new KeyValuePair <int, int>(y - 1, x + 1));
                    }

                    if (x >= 1 && y >= 1 &&
                        outputImageNms[y - 1, x - 1] >= lowThreshold && outputImageNms[y - 1, x - 1] < highThreshold) // left-up
                    {
                        neighbors.Enqueue(new KeyValuePair <int, int>(y - 1, x - 1));
                    }

                    if (y < outputImageNms.GetLength(0) - 1 && x >= 1 &&
                        outputImageNms[y + 1, x - 1] >= lowThreshold && outputImageNms[y + 1, x - 1] < highThreshold) // left-down
                    {
                        neighbors.Enqueue(new KeyValuePair <int, int>(y + 1, x - 1));
                    }

                    if (x < outputImageNms.GetLength(1) - 1 && y < outputImageNms.GetLength(0) - 1 &&
                        outputImageNms[y + 1, x + 1] >= lowThreshold && outputImageNms[y + 1, x + 1] < highThreshold) // right-down
                    {
                        neighbors.Enqueue(new KeyValuePair <int, int>(y + 1, x + 1));
                    }
                }
            }

            /////////////////////////////////// output image non maximum suppression  -> histeresis threshold-> outputImageHisteresis
            float[,] outputImageHist = new float[outputImageNms.GetLength(0), outputImageNms.GetLength(1)];

            for (int y = 0; y < outputImageNms.GetLength(0); y++)
            {
                for (int x = 0; x < outputImageNms.GetLength(1); x++)
                {
                    if (acceptanceMatrix[y, x])
                    {
                        outputImageHist[y, x] = outputImageNms[y, x];
                    }
                }
            }

            ////////////////////////////////// to byte
            byte[,] outputGray = new byte[outputImageHist.GetLength(0), outputImageHist.GetLength(1)];
            for (int y = 0; y < outputGray.GetLength(0); y++)
            {
                for (int x = 0; x < outputGray.GetLength(1); x++)
                {
                    float r = outputImageHist[y, x];
                    if (r < 0)
                    {
                        r = 0;
                    }
                    if (r > 255)
                    {
                        r = 255;
                    }
                    outputGray[y, x] = (byte)r;
                }
            }

            outputImage.setSizeX(outputGray.GetLength(1));
            outputImage.setSizeY(outputGray.GetLength(0));
            outputImage.setGray(outputGray);

            return(outputImage);
        }
Exemple #5
0
        public ProcessingImage filter(ProcessingImage inputImage)
        {
            ProcessingImage outputImage = new ProcessingImage();

            outputImage.copyAttributesAndAlpha(inputImage);
            outputImage.addWatermark(String.Format("LoG watermark"));


            // intout -> laplacian of gaussian -> output LOG
            const int logDim = 5;

            float[,] laplacianOfGaussian = new float[logDim, logDim]
            {
                { 0, 0, -1, 0, 0 },
                { 0, -1, -2, -1, 0 },
                { -1, -2, 16, -2, -1 },
                { 0, -1, -2, -1, 0 },
                { 0, 0, -1, 0, 0 },
            };

            byte[,] inputLuminance = inputImage.getLuminance();

            int[,] outputImageLoG = new int[inputImage.getSizeY() - (logDim - 1), inputImage.getSizeX() - (logDim - 1)];

            for (int y = logDim / 2; y < inputImage.getSizeY() - logDim / 2; y++)     //getlength0
            {
                for (int x = logDim / 2; x < inputImage.getSizeX() - logDim / 2; x++) //getlength1
                {
                    float r = applyConv(x, y, inputLuminance, laplacianOfGaussian);

                    outputImageLoG[y - logDim / 2, x - logDim / 2] = (int)r;
                }
            }

            // LOG -> zero crossing -> output
            byte[,] outputImageZC = new byte[outputImageLoG.GetLength(0), outputImageLoG.GetLength(1)];
            for (int y = 0; y < outputImageLoG.GetLength(0); y++)
            {
                for (int x = 0; x < outputImageLoG.GetLength(1); x++)
                {
                    bool zeroCrossing = false;
                    //left
                    if (x >= 1 && Math.Sign(outputImageLoG[y, x]) != Math.Sign(outputImageLoG[y, x - 1]))
                    {
                        zeroCrossing = true;
                    }
                    //upper left
                    else if (x >= 1 && y >= 1 && Math.Sign(outputImageLoG[y, x]) != Math.Sign(outputImageLoG[y - 1, x - 1]))
                    {
                        zeroCrossing = true;
                    }
                    //up
                    else if (y >= 1 && Math.Sign(outputImageLoG[y, x]) != Math.Sign(outputImageLoG[y - 1, x]))
                    {
                        zeroCrossing = true;
                    }
                    //upper right
                    else if (y >= 1 && x < outputImageLoG.GetLength(1) - 1 &&
                             Math.Sign(outputImageLoG[y, x]) != Math.Sign(outputImageLoG[y - 1, x + 1]))
                    {
                        zeroCrossing = true;
                    }

                    if (zeroCrossing)
                    {
                        outputImageZC[y, x] = 255;
                    }
                }
            }


            ////////////////////////////////// to byte
            byte[,] outputGray = new byte[outputImageZC.GetLength(0), outputImageZC.GetLength(1)];
            for (int y = 0; y < outputGray.GetLength(0); y++)
            {
                for (int x = 0; x < outputGray.GetLength(1); x++)
                {
                    float r = outputImageZC[y, x];
                    if (r < 0)
                    {
                        r = 0;
                    }
                    if (r > 255)
                    {
                        r = 255;
                    }
                    outputGray[y, x] = (byte)r;
                }
            }

            outputImage.setSizeX(outputGray.GetLength(1));
            outputImage.setSizeY(outputGray.GetLength(0));
            outputImage.setGray(outputGray);

            return(outputImage);
        }
        public ProcessingImage filter(ProcessingImage inputImage)
        {
            ProcessingImage outputImage = new ProcessingImage();

            outputImage.copyAttributesAndAlpha(inputImage);
            outputImage.addWatermark(String.Format("Active contour filter watermark"));

            double k      = 0.001;
            int    radius = 25;

            byte[,] inputLuminance = inputImage.getLuminance();
            int centerX = inputImage.getSizeX() / 2;
            int centerY = inputImage.getSizeY() / 2;

            int[,] outputImageResult = new int[inputImage.getSizeY(), inputImage.getSizeX()];

            outputImageResult[centerY, centerX] = 255;
            Point[] points = new Point[numPoints];
            int     n      = 0;

            for (double i = 0; i < 2 * Math.PI && n < numPoints; i += (2 * Math.PI) / numPoints)
            {
                double sinRes = Math.Sin(i);
                double cosRes = Math.Cos(i);
                points[n]   = new Point();
                points[n].x = centerY + (radius * sinRes);
                points[n].y = centerX + (radius * cosRes);
                n++;
            }


            for (int i = 0; i < numPoints; i++)
            {
                outputImageResult[(int)points[i].y, (int)points[i].x] = 255;
            }

            for (int s = 0; s < numSteps; s++)
            {
                for (int i = 0; i < numPoints; i++)
                {
                    int up_i   = i + 1;
                    int down_i = i - 1;

                    if (up_i >= numPoints - 1)
                    {
                        up_i = 0;
                    }

                    if (down_i < 0)
                    {
                        down_i = numPoints - 1;
                    }

                    double dx1 = points[down_i].x - points[i].x;
                    double dx2 = points[up_i].x - points[i].x;

                    double dy1 = points[down_i].y - points[i].y;
                    double dy2 = points[up_i].y - points[i].y;

                    points[i].accelX = k * dx1 + k * dx2; //elastic force, we approximate F=ma with a mass of 1
                    points[i].accelY = k * dy1 + k * dy2; // sum of forces that act on the object on both axes

                    points[i].speedY = points[i].speedY + points[i].accelY;
                    points[i].speedX = points[i].speedX + points[i].accelX;

                    if (points[i].speedY > 2)
                    {
                        points[i].speedY = 2;
                    }

                    if (points[i].speedY < -2)
                    {
                        points[i].speedY = -2;
                    }

                    if (points[i].speedX > 2)
                    {
                        points[i].speedX = 2;
                    }

                    if (points[i].speedX < -2)
                    {
                        points[i].speedX = -2;
                    }

                    points[i].y = (points[i].y + points[i].speedY);
                    points[i].x = (points[i].x + points[i].speedX);
                }
            }

            for (int i = 0; i < numPoints; i++)
            {
                if ((int)points[i].y >= 0 && (int)points[i].x >= 0 && (int)points[i].x < outputImage.getSizeX() && (int)points[i].y < outputImage.getSizeY())
                {
                    outputImageResult[(int)points[i].y, (int)points[i].x] = 100;
                }
            }

            ////////////////////////////////// to byte
            byte[,] outputGray = new byte[outputImageResult.GetLength(0), outputImageResult.GetLength(1)];
            for (int y = 0; y < outputGray.GetLength(0); y++)
            {
                for (int x = 0; x < outputGray.GetLength(1); x++)
                {
                    float r = outputImageResult[y, x];
                    if (r < 0)
                    {
                        r = 0;
                    }
                    if (r > 255)
                    {
                        r = 255;
                    }
                    outputGray[y, x] = (byte)r;
                }
            }

            outputImage.setSizeX(outputGray.GetLength(1));
            outputImage.setSizeY(outputGray.GetLength(0));
            outputImage.setGray(outputGray);

            return(outputImage);
        }