public List<IntPoint> 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." );
}
// get source image size
int width = image.Width;
int height = image.Height;
int stride = image.Stride;
int pixelSize = Bitmap.GetPixelFormatSize( image.PixelFormat ) / 8;
// window radius
int windowRadius = windowSize / 2;
// offset
int offset = stride - windowSize * pixelSize;
// create moravec cornerness map
int[,] moravecMap = new int[height, width];
// do the job
unsafe
{
byte* ptr = (byte*) image.ImageData.ToPointer( );
// for each row
for ( int y = windowRadius, maxY = height - windowRadius; y < maxY; y++ )
{
// for each pixel
for ( int x = windowRadius, maxX = width - windowRadius; x < maxX; x++ )
{
int minSum = int.MaxValue;
// go through 8 possible shifting directions
for ( int k = 0; k < 8; k++ )
{
// calculate center of shifted window
int sy = y + yDelta[k];
int sx = x + xDelta[k];
// check if shifted window is within the image
if (
( sy < windowRadius ) || ( sy >= maxY ) ||
( sx < windowRadius ) || ( sx >= maxX )
)
{
// skip this shifted window
continue;
}
int sum = 0;
byte* ptr1 = ptr + ( y - windowRadius ) * stride + ( x - windowRadius ) * pixelSize;
byte* ptr2 = ptr + ( sy - windowRadius ) * stride + ( sx - windowRadius ) * pixelSize;
// for each windows' rows
for ( int i = 0; i < windowSize; i++ )
{
// for each windows' pixels
for ( int j = 0, maxJ = windowSize * pixelSize; j < maxJ; j++, ptr1++, ptr2++ )
{
int dif = *ptr1 - *ptr2;
sum += dif * dif;
}
ptr1 += offset;
ptr2 += offset;
}
// check if the sum is mimimal
if ( sum < minSum )
{
minSum = sum;
}
}
// threshold the minimum sum
if ( minSum < threshold )
{
minSum = 0;
}
moravecMap[y, x] = minSum;
}
}
}
// collect interesting points - only those points, which are local maximums
List<IntPoint> cornersList = new List<IntPoint>( );
// for each row
for ( int y = windowRadius, maxY = height - windowRadius; y < maxY; y++ )
{
// for each pixel
for ( int x = windowRadius, maxX = width - windowRadius; x < maxX; x++ )
{
int currentValue = moravecMap[y, x];
// for each windows' rows
for ( int i = -windowRadius; ( currentValue != 0 ) && ( i <= windowRadius ); i++ )
{
// for each windows' pixels
for ( int j = -windowRadius; j <= windowRadius; j++ )
{
if ( moravecMap[y + i, x + j] > currentValue )
{
currentValue = 0;
break;
}
}
}
// check if this point is really interesting
if ( currentValue != 0 )
{
cornersList.Add( new IntPoint( x, y ) );
}
}
}
return cornersList;
}
}