Пример #1
0
        public static PNM Copy(PNM image)
        {
            PNM newImage = new PNM(image.Width, image.Height);

            Buffer.BlockCopy(image.raster, 0, newImage.raster, 0, image.raster.Length);
            return(newImage);
        }
Пример #2
0
 internal static void Pad(PNM image, int padding)
 {
     image.raster  = PadWithZeros(image.raster, image.Width * 3, image.Height, padding * 3, padding);
     image.Width  += 2 * padding;
     image.Height += 2 * padding;
     PadCorners(image, padding);
     PadBorders(image, padding);
 }
Пример #3
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);
        }
Пример #4
0
        internal void ReplaceImage(string path)
        {
            Stream stream = File.Open(path, FileMode.Open);
            Tuple <PNM, PNMFormat> payload = PNM.LoadFileWithFormat(stream);

            Image  = payload.Item1;
            Format = payload.Item2;
            undoList.Clear();
            Path = path;
        }
Пример #5
0
 internal static void SaveFile(PNM bitmap, FileStream stream)
 {
     bitmap.WriteLongHeader("P5", stream);
     for (int i = 0; i < bitmap.Height * bitmap.Width; i++)
     {
         byte r, g, b;
         bitmap.GetPixel(i, out r, out g, out b);
         byte pixel = RGBToLuminosity(r, g, b);
         stream.WriteByte(pixel);
     }
 }
Пример #6
0
 internal static void SaveFile(PNM bitmap, FileStream stream)
 {
     bitmap.WriteShortHeader("P4", stream);
     for (int i = 0; i < bitmap.Height; i++)
     {
         for (int j = 0; j < bitmap.Width; j += 8)
         {
             stream.WriteByte(PackBytes(bitmap, i * bitmap.Width + j, UnpackedBits(j, bitmap.Width)));
         }
     }
 }
Пример #7
0
 internal static void SaveFile(PNM bitmap, FileStream stream)
 {
     bitmap.WriteShortHeader("P4", stream);
     for (int i = 0; i < bitmap.Height; i++)
     {
         for (int j = 0; j < bitmap.Width; j += 8)
         {
             stream.WriteByte(PackBytes(bitmap, i * bitmap.Width + j,UnpackedBits(j, bitmap.Width)));
         }
     }
 }
Пример #8
0
 internal static void SaveFile(PNM bitmap, FileStream stream)
 {
     bitmap.WriteLongHeader("P5", stream);
     for (int i = 0; i < bitmap.Height * bitmap.Width; i++)
     {
         byte r,g,b;
         bitmap.GetPixel(i, out r, out g, out b);
         byte pixel = RGBToLuminosity(r, g, b);
         stream.WriteByte(pixel);
     }
 }
Пример #9
0
 internal static byte PackBytes(PNM bitmap, int start, int amount)
 {
     int result = 0;
     byte r,g,b;
     for(int i = 0; i< amount; i++)
     {
         bitmap.GetPixel(start + i, out r,out g,out b);
         if (ColorToBlack(r, g, b))
             result |= (128 >> i);
     }
     return (byte)result;
 }
Пример #10
0
 internal static void SaveFile(PNM bitmap, FileStream stream)
 {
     bitmap.WriteLongHeader("P6", stream);
     for (int i = 0; i < bitmap.Height * bitmap.Width; i++)
     {
         byte r, g, b;
         bitmap.GetPixel(i, out r, out g, out b);
         stream.WriteByte(r);
         stream.WriteByte(g);
         stream.WriteByte(b);
     }
 }
Пример #11
0
        internal static void SaveFile(PNM bitmap, FileStream stream)
        {

            bitmap.WriteLongHeader("P6", stream);
            for (int i = 0; i < bitmap.Height * bitmap.Width; i++)
            {
                byte r, g, b;
                bitmap.GetPixel(i, out r, out g, out b);
                stream.WriteByte(r);
                stream.WriteByte(g);
                stream.WriteByte(b);
            }
        }
Пример #12
0
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            PNM pnm = value as PNM;

            if (pnm == null)
            {
                return(null);
            }

            var bitmap = new WriteableBitmap(pnm.Width, pnm.Height, 96, 96, PixelFormats.Cmyk32, null);

            bitmap.WritePixels(new Int32Rect(0, 0, pnm.Width, pnm.Height), pnm.GetCMYK(), pnm.Width * 4, 0);
            return(bitmap);
        }
