/// <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);
}