Пример #1
0
        /// <summary>
        ///   Process image looking for interest points.
        /// </summary>
        ///
        /// <param name="image">Source image data to process.</param>
        ///
        /// <returns>Returns list of found features points.</returns>
        ///
        /// <exception cref="UnsupportedImageFormatException">
        ///   The source image has incorrect pixel format.
        /// </exception>
        ///
        public List <double[]> ProcessImage(UnmanagedImage image)
        {
            // check image format
            if (
                (image.PixelFormat != PixelFormat.Format8bppIndexed) &&
                (image.PixelFormat != PixelFormat.Format24bppRgb) &&
                (image.PixelFormat != PixelFormat.Format32bppRgb) &&
                (image.PixelFormat != PixelFormat.Format32bppArgb)
                )
            {
                throw new UnsupportedImageFormatException("Unsupported pixel format of the source image.");
            }

            // make sure we have grayscale image
            UnmanagedImage grayImage = null;

            if (image.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                grayImage = image;
            }
            else
            {
                // create temporary grayscale image
                grayImage = Grayscale.CommonAlgorithms.BT709.Apply(image);
            }


            // get source image size
            int width  = grayImage.Width;
            int height = grayImage.Height;


            matrix = new GrayLevelCooccurrenceMatrix(distance,
                                                     CooccurrenceDegree.Degree0, true, autoGray);

            if (cellSize > 0)
            {
                int cellCountX = (int)Math.Floor(width / (double)cellSize);
                int cellCountY = (int)Math.Floor(height / (double)cellSize);
                features = new HaralickDescriptorDictionary[cellCountX, cellCountY];

                // For each cell
                for (int i = 0; i < cellCountX; i++)
                {
                    for (int j = 0; j < cellCountY; j++)
                    {
                        var featureDict = new HaralickDescriptorDictionary();

                        Rectangle region = new Rectangle(
                            i * cellSize, j * cellSize, cellSize, cellSize);

                        foreach (CooccurrenceDegree degree in degrees)
                        {
                            matrix.Degree       = degree;
                            double[,] glcm      = matrix.Compute(grayImage, region);
                            featureDict[degree] = new HaralickDescriptor(glcm);
                        }

                        features[i, j] = featureDict;
                    }
                }
            }
            else
            {
                features       = new HaralickDescriptorDictionary[1, 1];
                features[0, 0] = new HaralickDescriptorDictionary();
                foreach (CooccurrenceDegree degree in degrees)
                {
                    matrix.Degree          = degree;
                    double[,] glcm         = matrix.Compute(grayImage);
                    features[0, 0][degree] = new HaralickDescriptor(glcm);
                }
            }

            // Free some resources which wont be needed anymore
            if (image.PixelFormat != PixelFormat.Format8bppIndexed)
            {
                grayImage.Dispose();
            }



            var blocks = new List <double[]>();

            switch (mode)
            {
            case HaralickMode.Average:
                foreach (HaralickDescriptorDictionary feature in features)
                {
                    blocks.Add(feature.Average(featureCount));
                }
                break;

            case HaralickMode.AverageWithRange:
                foreach (HaralickDescriptorDictionary feature in features)
                {
                    blocks.Add(feature.AverageWithRange(featureCount));
                }
                break;

            case HaralickMode.Combine:
                foreach (HaralickDescriptorDictionary feature in features)
                {
                    blocks.Add(feature.Combine(featureCount));
                }
                break;

            case HaralickMode.NormalizedAverage:
                foreach (HaralickDescriptorDictionary feature in features)
                {
                    blocks.Add(feature.Normalize(featureCount));
                }
                break;
            }

            if (normalize)
            {
                var sum = new double[featureCount];
                foreach (double[] block in blocks)
                {
                    for (int i = 0; i < sum.Length; i++)
                    {
                        sum[i] += block[i];
                    }
                }

                foreach (double[] block in blocks)
                {
                    for (int i = 0; i < sum.Length; i++)
                    {
                        block[i] /= sum[i];
                    }
                }
            }

            return(blocks);
        }
Пример #2
0
        /// <summary>
        ///   This method should be implemented by inheriting classes to implement the
        ///   actual feature extraction, transforming the input image into a list of features.
        /// </summary>
        ///
        protected override IEnumerable <FeatureDescriptor> InnerTransform(UnmanagedImage image)
        {
            // TODO: Improve memory usage of this method by
            // caching into class variables whenever possible

            // make sure we have grayscale image
            UnmanagedImage grayImage = null;

            if (image.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                grayImage = image;
            }
            else
            {
                // create temporary grayscale image
                grayImage = Grayscale.CommonAlgorithms.BT709.Apply(image);
            }


            // get source image size
            int width  = grayImage.Width;
            int height = grayImage.Height;


            this.matrix = new GrayLevelCooccurrenceMatrix(distance,
                                                          CooccurrenceDegree.Degree0, normalize: true, autoGray: autoGray);

            if (cellSize > 0)
            {
                int cellCountX = (int)Math.Floor(width / (double)cellSize);
                int cellCountY = (int)Math.Floor(height / (double)cellSize);
                this.features = new HaralickDescriptorDictionary[cellCountX, cellCountY];

                // For each cell
                for (int i = 0; i < cellCountX; i++)
                {
                    for (int j = 0; j < cellCountY; j++)
                    {
                        var dict = new HaralickDescriptorDictionary();

                        var region = new Rectangle(i * cellSize, j * cellSize, cellSize, cellSize);

                        foreach (CooccurrenceDegree degree in degrees)
                        {
                            matrix.Degree  = degree;
                            double[,] glcm = matrix.Compute(grayImage, region);
                            dict[degree]   = new HaralickDescriptor(glcm);
                        }

                        this.features[i, j] = dict;
                    }
                }
            }
            else
            {
                var dict = new HaralickDescriptorDictionary();
                foreach (CooccurrenceDegree degree in degrees)
                {
                    matrix.Degree  = degree;
                    double[,] glcm = matrix.Compute(grayImage);
                    dict[degree]   = new HaralickDescriptor(glcm);
                }

                this.features = new HaralickDescriptorDictionary[, ] {
                    { dict }
                };
            }

            // Free some resources which wont be needed anymore
            if (image.PixelFormat != PixelFormat.Format8bppIndexed)
            {
                grayImage.Dispose();
            }



            var blocks = new List <FeatureDescriptor>();

            switch (mode)
            {
            case HaralickMode.Average:
                foreach (HaralickDescriptorDictionary feature in features)
                {
                    blocks.Add(feature.Average(featureCount));
                }
                break;

            case HaralickMode.AverageWithRange:
                foreach (HaralickDescriptorDictionary feature in features)
                {
                    blocks.Add(feature.AverageWithRange(featureCount));
                }
                break;

            case HaralickMode.Combine:
                foreach (HaralickDescriptorDictionary feature in features)
                {
                    blocks.Add(feature.Combine(featureCount));
                }
                break;

            case HaralickMode.NormalizedAverage:
                foreach (HaralickDescriptorDictionary feature in features)
                {
                    blocks.Add(feature.Normalize(featureCount));
                }
                break;
            }

            if (normalize)
            {
                // TODO: Remove this block and instead propose a general architecture
                //       for applying normalizations to descriptor blocks
                foreach (FeatureDescriptor block in blocks)
                {
                    block.Descriptor.Divide(block.Descriptor.Euclidean() + epsilon, result: block.Descriptor);
                }
            }

            return(blocks);
        }