Example #1
0
        public static PNM ApplyPixelFunction(this PNM image, int matrixLength, Func <PNM, int, Pixel> func)
        {
            PNM newImage = PNM.Copy(image);
            int padding  = matrixLength / 2;

            Pad(newImage, padding);
            newImage = ApplyConvolutionFunctionCore(newImage, matrixLength, func);
            Trim(newImage, padding);
            return(newImage);
        }
Example #2
0
        public static PNM ApplyConvolutionMatrix(this PNM image, float[] matrix, float weight, float shift)
        {
            int length = (int)Math.Sqrt(matrix.Length);

            if (Math.Pow(length, 2) != matrix.Length || (length / 2) * 2 == length)
            {
                throw new ArgumentException("matrix");
            }
            PNM newImage = PNM.Copy(image);
            int padding  = length / 2;

            Pad(newImage, padding);
            newImage = ApplyConvolutionMatrixCore(newImage, matrix, length, weight, shift);
            Trim(newImage, padding);
            return(newImage);
        }
Example #3
0
        public static PNM ApplyHeightMapFunction(this PNM image, int matrixLength, Func <int, int, float[], int, Pixel> func)
        {
            PNM newImage = PNM.Copy(image);
            int padding  = matrixLength / 2;

            Pad(newImage, padding);
            int newImageSize = newImage.Width * newImage.Height;

            float[] heightmap = new float[newImageSize];
            byte    r, g, b;

            for (int i = 0; i < newImageSize; i++)
            {
                newImage.GetPixel(i, out r, out g, out b);
                heightmap[i] = PNM.RGBToLuminosity(r, g, b) / 255f;
            }
            newImage = ApplyHeightMapFunctionCore(newImage.Width, newImage.Height, heightmap, matrixLength, func);
            Trim(newImage, padding);
            return(newImage);
        }
Example #4
0
        //this should be rewritten to ApplyConvolutionFunction
        public static PNM ApplyGradientEdgesDetection(this PNM image)
        {
            PNM workImage = PNM.Copy(image);

            Pad(workImage, 1);
            Tuple <float[], float[], float[]> xraster = ApplyConvolutionUnbound(workImage, new float[] { -1, 0, 1,
                                                                                                         -1, 0, 1,
                                                                                                         -1, 0, 1 }, 3);
            Tuple <float[], float[], float[]> yraster = ApplyConvolutionUnbound(workImage, new float[] { 1, 1, 1,
                                                                                                         0, 0, 0,
                                                                                                         -1, -1, -1 }, 3);
            PNM newImage = new PNM(image.Width, image.Height);
            int size     = image.Width * image.Height;

            Parallel.For(0, size, i =>
            {
                byte r = Coerce(Math.Sqrt(Math.Pow(xraster.Item1[i], 2) + Math.Pow(yraster.Item1[i], 2)));
                byte g = Coerce(Math.Sqrt(Math.Pow(xraster.Item2[i], 2) + Math.Pow(yraster.Item2[i], 2)));
                byte b = Coerce(Math.Sqrt(Math.Pow(xraster.Item3[i], 2) + Math.Pow(yraster.Item3[i], 2)));
                newImage.SetPixel(i, r, g, b);
            });
            return(newImage);
        }
Example #5
0
        public static PNM ApplyHarrisDetector(this PNM image)
        {
            // gaussian window
            float[] gaussian = new float[] { 0, 0.01F, 0.02F, 0.01F, 0,
                                             0.01F, 0.06F, 0.1F, 0.06F, 0.01F,
                                             0.02F, 0.1F, 0.16F, 0.1F, 0.02F,
                                             0.01F, 0.06F, 0.1F, 0.06F, 0.01F,
                                             0, 0.01F, 0.02F, 0.01F, 0 };
            // greyscale
            PNM workImage = PNM.Copy(image).ApplyPointProcessing(Color.ToGrayscale);

            Filter.Pad(workImage, 1);
            // integrate with prewitt
            double[] normalizedWorkImage = workImage.raster.Where((b, idx) => idx % 3 == 0).Select(b => b / 255d).ToArray();
            double[] xraster             = RunConvolution(normalizedWorkImage, workImage.Width, workImage.Height, Edges.SobelX, 3);
            double[] yraster             = RunConvolution(normalizedWorkImage, workImage.Width, workImage.Height, Edges.SobelY, 3);
            double[] rasterA             = new double[xraster.Length];
            double[] rasterB             = new double[xraster.Length];
            double[] rasterC             = new double[xraster.Length];
            for (int i = 0; i < xraster.Length; i++)
            {
                rasterA[i] = Math.Pow(xraster[i], 2);
                rasterB[i] = Math.Pow(yraster[i], 2);
                rasterC[i] = xraster[i] * yraster[i];
            }
            rasterA = Filter.PadWithZeros(rasterA, image.Width, image.Height, 2, 2);
            rasterB = Filter.PadWithZeros(rasterB, image.Width, image.Height, 2, 2);
            rasterC = Filter.PadWithZeros(rasterC, image.Width, image.Height, 2, 2);
            // calculate the matrices
            double[][] matrices  = new double[image.Width * image.Height][];
            int        maxHeight = image.Height + 2;
            int        maxWidth  = image.Width + 2;
            int        newWidth  = image.Width + 4;
            int        width     = image.Width;

            for (int i = 2; i < maxHeight; i++)
            {
                //Parallel.For(2, maxHeight, (i) =>
                //{
                for (int j = 2; j < maxWidth; j++)
                {
                    // apply convolution
                    double accumulatorA = 0;
                    double accumulatorB = 0;
                    double accumulatorC = 0;
                    int    mi           = 0;
                    for (int x0 = -2; x0 <= 2; x0++)
                    {
                        for (int y0 = -2; y0 <= 2; y0++)
                        {
                            accumulatorA += gaussian[mi] * rasterA[(i + x0) * newWidth + j + y0];
                            accumulatorB += gaussian[mi] * rasterB[(i + x0) * newWidth + j + y0];
                            accumulatorC += gaussian[mi] * rasterC[(i + x0) * newWidth + j + y0];
                            mi++;
                        }
                    }
                    int realPosition = (i - 2) * width + (j - 2);
                    matrices[realPosition] = new double[] { accumulatorA, accumulatorB, accumulatorC };
                }
                //});
            }
            // do the part 2 and 3
            double[] cornerness = new double[image.Width * image.Height];
            for (int i = 0; i < matrices.Length; i++)
            {
                double det    = (matrices[i][0] * matrices[i][1]) - (matrices[i][2] * matrices[i][2]);
                double trace  = matrices[i][0] + matrices[i][1];
                double corner = det - (HarrisK * (trace * trace));
                if (corner >= HarrisThreshold)
                {
                    cornerness[i] = corner;
                }
            }
            //return ToPNM(cornerness, image.Width, image.Height);
            CenteredNonMaximumSuppression(cornerness, image.Width, image.Height, 3);
            // draw corners
            PNM newImage = PNM.Copy(image);

            for (int i = 0; i < cornerness.Length; i++)
            {
                if (cornerness[i] == 0)
                {
                    continue;
                }
                MarkPixel(newImage, i);
            }
            return(newImage);
        }