private unsafe void generateBackprojectionMap(UnmanagedImage frame, float[] ratioHistogram)
{
int width = frame.Width;
int height = frame.Height;
int stride = frame.Stride;
int pixelSize = Bitmap.GetPixelFormatSize(frame.PixelFormat) / 8;
int offset = stride - width * pixelSize;
fixed (float* map_ptr = map)
{
byte* src = (byte*)frame.ImageData.ToPointer();
float* dst = map_ptr;
if (mode == CamshiftMode.HSL)
{
// Process as HSL
HSL hsl = new HSL();
RGB rgb = new RGB();
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++, src += pixelSize, dst++)
{
// RGB
rgb.Red = (*(src + RGB.R));
rgb.Green = (*(src + RGB.G));
rgb.Blue = (*(src + RGB.B));
// Transform into HSL
Accord.Imaging.HSL.FromRGB(rgb, hsl);
if ((hsl.Saturation >= hslSaturation.Min) && (hsl.Saturation <= hslSaturation.Max) &&
(hsl.Luminance >= hslLuminance.Min) && (hsl.Luminance <= hslLuminance.Max))
*dst = ratioHistogram[hsl.Hue];
else *dst = 0;
}
src += offset;
}
}
else if (mode == CamshiftMode.Mixed)
{
// Process in mixed mode
HSL hsl = new HSL();
RGB rgb = new RGB();
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++, src += pixelSize, dst++)
{
// RGB
rgb.Red = (*(src + RGB.R));
rgb.Green = (*(src + RGB.G));
rgb.Blue = (*(src + RGB.B));
// Transform into HSL
Accord.Imaging.HSL.FromRGB(rgb, hsl);
if ((hsl.Saturation >= hslSaturation.Min) && (hsl.Saturation <= hslSaturation.Max) &&
(hsl.Luminance >= hslLuminance.Min) && (hsl.Luminance <= hslLuminance.Max))
*dst = ratioHistogram[(int)(hsl.Hue * 10 + hsl.Saturation * 100 + hsl.Luminance * 10)];
else *dst = 0;
}
src += offset;
}
}
else
{
// Process as RGB
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++, src += pixelSize, dst++)
{
// RGB
int r = (int)(*(src + RGB.R)) >> 4;
int g = (int)(*(src + RGB.G)) >> 4;
int b = (int)(*(src + RGB.B)) >> 4;
*dst = ratioHistogram[256 * r + 16 * g + b];
}
src += offset;
}
}
}
}