Пример #13
0
        public static PNM ApplyPointProcessing(this PNM oldImage, Func <byte, byte, byte, Pixel> filter)
        {
            PNM  newImage = new PNM(oldImage.Width, oldImage.Height);
            byte r, g, b;
            int  size = oldImage.Width * oldImage.Height;

            for (int i = 0; i < size; i++)
            {
                oldImage.GetPixel(i, out r, out g, out b);
                Pixel pixel = filter(r, g, b);
                newImage.SetPixel(i, pixel.Red, pixel.Green, pixel.Blue);
            }
            ;
            return(newImage);
        }
Пример #14
0
        internal static byte PackBytes(PNM bitmap, int start, int amount)
        {
            int  result = 0;
            byte r, g, b;

            for (int i = 0; i < amount; i++)
            {
                bitmap.GetPixel(start + i, out r, out g, out b);
                if (ColorToBlack(r, g, b))
                {
                    result |= (128 >> i);
                }
            }
            return((byte)result);
        }
Пример #15
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);
        }
Пример #16
0
        // poor man's pixel shader
        private static PNM ApplyConvolutionFunctionCore(PNM image, int matrixLength, Func <PNM, int, Pixel> func)
        {
            PNM newImage  = new PNM(image.Width, image.Height);
            int padding   = matrixLength / 2;
            int maxHeight = newImage.Height - padding;
            int maxWidth  = newImage.Width - padding;
            int width     = newImage.Width;

            Parallel.For(padding, maxHeight, i =>
            {
                for (int j = padding; j < maxWidth; j++)
                {
                    // current index position
                    int position = i * width + j;
                    newImage.SetPixel(position, func(image, position));
                }
            });
            return(newImage);
        }
Пример #17
0
        private static PNM ApplyHeightMapFunctionCore(int imgWidth, int imgHeight, float[] heightmap, int matrixLength, Func <int, int, float[], int, Pixel> func)
        {
            PNM newImage  = new PNM(imgWidth, imgHeight);
            int padding   = matrixLength / 2;
            int maxHeight = imgHeight - padding;
            int maxWidth  = imgWidth - padding;
            int width     = imgWidth;

            Parallel.For(padding, maxHeight, i =>
            {
                for (int j = padding; j < maxWidth; j++)
                {
                    // current index position
                    int position = i * width + j;
                    newImage.SetPixel(position, func(imgWidth, imgHeight, heightmap, position));
                }
            });
            return(newImage);
        }
Пример #18
0
 public static void SaveFile(PNM bitmap, string path, PNMFormat format)
 {
     using (FileStream stream = File.Open(path, FileMode.Create, FileAccess.Write))
     {
         switch (format)
         {
             case PNMFormat.PBM:
                 RawPBM.SaveFile(bitmap, stream);
                 break;
             case PNMFormat.PGM:
                 RawPGM.SaveFile(bitmap, stream);
                 break;
             case PNMFormat.PPM:
                 RawPPM.SaveFile(bitmap, stream);
                 break;
             default:
                 throw new ArgumentException("format");
         }
     }
 }
Пример #19
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);
        }
Пример #20
0
        private static void PadCorners(PNM image, int padding)
        {
            byte r, g, b;

            // pad top left
            image.GetPixel(padding, padding, out r, out g, out b);
            for (int i = 0; i < padding; i++)
            {
                for (int j = 0; j < padding; j++)
                {
                    image.SetPixel(i, j, r, g, b);
                }
            }
            // pad top right
            image.GetPixel(image.Width - padding - 1, padding, out r, out g, out b);
            for (int i = image.Width - padding; i < image.Width; i++)
            {
                for (int j = 0; j < padding; j++)
                {
                    image.SetPixel(i, j, r, g, b);
                }
            }
            // pad bottom left
            image.GetPixel(padding, image.Height - padding - 1, out r, out g, out b);
            for (int i = 0; i < padding; i++)
            {
                for (int j = image.Height - padding; j < image.Height; j++)
                {
                    image.SetPixel(i, j, r, g, b);
                }
            }
            // pad bottom right
            image.GetPixel(image.Width - padding - 1, image.Height - padding - 1, out r, out g, out b);
            for (int i = image.Width - padding; i < image.Width; i++)
            {
                for (int j = image.Height - padding; j < image.Height; j++)
                {
                    image.SetPixel(i, j, r, g, b);
                }
            }
        }
