183 lines
4.4 KiB
C#
183 lines
4.4 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Drawing.Imaging;
|
|
|
|
namespace AForge.Imaging;
|
|
|
|
public class IntegralImage
|
|
{
|
|
protected uint[,] integralImage;
|
|
|
|
private int width;
|
|
|
|
private int height;
|
|
|
|
public int Width => width;
|
|
|
|
public int Height => height;
|
|
|
|
public uint[,] InternalData => integralImage;
|
|
|
|
protected IntegralImage(int width, int height)
|
|
{
|
|
this.width = width;
|
|
this.height = height;
|
|
integralImage = new uint[height + 1, width + 1];
|
|
}
|
|
|
|
public static IntegralImage FromBitmap(Bitmap image)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_000b: Invalid comparison between Unknown and I4
|
|
if ((int)((Image)image).PixelFormat != 198659)
|
|
{
|
|
throw new UnsupportedImageFormatException("Source image can be graysclae (8 bpp indexed) image only.");
|
|
}
|
|
BitmapData val = image.LockBits(new Rectangle(0, 0, ((Image)image).Width, ((Image)image).Height), (ImageLockMode)1, (PixelFormat)198659);
|
|
IntegralImage result = FromBitmap(val);
|
|
image.UnlockBits(val);
|
|
return result;
|
|
}
|
|
|
|
public static IntegralImage FromBitmap(BitmapData imageData)
|
|
{
|
|
return FromBitmap(new UnmanagedImage(imageData));
|
|
}
|
|
|
|
public unsafe static IntegralImage FromBitmap(UnmanagedImage image)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_000b: Invalid comparison between Unknown and I4
|
|
if ((int)image.PixelFormat != 198659)
|
|
{
|
|
throw new ArgumentException("Source image can be graysclae (8 bpp indexed) image only.");
|
|
}
|
|
int num = image.Width;
|
|
int num2 = image.Height;
|
|
int num3 = image.Stride - num;
|
|
IntegralImage integralImage = new IntegralImage(num, num2);
|
|
uint[,] array = integralImage.integralImage;
|
|
byte* ptr = (byte*)image.ImageData.ToPointer();
|
|
for (int i = 1; i <= num2; i++)
|
|
{
|
|
uint num4 = 0u;
|
|
int num5 = 1;
|
|
while (num5 <= num)
|
|
{
|
|
num4 += *ptr;
|
|
array[i, num5] = num4 + array[i - 1, num5];
|
|
num5++;
|
|
ptr++;
|
|
}
|
|
ptr += num3;
|
|
}
|
|
return integralImage;
|
|
}
|
|
|
|
public uint GetRectangleSum(int x1, int y1, int x2, int y2)
|
|
{
|
|
if (x2 < 0 || y2 < 0 || x1 >= width || y1 >= height)
|
|
{
|
|
return 0u;
|
|
}
|
|
if (x1 < 0)
|
|
{
|
|
x1 = 0;
|
|
}
|
|
if (y1 < 0)
|
|
{
|
|
y1 = 0;
|
|
}
|
|
x2++;
|
|
y2++;
|
|
if (x2 > width)
|
|
{
|
|
x2 = width;
|
|
}
|
|
if (y2 > height)
|
|
{
|
|
y2 = height;
|
|
}
|
|
return integralImage[y2, x2] + integralImage[y1, x1] - integralImage[y2, x1] - integralImage[y1, x2];
|
|
}
|
|
|
|
public int GetHaarXWavelet(int x, int y, int radius)
|
|
{
|
|
int y2 = y - radius;
|
|
int y3 = y + radius - 1;
|
|
uint rectangleSum = GetRectangleSum(x, y2, x + radius - 1, y3);
|
|
uint rectangleSum2 = GetRectangleSum(x - radius, y2, x - 1, y3);
|
|
return (int)(rectangleSum - rectangleSum2);
|
|
}
|
|
|
|
public int GetHaarYWavelet(int x, int y, int radius)
|
|
{
|
|
int x2 = x - radius;
|
|
int x3 = x + radius - 1;
|
|
float num = GetRectangleSum(x2, y, x3, y + radius - 1);
|
|
float num2 = GetRectangleSum(x2, y - radius, x3, y - 1);
|
|
return (int)(num - num2);
|
|
}
|
|
|
|
public uint GetRectangleSumUnsafe(int x1, int y1, int x2, int y2)
|
|
{
|
|
x2++;
|
|
y2++;
|
|
return integralImage[y2, x2] + integralImage[y1, x1] - integralImage[y2, x1] - integralImage[y1, x2];
|
|
}
|
|
|
|
public uint GetRectangleSum(int x, int y, int radius)
|
|
{
|
|
return GetRectangleSum(x - radius, y - radius, x + radius, y + radius);
|
|
}
|
|
|
|
public uint GetRectangleSumUnsafe(int x, int y, int radius)
|
|
{
|
|
return GetRectangleSumUnsafe(x - radius, y - radius, x + radius, y + radius);
|
|
}
|
|
|
|
public float GetRectangleMean(int x1, int y1, int x2, int y2)
|
|
{
|
|
if (x2 < 0 || y2 < 0 || x1 >= width || y1 >= height)
|
|
{
|
|
return 0f;
|
|
}
|
|
if (x1 < 0)
|
|
{
|
|
x1 = 0;
|
|
}
|
|
if (y1 < 0)
|
|
{
|
|
y1 = 0;
|
|
}
|
|
x2++;
|
|
y2++;
|
|
if (x2 > width)
|
|
{
|
|
x2 = width;
|
|
}
|
|
if (y2 > height)
|
|
{
|
|
y2 = height;
|
|
}
|
|
return (float)((double)(integralImage[y2, x2] + integralImage[y1, x1] - integralImage[y2, x1] - integralImage[y1, x2]) / (double)((x2 - x1) * (y2 - y1)));
|
|
}
|
|
|
|
public float GetRectangleMeanUnsafe(int x1, int y1, int x2, int y2)
|
|
{
|
|
x2++;
|
|
y2++;
|
|
return (float)((double)(integralImage[y2, x2] + integralImage[y1, x1] - integralImage[y2, x1] - integralImage[y1, x2]) / (double)((x2 - x1) * (y2 - y1)));
|
|
}
|
|
|
|
public float GetRectangleMean(int x, int y, int radius)
|
|
{
|
|
return GetRectangleMean(x - radius, y - radius, x + radius, y + radius);
|
|
}
|
|
|
|
public float GetRectangleMeanUnsafe(int x, int y, int radius)
|
|
{
|
|
return GetRectangleMeanUnsafe(x - radius, y - radius, x + radius, y + radius);
|
|
}
|
|
}
|