799 lines
19 KiB
C#
799 lines
19 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Drawing.Imaging;
|
|
|
|
namespace AForge.Imaging;
|
|
|
|
public abstract class BlobCounterBase
|
|
{
|
|
private class BlobsSorter : IComparer<Blob>
|
|
{
|
|
private ObjectsOrder order;
|
|
|
|
public BlobsSorter(ObjectsOrder order)
|
|
{
|
|
this.order = order;
|
|
}
|
|
|
|
public int Compare(Blob a, Blob b)
|
|
{
|
|
Rectangle rectangle = a.Rectangle;
|
|
Rectangle rectangle2 = b.Rectangle;
|
|
return order switch
|
|
{
|
|
ObjectsOrder.Size => rectangle2.Width * rectangle2.Height - rectangle.Width * rectangle.Height,
|
|
ObjectsOrder.Area => b.Area - a.Area,
|
|
ObjectsOrder.YX => rectangle.Y * 100000 + rectangle.X - (rectangle2.Y * 100000 + rectangle2.X),
|
|
ObjectsOrder.XY => rectangle.X * 100000 + rectangle.Y - (rectangle2.X * 100000 + rectangle2.Y),
|
|
_ => 0,
|
|
};
|
|
}
|
|
}
|
|
|
|
private List<Blob> blobs = new List<Blob>();
|
|
|
|
private ObjectsOrder objectsOrder;
|
|
|
|
private bool filterBlobs;
|
|
|
|
private IBlobsFilter filter;
|
|
|
|
private bool coupledSizeFiltering;
|
|
|
|
private int minWidth = 1;
|
|
|
|
private int minHeight = 1;
|
|
|
|
private int maxWidth = int.MaxValue;
|
|
|
|
private int maxHeight = int.MaxValue;
|
|
|
|
protected int objectsCount;
|
|
|
|
protected int[] objectLabels;
|
|
|
|
protected int imageWidth;
|
|
|
|
protected int imageHeight;
|
|
|
|
public int ObjectsCount => objectsCount;
|
|
|
|
public int[] ObjectLabels => objectLabels;
|
|
|
|
public ObjectsOrder ObjectsOrder
|
|
{
|
|
get
|
|
{
|
|
return objectsOrder;
|
|
}
|
|
set
|
|
{
|
|
objectsOrder = value;
|
|
}
|
|
}
|
|
|
|
public bool FilterBlobs
|
|
{
|
|
get
|
|
{
|
|
return filterBlobs;
|
|
}
|
|
set
|
|
{
|
|
filterBlobs = value;
|
|
}
|
|
}
|
|
|
|
public bool CoupledSizeFiltering
|
|
{
|
|
get
|
|
{
|
|
return coupledSizeFiltering;
|
|
}
|
|
set
|
|
{
|
|
coupledSizeFiltering = value;
|
|
}
|
|
}
|
|
|
|
public int MinWidth
|
|
{
|
|
get
|
|
{
|
|
return minWidth;
|
|
}
|
|
set
|
|
{
|
|
minWidth = value;
|
|
}
|
|
}
|
|
|
|
public int MinHeight
|
|
{
|
|
get
|
|
{
|
|
return minHeight;
|
|
}
|
|
set
|
|
{
|
|
minHeight = value;
|
|
}
|
|
}
|
|
|
|
public int MaxWidth
|
|
{
|
|
get
|
|
{
|
|
return maxWidth;
|
|
}
|
|
set
|
|
{
|
|
maxWidth = value;
|
|
}
|
|
}
|
|
|
|
public int MaxHeight
|
|
{
|
|
get
|
|
{
|
|
return maxHeight;
|
|
}
|
|
set
|
|
{
|
|
maxHeight = value;
|
|
}
|
|
}
|
|
|
|
public IBlobsFilter BlobsFilter
|
|
{
|
|
get
|
|
{
|
|
return filter;
|
|
}
|
|
set
|
|
{
|
|
filter = value;
|
|
}
|
|
}
|
|
|
|
public BlobCounterBase()
|
|
{
|
|
}
|
|
|
|
public BlobCounterBase(Bitmap image)
|
|
{
|
|
ProcessImage(image);
|
|
}
|
|
|
|
public BlobCounterBase(BitmapData imageData)
|
|
{
|
|
ProcessImage(imageData);
|
|
}
|
|
|
|
public BlobCounterBase(UnmanagedImage image)
|
|
{
|
|
ProcessImage(image);
|
|
}
|
|
|
|
public void ProcessImage(Bitmap image)
|
|
{
|
|
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
|
|
BitmapData val = image.LockBits(new Rectangle(0, 0, ((Image)image).Width, ((Image)image).Height), (ImageLockMode)1, ((Image)image).PixelFormat);
|
|
try
|
|
{
|
|
ProcessImage(val);
|
|
}
|
|
finally
|
|
{
|
|
image.UnlockBits(val);
|
|
}
|
|
}
|
|
|
|
public void ProcessImage(BitmapData imageData)
|
|
{
|
|
ProcessImage(new UnmanagedImage(imageData));
|
|
}
|
|
|
|
public void ProcessImage(UnmanagedImage image)
|
|
{
|
|
imageWidth = image.Width;
|
|
imageHeight = image.Height;
|
|
BuildObjectsMap(image);
|
|
CollectObjectsInfo(image);
|
|
if (filterBlobs)
|
|
{
|
|
int[] array = new int[objectsCount + 1];
|
|
for (int i = 1; i <= objectsCount; i++)
|
|
{
|
|
array[i] = i;
|
|
}
|
|
int num = 0;
|
|
if (filter == null)
|
|
{
|
|
for (int num2 = objectsCount - 1; num2 >= 0; num2--)
|
|
{
|
|
int width = blobs[num2].Rectangle.Width;
|
|
int height = blobs[num2].Rectangle.Height;
|
|
if (!coupledSizeFiltering)
|
|
{
|
|
if (width < minWidth || height < minHeight || width > maxWidth || height > maxHeight)
|
|
{
|
|
array[num2 + 1] = 0;
|
|
num++;
|
|
blobs.RemoveAt(num2);
|
|
}
|
|
}
|
|
else if ((width < minWidth && height < minHeight) || (width > maxWidth && height > maxHeight))
|
|
{
|
|
array[num2 + 1] = 0;
|
|
num++;
|
|
blobs.RemoveAt(num2);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int num3 = objectsCount - 1; num3 >= 0; num3--)
|
|
{
|
|
if (!filter.Check(blobs[num3]))
|
|
{
|
|
array[num3 + 1] = 0;
|
|
num++;
|
|
blobs.RemoveAt(num3);
|
|
}
|
|
}
|
|
}
|
|
int num4 = 0;
|
|
for (int j = 1; j <= objectsCount; j++)
|
|
{
|
|
if (array[j] != 0)
|
|
{
|
|
num4 = (array[j] = num4 + 1);
|
|
}
|
|
}
|
|
int k = 0;
|
|
for (int num5 = objectLabels.Length; k < num5; k++)
|
|
{
|
|
objectLabels[k] = array[objectLabels[k]];
|
|
}
|
|
objectsCount -= num;
|
|
int l = 0;
|
|
for (int count = blobs.Count; l < count; l++)
|
|
{
|
|
blobs[l].ID = l + 1;
|
|
}
|
|
}
|
|
if (objectsOrder != ObjectsOrder.None)
|
|
{
|
|
blobs.Sort(new BlobsSorter(objectsOrder));
|
|
}
|
|
}
|
|
|
|
public Rectangle[] GetObjectsRectangles()
|
|
{
|
|
if (objectLabels == null)
|
|
{
|
|
throw new ApplicationException("Image should be processed before to collect objects map.");
|
|
}
|
|
Rectangle[] array = new Rectangle[objectsCount];
|
|
for (int i = 0; i < objectsCount; i++)
|
|
{
|
|
ref Rectangle reference = ref array[i];
|
|
reference = blobs[i].Rectangle;
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public Blob[] GetObjectsInformation()
|
|
{
|
|
if (objectLabels == null)
|
|
{
|
|
throw new ApplicationException("Image should be processed before to collect objects map.");
|
|
}
|
|
Blob[] array = new Blob[objectsCount];
|
|
for (int i = 0; i < objectsCount; i++)
|
|
{
|
|
array[i] = new Blob(blobs[i]);
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public Blob[] GetObjects(Bitmap image, bool extractInOriginalSize)
|
|
{
|
|
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
|
|
Blob[] array = null;
|
|
BitmapData val = image.LockBits(new Rectangle(0, 0, ((Image)image).Width, ((Image)image).Height), (ImageLockMode)1, ((Image)image).PixelFormat);
|
|
try
|
|
{
|
|
return GetObjects(new UnmanagedImage(val), extractInOriginalSize);
|
|
}
|
|
finally
|
|
{
|
|
image.UnlockBits(val);
|
|
}
|
|
}
|
|
|
|
public unsafe Blob[] GetObjects(UnmanagedImage image, bool extractInOriginalSize)
|
|
{
|
|
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_001e: Invalid comparison between Unknown and I4
|
|
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_002b: Invalid comparison between Unknown and I4
|
|
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0038: Invalid comparison between Unknown and I4
|
|
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0045: Invalid comparison between Unknown and I4
|
|
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0052: Invalid comparison between Unknown and I4
|
|
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_005f: Invalid comparison between Unknown and I4
|
|
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
|
|
if (objectLabels == null)
|
|
{
|
|
throw new ApplicationException("Image should be processed before to collect objects map.");
|
|
}
|
|
if ((int)image.PixelFormat != 137224 && (int)image.PixelFormat != 198659 && (int)image.PixelFormat != 139273 && (int)image.PixelFormat != 2498570 && (int)image.PixelFormat != 139273 && (int)image.PixelFormat != 925707)
|
|
{
|
|
throw new UnsupportedImageFormatException("Unsupported pixel format of the provided image.");
|
|
}
|
|
int width = image.Width;
|
|
int height = image.Height;
|
|
int stride = image.Stride;
|
|
int num = Image.GetPixelFormatSize(image.PixelFormat) / 8;
|
|
Blob[] array = new Blob[objectsCount];
|
|
for (int i = 0; i < objectsCount; i++)
|
|
{
|
|
int width2 = blobs[i].Rectangle.Width;
|
|
int height2 = blobs[i].Rectangle.Height;
|
|
int width3 = (extractInOriginalSize ? width : width2);
|
|
int height3 = (extractInOriginalSize ? height : height2);
|
|
int x = blobs[i].Rectangle.X;
|
|
int num2 = x + width2 - 1;
|
|
int y = blobs[i].Rectangle.Y;
|
|
int num3 = y + height2 - 1;
|
|
int iD = blobs[i].ID;
|
|
UnmanagedImage unmanagedImage = UnmanagedImage.Create(width3, height3, image.PixelFormat);
|
|
byte* ptr = (byte*)image.ImageData.ToPointer() + (nint)y * (nint)stride + (nint)x * (nint)num;
|
|
byte* ptr2 = (byte*)unmanagedImage.ImageData.ToPointer();
|
|
int num4 = y * width + x;
|
|
if (extractInOriginalSize)
|
|
{
|
|
ptr2 += y * unmanagedImage.Stride + x * num;
|
|
}
|
|
int num5 = stride - width2 * num;
|
|
int num6 = unmanagedImage.Stride - width2 * num;
|
|
int num7 = width - width2;
|
|
for (int j = y; j <= num3; j++)
|
|
{
|
|
int num8 = x;
|
|
while (num8 <= num2)
|
|
{
|
|
if (objectLabels[num4] == iD)
|
|
{
|
|
*ptr2 = *ptr;
|
|
if (num > 1)
|
|
{
|
|
ptr2[1] = ptr[1];
|
|
ptr2[2] = ptr[2];
|
|
if (num > 3)
|
|
{
|
|
ptr2[3] = ptr[3];
|
|
}
|
|
}
|
|
}
|
|
num8++;
|
|
num4++;
|
|
ptr2 += num;
|
|
ptr += num;
|
|
}
|
|
ptr += num5;
|
|
ptr2 += num6;
|
|
num4 += num7;
|
|
}
|
|
array[i] = new Blob(blobs[i]);
|
|
array[i].Image = unmanagedImage;
|
|
array[i].OriginalSize = extractInOriginalSize;
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public void ExtractBlobsImage(Bitmap image, Blob blob, bool extractInOriginalSize)
|
|
{
|
|
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
|
|
BitmapData val = image.LockBits(new Rectangle(0, 0, ((Image)image).Width, ((Image)image).Height), (ImageLockMode)1, ((Image)image).PixelFormat);
|
|
try
|
|
{
|
|
ExtractBlobsImage(new UnmanagedImage(val), blob, extractInOriginalSize);
|
|
}
|
|
finally
|
|
{
|
|
image.UnlockBits(val);
|
|
}
|
|
}
|
|
|
|
public unsafe void ExtractBlobsImage(UnmanagedImage image, Blob blob, bool extractInOriginalSize)
|
|
{
|
|
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_001e: Invalid comparison between Unknown and I4
|
|
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_002b: Invalid comparison between Unknown and I4
|
|
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0038: Invalid comparison between Unknown and I4
|
|
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0045: Invalid comparison between Unknown and I4
|
|
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0052: Invalid comparison between Unknown and I4
|
|
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_005f: Invalid comparison between Unknown and I4
|
|
if (objectLabels == null)
|
|
{
|
|
throw new ApplicationException("Image should be processed before to collect objects map.");
|
|
}
|
|
if ((int)image.PixelFormat != 137224 && (int)image.PixelFormat != 198659 && (int)image.PixelFormat != 139273 && (int)image.PixelFormat != 2498570 && (int)image.PixelFormat != 139273 && (int)image.PixelFormat != 925707)
|
|
{
|
|
throw new UnsupportedImageFormatException("Unsupported pixel format of the provided image.");
|
|
}
|
|
int width = image.Width;
|
|
int height = image.Height;
|
|
int stride = image.Stride;
|
|
int num = Image.GetPixelFormatSize(image.PixelFormat) / 8;
|
|
int width2 = blob.Rectangle.Width;
|
|
int height2 = blob.Rectangle.Height;
|
|
int width3 = (extractInOriginalSize ? width : width2);
|
|
int height3 = (extractInOriginalSize ? height : height2);
|
|
int left = blob.Rectangle.Left;
|
|
int num2 = left + width2 - 1;
|
|
int top = blob.Rectangle.Top;
|
|
int num3 = top + height2 - 1;
|
|
int iD = blob.ID;
|
|
blob.Image = UnmanagedImage.Create(width3, height3, image.PixelFormat);
|
|
blob.OriginalSize = extractInOriginalSize;
|
|
byte* ptr = (byte*)image.ImageData.ToPointer() + (nint)top * (nint)stride + (nint)left * (nint)num;
|
|
byte* ptr2 = (byte*)blob.Image.ImageData.ToPointer();
|
|
int num4 = top * width + left;
|
|
if (extractInOriginalSize)
|
|
{
|
|
ptr2 += top * blob.Image.Stride + left * num;
|
|
}
|
|
int num5 = stride - width2 * num;
|
|
int num6 = blob.Image.Stride - width2 * num;
|
|
int num7 = width - width2;
|
|
for (int i = top; i <= num3; i++)
|
|
{
|
|
int num8 = left;
|
|
while (num8 <= num2)
|
|
{
|
|
if (objectLabels[num4] == iD)
|
|
{
|
|
*ptr2 = *ptr;
|
|
if (num > 1)
|
|
{
|
|
ptr2[1] = ptr[1];
|
|
ptr2[2] = ptr[2];
|
|
if (num > 3)
|
|
{
|
|
ptr2[3] = ptr[3];
|
|
}
|
|
}
|
|
}
|
|
num8++;
|
|
num4++;
|
|
ptr2 += num;
|
|
ptr += num;
|
|
}
|
|
ptr += num5;
|
|
ptr2 += num6;
|
|
num4 += num7;
|
|
}
|
|
}
|
|
|
|
public void GetBlobsLeftAndRightEdges(Blob blob, out List<IntPoint> leftEdge, out List<IntPoint> rightEdge)
|
|
{
|
|
if (objectLabels == null)
|
|
{
|
|
throw new ApplicationException("Image should be processed before to collect objects map.");
|
|
}
|
|
leftEdge = new List<IntPoint>();
|
|
rightEdge = new List<IntPoint>();
|
|
int left = blob.Rectangle.Left;
|
|
int num = left + blob.Rectangle.Width - 1;
|
|
int top = blob.Rectangle.Top;
|
|
int num2 = top + blob.Rectangle.Height - 1;
|
|
int iD = blob.ID;
|
|
for (int i = top; i <= num2; i++)
|
|
{
|
|
int num3 = i * imageWidth + left;
|
|
int num4 = left;
|
|
while (num4 <= num)
|
|
{
|
|
if (objectLabels[num3] == iD)
|
|
{
|
|
leftEdge.Add(new IntPoint(num4, i));
|
|
break;
|
|
}
|
|
num4++;
|
|
num3++;
|
|
}
|
|
num3 = i * imageWidth + num;
|
|
int num5 = num;
|
|
while (num5 >= left)
|
|
{
|
|
if (objectLabels[num3] == iD)
|
|
{
|
|
rightEdge.Add(new IntPoint(num5, i));
|
|
break;
|
|
}
|
|
num5--;
|
|
num3--;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void GetBlobsTopAndBottomEdges(Blob blob, out List<IntPoint> topEdge, out List<IntPoint> bottomEdge)
|
|
{
|
|
if (objectLabels == null)
|
|
{
|
|
throw new ApplicationException("Image should be processed before to collect objects map.");
|
|
}
|
|
topEdge = new List<IntPoint>();
|
|
bottomEdge = new List<IntPoint>();
|
|
int left = blob.Rectangle.Left;
|
|
int num = left + blob.Rectangle.Width - 1;
|
|
int top = blob.Rectangle.Top;
|
|
int num2 = top + blob.Rectangle.Height - 1;
|
|
int iD = blob.ID;
|
|
for (int i = left; i <= num; i++)
|
|
{
|
|
int num3 = top * imageWidth + i;
|
|
int num4 = top;
|
|
while (num4 <= num2)
|
|
{
|
|
if (objectLabels[num3] == iD)
|
|
{
|
|
topEdge.Add(new IntPoint(i, num4));
|
|
break;
|
|
}
|
|
num4++;
|
|
num3 += imageWidth;
|
|
}
|
|
num3 = num2 * imageWidth + i;
|
|
int num5 = num2;
|
|
while (num5 >= top)
|
|
{
|
|
if (objectLabels[num3] == iD)
|
|
{
|
|
bottomEdge.Add(new IntPoint(i, num5));
|
|
break;
|
|
}
|
|
num5--;
|
|
num3 -= imageWidth;
|
|
}
|
|
}
|
|
}
|
|
|
|
public List<IntPoint> GetBlobsEdgePoints(Blob blob)
|
|
{
|
|
if (objectLabels == null)
|
|
{
|
|
throw new ApplicationException("Image should be processed before to collect objects map.");
|
|
}
|
|
List<IntPoint> list = new List<IntPoint>();
|
|
int left = blob.Rectangle.Left;
|
|
int num = left + blob.Rectangle.Width - 1;
|
|
int top = blob.Rectangle.Top;
|
|
int num2 = top + blob.Rectangle.Height - 1;
|
|
int iD = blob.ID;
|
|
int[] array = new int[blob.Rectangle.Height];
|
|
int[] array2 = new int[blob.Rectangle.Height];
|
|
for (int i = top; i <= num2; i++)
|
|
{
|
|
int num3 = i * imageWidth + left;
|
|
int num4 = left;
|
|
while (num4 <= num)
|
|
{
|
|
if (objectLabels[num3] == iD)
|
|
{
|
|
list.Add(new IntPoint(num4, i));
|
|
array[i - top] = num4;
|
|
break;
|
|
}
|
|
num4++;
|
|
num3++;
|
|
}
|
|
num3 = i * imageWidth + num;
|
|
int num5 = num;
|
|
while (num5 >= left)
|
|
{
|
|
if (objectLabels[num3] == iD)
|
|
{
|
|
if (array[i - top] != num5)
|
|
{
|
|
list.Add(new IntPoint(num5, i));
|
|
}
|
|
array2[i - top] = num5;
|
|
break;
|
|
}
|
|
num5--;
|
|
num3--;
|
|
}
|
|
}
|
|
for (int j = left; j <= num; j++)
|
|
{
|
|
int num6 = top * imageWidth + j;
|
|
int num7 = top;
|
|
int num8 = 0;
|
|
while (num7 <= num2)
|
|
{
|
|
if (objectLabels[num6] == iD)
|
|
{
|
|
if (array[num8] != j && array2[num8] != j)
|
|
{
|
|
list.Add(new IntPoint(j, num7));
|
|
}
|
|
break;
|
|
}
|
|
num7++;
|
|
num8++;
|
|
num6 += imageWidth;
|
|
}
|
|
num6 = num2 * imageWidth + j;
|
|
int num9 = num2;
|
|
int num10 = num2 - top;
|
|
while (num9 >= top)
|
|
{
|
|
if (objectLabels[num6] == iD)
|
|
{
|
|
if (array[num10] != j && array2[num10] != j)
|
|
{
|
|
list.Add(new IntPoint(j, num9));
|
|
}
|
|
break;
|
|
}
|
|
num9--;
|
|
num10--;
|
|
num6 -= imageWidth;
|
|
}
|
|
}
|
|
return list;
|
|
}
|
|
|
|
protected abstract void BuildObjectsMap(UnmanagedImage image);
|
|
|
|
private unsafe void CollectObjectsInfo(UnmanagedImage image)
|
|
{
|
|
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0108: Invalid comparison between Unknown and I4
|
|
//IL_0263: Unknown result type (might be due to invalid IL or missing references)
|
|
int num = 0;
|
|
int[] array = new int[objectsCount + 1];
|
|
int[] array2 = new int[objectsCount + 1];
|
|
int[] array3 = new int[objectsCount + 1];
|
|
int[] array4 = new int[objectsCount + 1];
|
|
int[] array5 = new int[objectsCount + 1];
|
|
long[] array6 = new long[objectsCount + 1];
|
|
long[] array7 = new long[objectsCount + 1];
|
|
long[] array8 = new long[objectsCount + 1];
|
|
long[] array9 = new long[objectsCount + 1];
|
|
long[] array10 = new long[objectsCount + 1];
|
|
long[] array11 = new long[objectsCount + 1];
|
|
long[] array12 = new long[objectsCount + 1];
|
|
long[] array13 = new long[objectsCount + 1];
|
|
for (int i = 1; i <= objectsCount; i++)
|
|
{
|
|
array[i] = imageWidth;
|
|
array2[i] = imageHeight;
|
|
}
|
|
byte* ptr = (byte*)image.ImageData.ToPointer();
|
|
if ((int)image.PixelFormat == 198659)
|
|
{
|
|
int num2 = image.Stride - imageWidth;
|
|
for (int j = 0; j < imageHeight; j++)
|
|
{
|
|
int num3 = 0;
|
|
while (num3 < imageWidth)
|
|
{
|
|
int num4 = objectLabels[num];
|
|
if (num4 != 0)
|
|
{
|
|
if (num3 < array[num4])
|
|
{
|
|
array[num4] = num3;
|
|
}
|
|
if (num3 > array3[num4])
|
|
{
|
|
array3[num4] = num3;
|
|
}
|
|
if (j < array2[num4])
|
|
{
|
|
array2[num4] = j;
|
|
}
|
|
if (j > array4[num4])
|
|
{
|
|
array4[num4] = j;
|
|
}
|
|
array5[num4]++;
|
|
array6[num4] += num3;
|
|
array7[num4] += j;
|
|
byte b = *ptr;
|
|
array9[num4] += b;
|
|
array12[num4] += b * b;
|
|
}
|
|
num3++;
|
|
num++;
|
|
ptr++;
|
|
}
|
|
ptr += num2;
|
|
}
|
|
for (int k = 1; k <= objectsCount; k++)
|
|
{
|
|
array8[k] = (array10[k] = array9[k]);
|
|
array11[k] = (array13[k] = array12[k]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int num5 = Image.GetPixelFormatSize(image.PixelFormat) / 8;
|
|
int num6 = image.Stride - imageWidth * num5;
|
|
for (int l = 0; l < imageHeight; l++)
|
|
{
|
|
int num7 = 0;
|
|
while (num7 < imageWidth)
|
|
{
|
|
int num4 = objectLabels[num];
|
|
if (num4 != 0)
|
|
{
|
|
if (num7 < array[num4])
|
|
{
|
|
array[num4] = num7;
|
|
}
|
|
if (num7 > array3[num4])
|
|
{
|
|
array3[num4] = num7;
|
|
}
|
|
if (l < array2[num4])
|
|
{
|
|
array2[num4] = l;
|
|
}
|
|
if (l > array4[num4])
|
|
{
|
|
array4[num4] = l;
|
|
}
|
|
array5[num4]++;
|
|
array6[num4] += num7;
|
|
array7[num4] += l;
|
|
byte b2 = ptr[2];
|
|
byte b3 = ptr[1];
|
|
byte b4 = *ptr;
|
|
array8[num4] += b2;
|
|
array9[num4] += b3;
|
|
array10[num4] += b4;
|
|
array11[num4] += b2 * b2;
|
|
array12[num4] += b3 * b3;
|
|
array13[num4] += b4 * b4;
|
|
}
|
|
num7++;
|
|
num++;
|
|
ptr += num5;
|
|
}
|
|
ptr += num6;
|
|
}
|
|
}
|
|
blobs.Clear();
|
|
for (int m = 1; m <= objectsCount; m++)
|
|
{
|
|
int num8 = array5[m];
|
|
Blob blob = new Blob(m, new Rectangle(array[m], array2[m], array3[m] - array[m] + 1, array4[m] - array2[m] + 1));
|
|
blob.Area = num8;
|
|
blob.Fullness = (double)num8 / (double)((array3[m] - array[m] + 1) * (array4[m] - array2[m] + 1));
|
|
blob.CenterOfGravity = new Point((float)array6[m] / (float)num8, (float)array7[m] / (float)num8);
|
|
blob.ColorMean = Color.FromArgb((byte)(array8[m] / num8), (byte)(array9[m] / num8), (byte)(array10[m] / num8));
|
|
blob.ColorStdDev = Color.FromArgb((byte)System.Math.Sqrt(array11[m] / num8 - blob.ColorMean.R * blob.ColorMean.R), (byte)System.Math.Sqrt(array12[m] / num8 - blob.ColorMean.G * blob.ColorMean.G), (byte)System.Math.Sqrt(array13[m] / num8 - blob.ColorMean.B * blob.ColorMean.B));
|
|
blobs.Add(blob);
|
|
}
|
|
}
|
|
}
|