Пример #21
0
        internal static Tuple <float[], float[], float[]> ApplyConvolutionUnbound(PNM image, float[] matrix, int matrixLength)
        {
            int padding   = matrixLength / 2;
            int oldHeight = image.Height - (padding * 2);
            int oldWidth  = image.Width - (padding * 2);
            Tuple <float[], float[], float[]> rasters = Tuple.Create(new float[oldHeight * oldWidth],
                                                                     new float[oldHeight * oldWidth],
                                                                     new float[oldHeight * oldWidth]);
            int maxHeight = image.Height - padding;
            int maxWidth  = image.Width - padding;

            Parallel.For(padding, maxHeight, i =>
            {
                int index = (i - padding) * oldWidth;
                for (int j = padding; j < maxWidth; j++)
                {
                    float sumR = 0;
                    float sumG = 0;
                    float sumB = 0;
                    // current index position
                    int position = i * image.Width + j;
                    for (int m = 0; m < matrixLength; m++)
                    {
                        for (int n = 0; n < matrixLength; n++)
                        {
                            byte r, g, b;
                            image.GetPixel(position - ((padding - m) * image.Width) - (padding - n), out r, out g, out b);
                            float coeff = matrix[(m * matrixLength) + n];
                            sumR       += r * coeff;
                            sumG       += g * coeff;
                            sumB       += b * coeff;
                        }
                    }
                    rasters.Item1[index] = sumR;
                    rasters.Item2[index] = sumG;
                    rasters.Item3[index] = sumB;
                    index++;
                }
            });
            return(rasters);
        }
Пример #22
0
        private static void MarkPixel(PNM image, int index)
        {
            int x = index % image.Width;
            int y = index / image.Width;

            for (int x0 = -1; x0 <= 1; x0++)
            {
                for (int y0 = -1; y0 <= 1; y0++)
                {
                    if (x0 == 0 && y0 == 0)
                    {
                        continue;
                    }
                    int currentY = y + y0;
                    int currentX = x + x0;
                    if (currentX < 0 || currentX >= image.Width || currentY < 0 || currentY >= image.Height)
                    {
                        continue;
                    }
                    image.SetPixel(x + x0, y + y0, 0, 255, 0);
                }
            }
        }
Пример #23
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);
        }
Пример #24
0
        public static void SaveFile(PNM bitmap, string path, PNMFormat format)
        {
            using (FileStream stream = File.Open(path, FileMode.Create, FileAccess.Write))
            {
                switch (format)
                {
                case PNMFormat.PBM:
                    RawPBM.SaveFile(bitmap, stream);
                    break;

                case PNMFormat.PGM:
                    RawPGM.SaveFile(bitmap, stream);
                    break;

                case PNMFormat.PPM:
                    RawPPM.SaveFile(bitmap, stream);
                    break;

                default:
                    throw new ArgumentException("format");
                }
            }
        }
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            PNM        pnm        = values[0] as PNM;
            int?       selection  = values[1] as int?;
            Visibility?visibility = values[2] as Visibility?;

            if (pnm == null || selection == null || visibility != Visibility.Visible)
            {
                return(Binding.DoNothing);
            }

            double[] rawData;
            switch (selection)
            {
            case 0:
                rawData = pnm.GetHistogramLuminosity();
                break;

            case 1:
                rawData = pnm.GetHistogramRed();
                break;

            case 2:
                rawData = pnm.GetHistogramGreen();
                break;

            case 3:
                rawData = pnm.GetHistogramBlue();
                break;

            default:
                return(Binding.DoNothing);
            }

            return(BuildHistogramGeometry(rawData));
        }
Пример #26
0
 public void Undo()
 {
     image = undoList.Pop();
     OnPropertyChanged("Image");
 }
Пример #27
0
 public static PNM Copy(PNM image)
 {
     PNM newImage = new PNM(image.Width, image.Height);
     Buffer.BlockCopy(image.raster, 0, newImage.raster, 0, image.raster.Length);
     return newImage;
 }
Пример #28
0
 internal static void Trim(PNM image, int padding)
 {
     image.raster  = Trim(image.raster, image.Width * 3, image.Height, padding * 3, padding);
     image.Width  -= 2 * padding;
     image.Height -= 2 * padding;
 }
Пример #29
0
 internal void SaveImage(string path, PNMFormat format)
 {
     PNM.SaveFile(Image, path, format);
     Path   = path;
     Format = format;
 }
Пример #30
0
 public void Undo()
 {
     image = undoList.Pop();
     OnPropertyChanged("Image");
 }
Пример #31
0
 internal void SaveImage()
 {
     PNM.SaveFile(Image, Path, Format);
     Path = path;
 }
Пример #32
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);
        }
Пример #33
0
 private static void MarkPixel(PNM image, int index)
 {
     int x = index % image.Width;
     int y = index / image.Width;
     for (int x0 = -1; x0 <= 1; x0++)
     {
         for (int y0 = -1; y0 <= 1; y0++)
         {
             if(x0 == 0 && y0 == 0)
                 continue;
             int currentY = y + y0;
             int currentX = x + x0;
             if(currentX < 0 || currentX >= image.Width || currentY < 0 || currentY >= image.Height)
                 continue;
             image.SetPixel(x + x0, y + y0, 0, 255, 0);
         }
     }
 }