Beispiel #1
0
        public void water_test()
        {
            Bitmap water = Accord.Imaging.Image.Clone(Resources.water);

            var    dt     = new DistanceTransform();
            Bitmap result = dt.Apply(water);

            Assert.AreEqual(111.364265, dt.MaximumDistance, 1e-5);
            Assert.AreEqual(new IntPoint(436, 310), dt.UltimateErodedPoint);
            Assert.IsNotNull(result);

            float[] distance1D;
            new ImageToArray().Convert(result, out distance1D);

            float[][] distance;
            new ImageToMatrix().Convert(result, out distance);

            Assert.AreEqual(distance1D.Sum(), distance.Sum());

            float[][] distances2 = Jagged.Reshape(dt.Pixels, result.Height, result.Width);
            float     actual     = distances2[84][533];
            float     expected   = 1.4142135f;

            Assert.AreEqual(expected, actual);
        }
Beispiel #2
0
        /// <summary>
        /// Processes the filter.
        /// </summary>
        /// <param name="image">The image.</param>
        protected override void ProcessFilter(UnmanagedImage image)
        {
            if (image.PixelFormat != PixelFormat.Format8bppIndexed)
            {
                throw new UnsupportedImageFormatException("Binary Watershed only works in grayscale (binary) images");
            }

            int width  = image.Width;
            int height = image.Height;

            DistanceTransform dt = new DistanceTransform(this.distance);
            UnmanagedImage    d  = dt.Apply(image);

            // Convert 2D to 1D - ImageJ Compatibility
            float[]   distance1D = dt.Pixels;
            float[][] distance   = Jagged.Reshape(distance1D, height, width);

            Debug.Assert(distance1D.Length == d.Size);
            Debug.Assert(distance.GetTotalLength() == d.Size);

            // Make directions offsets
            makeDirectionOffsets(width);

            byte[] back = new byte[width * height];

            // Find the maxima
            long[] maxPoints = getSortedMaxPoints(distance, distance1D, back, 0, dt.MaximumDistance, -808080.0);

            // Mark the maxima locations
            float maxSortingError = 1.1f * SQRT2 / 2f;

            this.maxPoints = analyseAndMarkMaxima(distance1D, back, maxPoints, tolerance, maxSortingError, width, height);

            // Transform em 8bit 0..255
            byte[] outImage = make8Bit(distance, back, dt.MaximumDistance, -808080.0, width, height);

            cleanupMaxima(outImage, back, maxPoints, width, height);
            watershedSegment(outImage, width, height);
            watershedPostProcess(outImage);

            unsafe
            {
                int   offset = image.Offset;
                byte *dst    = (byte *)image.ImageData;
                for (int y = 0, k = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++, dst++, k++)
                    {
                        *dst = outImage[k];
                    }
                    dst += offset;
                }
            }
        }