public double GetSkewAngle( UnmanagedImage image, Rectangle rect )
{
if ( image.PixelFormat != PixelFormat.Format8bppIndexed )
{
throw new UnsupportedImageFormatException( "Unsupported pixel format of the source image." );
}
// init hough transformation settings
InitHoughMap( );
// get source image size
int width = image.Width;
int height = image.Height;
int halfWidth = width / 2;
int halfHeight = height / 2;
// make sure the specified rectangle recides with the source image
rect.Intersect( new Rectangle( 0, 0, width, height ) );
int startX = -halfWidth + rect.Left;
int startY = -halfHeight + rect.Top;
int stopX = width - halfWidth - ( width - rect.Right );
int stopY = height - halfHeight - ( height - rect.Bottom ) - 1;
int offset = image.Stride - rect.Width;
// calculate Hough map's width
int halfHoughWidth = (int) Math.Sqrt( halfWidth * halfWidth + halfHeight * halfHeight );
int houghWidth = halfHoughWidth * 2;
houghMap = new short[houghHeight, houghWidth];
// do the job
unsafe
{
byte* src = (byte*) image.ImageData.ToPointer( ) +
rect.Top * image.Stride + rect.Left;
byte* srcBelow = src + image.Stride;
// for each row
for ( int y = startY; y < stopY; y++ )
{
// for each pixel
for ( int x = startX; x < stopX; x++, src++, srcBelow++ )
{
// if current pixel is more black
// and pixel below is more white
if ( ( *src < 128 ) && ( *srcBelow >= 128 ) )
{
// for each Theta value
for ( int theta = 0; theta < houghHeight; theta++ )
{
int radius = (int) ( cosMap[theta] * x - sinMap[theta] * y ) + halfHoughWidth;
if ( ( radius < 0 ) || ( radius >= houghWidth ) )
continue;
houghMap[theta, radius]++;
}
}
}
src += offset;
srcBelow += offset;
}
}
// find max value in Hough map
maxMapIntensity = 0;
for ( int i = 0; i < houghHeight; i++ )
{
for ( int j = 0; j < houghWidth; j++ )
{
if ( houghMap[i, j] > maxMapIntensity )
{
maxMapIntensity = houghMap[i, j];
}
}
}
CollectLines( (short) ( width / 10 ) );
// get skew angle
HoughLine[] hls = this.GetMostIntensiveLines( 5 );
double skewAngle = 0;
double sumIntensity = 0;
foreach ( HoughLine hl in hls )
{
if ( hl.RelativeIntensity > 0.5 )
{
skewAngle += ( hl.Theta * hl.RelativeIntensity );
sumIntensity += hl.RelativeIntensity;
}
}
if ( hls.Length > 0 ) skewAngle = skewAngle / sumIntensity;
return skewAngle - 90.0;
}