241 lines
8.1 KiB
C#
241 lines
8.1 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Drawing.Imaging;
|
|
using AForge.Math;
|
|
|
|
namespace AForge.Imaging;
|
|
|
|
public class ImageStatisticsYCbCr
|
|
{
|
|
private ContinuousHistogram yHistogram;
|
|
|
|
private ContinuousHistogram cbHistogram;
|
|
|
|
private ContinuousHistogram crHistogram;
|
|
|
|
private ContinuousHistogram yHistogramWithoutBlack;
|
|
|
|
private ContinuousHistogram cbHistogramWithoutBlack;
|
|
|
|
private ContinuousHistogram crHistogramWithoutBlack;
|
|
|
|
private int pixels;
|
|
|
|
private int pixelsWithoutBlack;
|
|
|
|
public ContinuousHistogram Y => yHistogram;
|
|
|
|
public ContinuousHistogram Cb => cbHistogram;
|
|
|
|
public ContinuousHistogram Cr => crHistogram;
|
|
|
|
public ContinuousHistogram YWithoutBlack => yHistogramWithoutBlack;
|
|
|
|
public ContinuousHistogram CbWithoutBlack => cbHistogramWithoutBlack;
|
|
|
|
public ContinuousHistogram CrWithoutBlack => crHistogramWithoutBlack;
|
|
|
|
public int PixelsCount => pixels;
|
|
|
|
public int PixelsCountWithoutBlack => pixelsWithoutBlack;
|
|
|
|
public unsafe ImageStatisticsYCbCr(Bitmap image)
|
|
{
|
|
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
|
|
CheckSourceFormat(((Image)image).PixelFormat);
|
|
BitmapData val = image.LockBits(new Rectangle(0, 0, ((Image)image).Width, ((Image)image).Height), (ImageLockMode)1, (PixelFormat)137224);
|
|
try
|
|
{
|
|
ProcessImage(new UnmanagedImage(val), null, 0);
|
|
}
|
|
finally
|
|
{
|
|
image.UnlockBits(val);
|
|
}
|
|
}
|
|
|
|
public unsafe ImageStatisticsYCbCr(Bitmap image, Bitmap mask)
|
|
{
|
|
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
|
|
CheckSourceFormat(((Image)image).PixelFormat);
|
|
CheckMaskProperties(((Image)mask).PixelFormat, new Size(((Image)mask).Width, ((Image)mask).Height), new Size(((Image)image).Width, ((Image)image).Height));
|
|
BitmapData val = image.LockBits(new Rectangle(0, 0, ((Image)image).Width, ((Image)image).Height), (ImageLockMode)1, ((Image)image).PixelFormat);
|
|
BitmapData val2 = mask.LockBits(new Rectangle(0, 0, ((Image)mask).Width, ((Image)mask).Height), (ImageLockMode)1, ((Image)mask).PixelFormat);
|
|
try
|
|
{
|
|
ProcessImage(new UnmanagedImage(val), (byte*)val2.Scan0.ToPointer(), val2.Stride);
|
|
}
|
|
finally
|
|
{
|
|
image.UnlockBits(val);
|
|
mask.UnlockBits(val2);
|
|
}
|
|
}
|
|
|
|
public unsafe ImageStatisticsYCbCr(Bitmap image, byte[,] mask)
|
|
{
|
|
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
|
|
CheckSourceFormat(((Image)image).PixelFormat);
|
|
CheckMaskProperties((PixelFormat)198659, new Size(mask.GetLength(1), mask.GetLength(0)), new Size(((Image)image).Width, ((Image)image).Height));
|
|
BitmapData val = image.LockBits(new Rectangle(0, 0, ((Image)image).Width, ((Image)image).Height), (ImageLockMode)1, ((Image)image).PixelFormat);
|
|
try
|
|
{
|
|
fixed (byte* mask2 = mask)
|
|
{
|
|
ProcessImage(new UnmanagedImage(val), mask2, mask.GetLength(1));
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
image.UnlockBits(val);
|
|
}
|
|
}
|
|
|
|
public unsafe ImageStatisticsYCbCr(UnmanagedImage image)
|
|
{
|
|
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
|
|
CheckSourceFormat(image.PixelFormat);
|
|
ProcessImage(image, null, 0);
|
|
}
|
|
|
|
public unsafe ImageStatisticsYCbCr(UnmanagedImage image, UnmanagedImage mask)
|
|
{
|
|
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
|
|
CheckSourceFormat(image.PixelFormat);
|
|
CheckMaskProperties(mask.PixelFormat, new Size(mask.Width, mask.Height), new Size(image.Width, image.Height));
|
|
ProcessImage(image, (byte*)mask.ImageData.ToPointer(), mask.Stride);
|
|
}
|
|
|
|
public unsafe ImageStatisticsYCbCr(UnmanagedImage image, byte[,] mask)
|
|
{
|
|
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
|
|
CheckSourceFormat(image.PixelFormat);
|
|
CheckMaskProperties((PixelFormat)198659, new Size(mask.GetLength(1), mask.GetLength(0)), new Size(image.Width, image.Height));
|
|
fixed (byte* mask2 = mask)
|
|
{
|
|
ProcessImage(image, mask2, mask.GetLength(1));
|
|
}
|
|
}
|
|
|
|
private unsafe void ProcessImage(UnmanagedImage image, byte* mask, int maskLineSize)
|
|
{
|
|
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_007f: Invalid comparison between Unknown and I4
|
|
int width = image.Width;
|
|
int height = image.Height;
|
|
pixels = (pixelsWithoutBlack = 0);
|
|
int[] array = new int[256];
|
|
int[] array2 = new int[256];
|
|
int[] array3 = new int[256];
|
|
int[] array4 = new int[256];
|
|
int[] array5 = new int[256];
|
|
int[] array6 = new int[256];
|
|
RGB rGB = new RGB();
|
|
YCbCr yCbCr = new YCbCr();
|
|
int num = (((int)image.PixelFormat == 137224) ? 3 : 4);
|
|
int num2 = image.Stride - width * num;
|
|
int num3 = maskLineSize - width;
|
|
byte* ptr = (byte*)image.ImageData.ToPointer();
|
|
if (mask == null)
|
|
{
|
|
for (int i = 0; i < height; i++)
|
|
{
|
|
int num4 = 0;
|
|
while (num4 < width)
|
|
{
|
|
rGB.Red = ptr[2];
|
|
rGB.Green = ptr[1];
|
|
rGB.Blue = *ptr;
|
|
YCbCr.FromRGB(rGB, yCbCr);
|
|
array[(int)(yCbCr.Y * 255f)]++;
|
|
array2[(int)(((double)yCbCr.Cb + 0.5) * 255.0)]++;
|
|
array3[(int)(((double)yCbCr.Cr + 0.5) * 255.0)]++;
|
|
pixels++;
|
|
if ((double)yCbCr.Y != 0.0 || (double)yCbCr.Cb != 0.0 || (double)yCbCr.Cr != 0.0)
|
|
{
|
|
array4[(int)(yCbCr.Y * 255f)]++;
|
|
array5[(int)(((double)yCbCr.Cb + 0.5) * 255.0)]++;
|
|
array6[(int)(((double)yCbCr.Cr + 0.5) * 255.0)]++;
|
|
pixelsWithoutBlack++;
|
|
}
|
|
num4++;
|
|
ptr += num;
|
|
}
|
|
ptr += num2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int j = 0; j < height; j++)
|
|
{
|
|
int num5 = 0;
|
|
while (num5 < width)
|
|
{
|
|
if (*mask != 0)
|
|
{
|
|
rGB.Red = ptr[2];
|
|
rGB.Green = ptr[1];
|
|
rGB.Blue = *ptr;
|
|
YCbCr.FromRGB(rGB, yCbCr);
|
|
array[(int)(yCbCr.Y * 255f)]++;
|
|
array2[(int)(((double)yCbCr.Cb + 0.5) * 255.0)]++;
|
|
array3[(int)(((double)yCbCr.Cr + 0.5) * 255.0)]++;
|
|
pixels++;
|
|
if ((double)yCbCr.Y != 0.0 || (double)yCbCr.Cb != 0.0 || (double)yCbCr.Cr != 0.0)
|
|
{
|
|
array4[(int)(yCbCr.Y * 255f)]++;
|
|
array5[(int)(((double)yCbCr.Cb + 0.5) * 255.0)]++;
|
|
array6[(int)(((double)yCbCr.Cr + 0.5) * 255.0)]++;
|
|
pixelsWithoutBlack++;
|
|
}
|
|
}
|
|
num5++;
|
|
ptr += num;
|
|
mask++;
|
|
}
|
|
ptr += num2;
|
|
mask += num3;
|
|
}
|
|
}
|
|
yHistogram = new ContinuousHistogram(array, new Range(0f, 1f));
|
|
cbHistogram = new ContinuousHistogram(array2, new Range(-0.5f, 0.5f));
|
|
crHistogram = new ContinuousHistogram(array3, new Range(-0.5f, 0.5f));
|
|
yHistogramWithoutBlack = new ContinuousHistogram(array4, new Range(0f, 1f));
|
|
cbHistogramWithoutBlack = new ContinuousHistogram(array5, new Range(-0.5f, 0.5f));
|
|
crHistogramWithoutBlack = new ContinuousHistogram(array6, new Range(-0.5f, 0.5f));
|
|
}
|
|
|
|
private void CheckSourceFormat(PixelFormat pixelFormat)
|
|
{
|
|
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0006: Invalid comparison between Unknown and I4
|
|
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_000e: Invalid comparison between Unknown and I4
|
|
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0016: Invalid comparison between Unknown and I4
|
|
if ((int)pixelFormat != 137224 && (int)pixelFormat != 139273 && (int)pixelFormat != 2498570)
|
|
{
|
|
throw new UnsupportedImageFormatException("Source pixel format is not supported.");
|
|
}
|
|
}
|
|
|
|
private void CheckMaskProperties(PixelFormat maskFormat, Size maskSize, Size sourceImageSize)
|
|
{
|
|
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0006: Invalid comparison between Unknown and I4
|
|
if ((int)maskFormat != 198659)
|
|
{
|
|
throw new ArgumentException("Mask image must be 8 bpp grayscale image.");
|
|
}
|
|
if (maskSize.Width != sourceImageSize.Width || maskSize.Height != sourceImageSize.Height)
|
|
{
|
|
throw new ArgumentException("Mask must have the same size as the source image to get statistics for.");
|
|
}
|
|
}
|
|
}
|