init commit

This commit is contained in:
2025-10-09 09:57:24 +09:00
commit 4d551bd74f
6636 changed files with 1218703 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyName>AForge.Imaging</AssemblyName>
<GenerateAssemblyInfo>False</GenerateAssemblyInfo>
<TargetFramework>net20</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<LangVersion>12.0</LangVersion>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup />
<ItemGroup />
<ItemGroup>
<Reference Include="AForge">
<HintPath>../../../desktop/AForge.dll</HintPath>
</Reference>
<Reference Include="AForge.Math">
<HintPath>../../../desktop/AForge.Math.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,143 @@
using System.ComponentModel;
using System.Drawing;
namespace AForge.Imaging;
public class Blob
{
private UnmanagedImage image;
private bool originalSize;
private Rectangle rect;
private int id;
private int area;
private Point cog;
private double fullness;
private Color colorMean = Color.Black;
private Color colorStdDev = Color.Black;
[Browsable(false)]
public UnmanagedImage Image
{
get
{
return image;
}
internal set
{
image = value;
}
}
[Browsable(false)]
public bool OriginalSize
{
get
{
return originalSize;
}
internal set
{
originalSize = value;
}
}
public Rectangle Rectangle => rect;
[Browsable(false)]
public int ID
{
get
{
return id;
}
internal set
{
id = value;
}
}
public int Area
{
get
{
return area;
}
internal set
{
area = value;
}
}
public double Fullness
{
get
{
return fullness;
}
internal set
{
fullness = value;
}
}
public Point CenterOfGravity
{
get
{
return cog;
}
internal set
{
cog = value;
}
}
public Color ColorMean
{
get
{
return colorMean;
}
internal set
{
colorMean = value;
}
}
public Color ColorStdDev
{
get
{
return colorStdDev;
}
internal set
{
colorStdDev = value;
}
}
public Blob(int id, Rectangle rect)
{
this.id = id;
this.rect = rect;
}
public Blob(Blob source)
{
id = source.id;
rect = source.rect;
cog = source.cog;
area = source.area;
fullness = source.fullness;
colorMean = source.colorMean;
colorStdDev = source.colorStdDev;
}
}

View File

@@ -0,0 +1,379 @@
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging;
public class BlobCounter : BlobCounterBase
{
private byte backgroundThresholdR;
private byte backgroundThresholdG;
private byte backgroundThresholdB;
public Color BackgroundThreshold
{
get
{
return Color.FromArgb(backgroundThresholdR, backgroundThresholdG, backgroundThresholdB);
}
set
{
backgroundThresholdR = value.R;
backgroundThresholdG = value.G;
backgroundThresholdB = value.B;
}
}
public BlobCounter()
{
}
public BlobCounter(Bitmap image)
: base(image)
{
}
public BlobCounter(BitmapData imageData)
: base(imageData)
{
}
public BlobCounter(UnmanagedImage image)
: base(image)
{
}
protected unsafe override void BuildObjectsMap(UnmanagedImage image)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Invalid comparison between Unknown and I4
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Invalid comparison between Unknown and I4
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Invalid comparison between Unknown and I4
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Invalid comparison between Unknown and I4
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Invalid comparison between Unknown and I4
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Invalid comparison between Unknown and I4
//IL_046c: Unknown result type (might be due to invalid IL or missing references)
int stride = image.Stride;
if ((int)image.PixelFormat != 198659 && (int)image.PixelFormat != 137224 && (int)image.PixelFormat != 139273 && (int)image.PixelFormat != 2498570 && (int)image.PixelFormat != 925707)
{
throw new UnsupportedImageFormatException("Unsupported pixel format of the source image.");
}
if (imageWidth == 1)
{
throw new InvalidImagePropertiesException("BlobCounter cannot process images that are one pixel wide. Rotate the image or use RecursiveBlobCounter.");
}
int num = imageWidth - 1;
objectLabels = new int[imageWidth * imageHeight];
int num2 = 0;
int num3 = (imageWidth / 2 + 1) * (imageHeight / 2 + 1) + 1;
int[] array = new int[num3];
for (int i = 0; i < num3; i++)
{
array[i] = i;
}
byte* ptr = (byte*)image.ImageData.ToPointer();
int num4 = 0;
if ((int)image.PixelFormat == 198659)
{
int num5 = stride - imageWidth;
if (*ptr > backgroundThresholdG)
{
num2 = (objectLabels[num4] = num2 + 1);
}
ptr++;
num4++;
int num6 = 1;
while (num6 < imageWidth)
{
if (*ptr > backgroundThresholdG)
{
if (ptr[-1] > backgroundThresholdG)
{
objectLabels[num4] = objectLabels[num4 - 1];
}
else
{
num2 = (objectLabels[num4] = num2 + 1);
}
}
num6++;
ptr++;
num4++;
}
ptr += num5;
for (int j = 1; j < imageHeight; j++)
{
if (*ptr > backgroundThresholdG)
{
if (ptr[-stride] > backgroundThresholdG)
{
objectLabels[num4] = objectLabels[num4 - imageWidth];
}
else if (ptr[1 - stride] <= backgroundThresholdG)
{
num2 = (objectLabels[num4] = num2 + 1);
}
else
{
objectLabels[num4] = objectLabels[num4 + 1 - imageWidth];
}
}
ptr++;
num4++;
int num7 = 1;
while (num7 < num)
{
if (*ptr > backgroundThresholdG)
{
if (ptr[-1] > backgroundThresholdG)
{
objectLabels[num4] = objectLabels[num4 - 1];
}
else if (ptr[-1 - stride] > backgroundThresholdG)
{
objectLabels[num4] = objectLabels[num4 - 1 - imageWidth];
}
else if (ptr[-stride] > backgroundThresholdG)
{
objectLabels[num4] = objectLabels[num4 - imageWidth];
}
if (ptr[1 - stride] > backgroundThresholdG)
{
if (objectLabels[num4] == 0)
{
objectLabels[num4] = objectLabels[num4 + 1 - imageWidth];
}
else
{
int num8 = objectLabels[num4];
int num9 = objectLabels[num4 + 1 - imageWidth];
if (num8 != num9 && array[num8] != array[num9])
{
if (array[num8] == num8)
{
array[num8] = array[num9];
}
else if (array[num9] == num9)
{
array[num9] = array[num8];
}
else
{
array[array[num8]] = array[num9];
array[num8] = array[num9];
}
for (int k = 1; k <= num2; k++)
{
if (array[k] != k)
{
int num10;
for (num10 = array[k]; num10 != array[num10]; num10 = array[num10])
{
}
array[k] = num10;
}
}
}
}
}
if (objectLabels[num4] == 0)
{
num2 = (objectLabels[num4] = num2 + 1);
}
}
num7++;
ptr++;
num4++;
}
if (*ptr > backgroundThresholdG)
{
if (ptr[-1] > backgroundThresholdG)
{
objectLabels[num4] = objectLabels[num4 - 1];
}
else if (ptr[-1 - stride] > backgroundThresholdG)
{
objectLabels[num4] = objectLabels[num4 - 1 - imageWidth];
}
else if (ptr[-stride] > backgroundThresholdG)
{
objectLabels[num4] = objectLabels[num4 - imageWidth];
}
else
{
num2 = (objectLabels[num4] = num2 + 1);
}
}
ptr++;
num4++;
ptr += num5;
}
}
else
{
int num11 = Image.GetPixelFormatSize(image.PixelFormat) / 8;
int num12 = stride - imageWidth * num11;
int num13 = stride - num11;
int num14 = stride + num11;
if ((ptr[2] | ptr[1] | *ptr) != 0)
{
num2 = (objectLabels[num4] = num2 + 1);
}
ptr += num11;
num4++;
int num15 = 1;
while (num15 < imageWidth)
{
if (ptr[2] > backgroundThresholdR || ptr[1] > backgroundThresholdG || *ptr > backgroundThresholdB)
{
if (ptr[2 - num11] > backgroundThresholdR || ptr[1 - num11] > backgroundThresholdG || ptr[-num11] > backgroundThresholdB)
{
objectLabels[num4] = objectLabels[num4 - 1];
}
else
{
num2 = (objectLabels[num4] = num2 + 1);
}
}
num15++;
ptr += num11;
num4++;
}
ptr += num12;
for (int l = 1; l < imageHeight; l++)
{
if (ptr[2] > backgroundThresholdR || ptr[1] > backgroundThresholdG || *ptr > backgroundThresholdB)
{
if (ptr[2 - stride] > backgroundThresholdR || ptr[1 - stride] > backgroundThresholdG || ptr[-stride] > backgroundThresholdB)
{
objectLabels[num4] = objectLabels[num4 - imageWidth];
}
else if (ptr[2 - num13] <= backgroundThresholdR && ptr[1 - num13] <= backgroundThresholdG && ptr[-num13] <= backgroundThresholdB)
{
num2 = (objectLabels[num4] = num2 + 1);
}
else
{
objectLabels[num4] = objectLabels[num4 + 1 - imageWidth];
}
}
ptr += num11;
num4++;
int num16 = 1;
while (num16 < imageWidth - 1)
{
if (ptr[2] > backgroundThresholdR || ptr[1] > backgroundThresholdG || *ptr > backgroundThresholdB)
{
if (ptr[2 - num11] > backgroundThresholdR || ptr[1 - num11] > backgroundThresholdG || ptr[-num11] > backgroundThresholdB)
{
objectLabels[num4] = objectLabels[num4 - 1];
}
else if (ptr[2 - num14] > backgroundThresholdR || ptr[1 - num14] > backgroundThresholdG || ptr[-num14] > backgroundThresholdB)
{
objectLabels[num4] = objectLabels[num4 - 1 - imageWidth];
}
else if (ptr[2 - stride] > backgroundThresholdR || ptr[1 - stride] > backgroundThresholdG || ptr[-stride] > backgroundThresholdB)
{
objectLabels[num4] = objectLabels[num4 - imageWidth];
}
if (ptr[2 - num13] > backgroundThresholdR || ptr[1 - num13] > backgroundThresholdG || ptr[-num13] > backgroundThresholdB)
{
if (objectLabels[num4] == 0)
{
objectLabels[num4] = objectLabels[num4 + 1 - imageWidth];
}
else
{
int num17 = objectLabels[num4];
int num18 = objectLabels[num4 + 1 - imageWidth];
if (num17 != num18 && array[num17] != array[num18])
{
if (array[num17] == num17)
{
array[num17] = array[num18];
}
else if (array[num18] == num18)
{
array[num18] = array[num17];
}
else
{
array[array[num17]] = array[num18];
array[num17] = array[num18];
}
for (int m = 1; m <= num2; m++)
{
if (array[m] != m)
{
int num19;
for (num19 = array[m]; num19 != array[num19]; num19 = array[num19])
{
}
array[m] = num19;
}
}
}
}
}
if (objectLabels[num4] == 0)
{
num2 = (objectLabels[num4] = num2 + 1);
}
}
num16++;
ptr += num11;
num4++;
}
if (ptr[2] > backgroundThresholdR || ptr[1] > backgroundThresholdG || *ptr > backgroundThresholdB)
{
if (ptr[2 - num11] > backgroundThresholdR || ptr[1 - num11] > backgroundThresholdG || ptr[-num11] > backgroundThresholdB)
{
objectLabels[num4] = objectLabels[num4 - 1];
}
else if (ptr[2 - num14] > backgroundThresholdR || ptr[1 - num14] > backgroundThresholdG || ptr[-num14] > backgroundThresholdB)
{
objectLabels[num4] = objectLabels[num4 - 1 - imageWidth];
}
else if (ptr[2 - stride] > backgroundThresholdR || ptr[1 - stride] > backgroundThresholdG || ptr[-stride] > backgroundThresholdB)
{
objectLabels[num4] = objectLabels[num4 - imageWidth];
}
else
{
num2 = (objectLabels[num4] = num2 + 1);
}
}
ptr += num11;
num4++;
ptr += num12;
}
}
int[] array2 = new int[array.Length];
objectsCount = 0;
for (int n = 1; n <= num2; n++)
{
if (array[n] == n)
{
array2[n] = ++objectsCount;
}
}
for (int num20 = 1; num20 <= num2; num20++)
{
if (array[num20] != num20)
{
array2[num20] = array2[array[num20]];
}
}
int num21 = 0;
for (int num22 = objectLabels.Length; num21 < num22; num21++)
{
objectLabels[num21] = array2[objectLabels[num21]];
}
}
}

View File

@@ -0,0 +1,798 @@
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);
}
}
}

View File

@@ -0,0 +1,23 @@
namespace AForge.Imaging;
public class BlockMatch
{
private IntPoint sourcePoint;
private IntPoint matchPoint;
private float similarity;
public IntPoint SourcePoint => sourcePoint;
public IntPoint MatchPoint => matchPoint;
public float Similarity => similarity;
public BlockMatch(IntPoint sourcePoint, IntPoint matchPoint, float similarity)
{
this.sourcePoint = sourcePoint;
this.matchPoint = matchPoint;
this.similarity = similarity;
}
}

View File

@@ -0,0 +1,13 @@
namespace AForge.Imaging.ColorReduction;
public sealed class BurkesColorDithering : ColorErrorDiffusionToAdjacentNeighbors
{
public BurkesColorDithering()
: base(new int[2][]
{
new int[2] { 8, 4 },
new int[5] { 2, 4, 8, 4, 2 }
})
{
}
}

View File

@@ -0,0 +1,94 @@
namespace AForge.Imaging.ColorReduction;
public class ColorErrorDiffusionToAdjacentNeighbors : ErrorDiffusionColorDithering
{
private int[][] coefficients;
private int coefficientsSum;
public int[][] Coefficients
{
get
{
return coefficients;
}
set
{
coefficients = value;
CalculateCoefficientsSum();
}
}
public ColorErrorDiffusionToAdjacentNeighbors(int[][] coefficients)
{
this.coefficients = coefficients;
CalculateCoefficientsSum();
}
protected unsafe override void Diffuse(int rError, int gError, int bError, byte* ptr)
{
int[] array = coefficients[0];
int num = 1;
int num2 = pixelSize;
int num3 = 0;
int num4 = array.Length;
while (num3 < num4 && x + num < width)
{
int num5 = ptr[num2 + 2] + rError * array[num3] / coefficientsSum;
num5 = ((num5 >= 0) ? ((num5 > 255) ? 255 : num5) : 0);
ptr[num2 + 2] = (byte)num5;
int num6 = ptr[num2 + 1] + gError * array[num3] / coefficientsSum;
num6 = ((num6 >= 0) ? ((num6 > 255) ? 255 : num6) : 0);
ptr[num2 + 1] = (byte)num6;
int num7 = ptr[num2] + bError * array[num3] / coefficientsSum;
num7 = ((num7 >= 0) ? ((num7 > 255) ? 255 : num7) : 0);
ptr[num2] = (byte)num7;
num++;
num3++;
num2 += pixelSize;
}
int i = 1;
for (int num8 = coefficients.Length; i < num8 && y + i < height; i++)
{
ptr += stride;
array = coefficients[i];
int num9 = 0;
int num10 = array.Length;
int num11 = -(num10 >> 1);
int num12 = -(num10 >> 1) * pixelSize;
while (num9 < num10 && x + num11 < width)
{
if (x + num11 >= 0)
{
int num5 = ptr[num12 + 2] + rError * array[num9] / coefficientsSum;
num5 = ((num5 >= 0) ? ((num5 > 255) ? 255 : num5) : 0);
ptr[num12 + 2] = (byte)num5;
int num6 = ptr[num12 + 1] + gError * array[num9] / coefficientsSum;
num6 = ((num6 >= 0) ? ((num6 > 255) ? 255 : num6) : 0);
ptr[num12 + 1] = (byte)num6;
int num7 = ptr[num12] + bError * array[num9] / coefficientsSum;
num7 = ((num7 >= 0) ? ((num7 > 255) ? 255 : num7) : 0);
ptr[num12] = (byte)num7;
}
num11++;
num9++;
num12 += pixelSize;
}
}
}
private void CalculateCoefficientsSum()
{
coefficientsSum = 0;
int i = 0;
for (int num = coefficients.Length; i < num; i++)
{
int[] array = coefficients[i];
int j = 0;
for (int num2 = array.Length; j < num2; j++)
{
coefficientsSum += array[j];
}
}
}
}

View File

@@ -0,0 +1,247 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.ColorReduction;
public class ColorImageQuantizer
{
private IColorQuantizer quantizer;
private bool useCaching;
[NonSerialized]
private Color[] paletteToUse;
[NonSerialized]
private Dictionary<Color, int> cache = new Dictionary<Color, int>();
public IColorQuantizer Quantizer
{
get
{
return quantizer;
}
set
{
quantizer = value;
}
}
public bool UseCaching
{
get
{
return useCaching;
}
set
{
useCaching = value;
}
}
public ColorImageQuantizer(IColorQuantizer quantizer)
{
this.quantizer = quantizer;
}
public Color[] CalculatePalette(Bitmap image, int paletteSize)
{
//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
{
return CalculatePalette(new UnmanagedImage(val), paletteSize);
}
finally
{
image.UnlockBits(val);
}
}
public unsafe Color[] CalculatePalette(UnmanagedImage image, int paletteSize)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Invalid comparison between Unknown and I4
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Invalid comparison between Unknown and I4
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Invalid comparison between Unknown and I4
if ((int)image.PixelFormat != 137224 && (int)image.PixelFormat != 139273 && (int)image.PixelFormat != 2498570 && (int)image.PixelFormat != 925707)
{
throw new UnsupportedImageFormatException("Unsupported format of the source image.");
}
quantizer.Clear();
int width = image.Width;
int height = image.Height;
int num = Image.GetPixelFormatSize(image.PixelFormat) / 8;
byte* ptr = (byte*)image.ImageData.ToPointer();
int num2 = image.Stride - width * num;
for (int i = 0; i < height; i++)
{
int num3 = 0;
while (num3 < width)
{
quantizer.AddColor(Color.FromArgb(ptr[2], ptr[1], *ptr));
num3++;
ptr += num;
}
ptr += num2;
}
return quantizer.GetPalette(paletteSize);
}
public Bitmap ReduceColors(Bitmap image, int paletteSize)
{
//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
{
Bitmap val2 = ReduceColors(new UnmanagedImage(val), paletteSize);
if (((Image)image).HorizontalResolution > 0f && ((Image)image).VerticalResolution > 0f)
{
val2.SetResolution(((Image)image).HorizontalResolution, ((Image)image).VerticalResolution);
}
return val2;
}
finally
{
image.UnlockBits(val);
}
}
public Bitmap ReduceColors(UnmanagedImage image, int paletteSize)
{
if (paletteSize < 2 || paletteSize > 256)
{
throw new ArgumentException("Invalid size of the target color palette.");
}
return ReduceColors(image, CalculatePalette(image, paletteSize));
}
public Bitmap ReduceColors(Bitmap image, Color[] palette)
{
//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
{
Bitmap val2 = ReduceColors(new UnmanagedImage(val), palette);
if (((Image)image).HorizontalResolution > 0f && ((Image)image).VerticalResolution > 0f)
{
val2.SetResolution(((Image)image).HorizontalResolution, ((Image)image).VerticalResolution);
}
return val2;
}
finally
{
image.UnlockBits(val);
}
}
public unsafe Bitmap ReduceColors(UnmanagedImage image, Color[] palette)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Invalid comparison between Unknown and I4
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Invalid comparison between Unknown and I4
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Invalid comparison between Unknown and I4
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Expected O, but got Unknown
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
if ((int)image.PixelFormat != 137224 && (int)image.PixelFormat != 139273 && (int)image.PixelFormat != 2498570 && (int)image.PixelFormat != 925707)
{
throw new UnsupportedImageFormatException("Unsupported format of the source image.");
}
if (palette.Length < 2 || palette.Length > 256)
{
throw new ArgumentException("Invalid size of the target color palette.");
}
paletteToUse = palette;
cache.Clear();
int width = image.Width;
int height = image.Height;
int stride = image.Stride;
int num = Image.GetPixelFormatSize(image.PixelFormat) / 8;
int num2 = stride - width * num;
Bitmap val = new Bitmap(width, height, (PixelFormat)((palette.Length > 16) ? 198659 : 197634));
ColorPalette palette2 = ((Image)val).Palette;
int i = 0;
for (int num3 = palette.Length; i < num3; i++)
{
ref Color reference = ref palette2.Entries[i];
reference = palette[i];
}
((Image)val).Palette = palette2;
BitmapData val2 = val.LockBits(new Rectangle(0, 0, width, height), (ImageLockMode)3, ((Image)val).PixelFormat);
byte* ptr = (byte*)image.ImageData.ToPointer();
byte* ptr2 = (byte*)val2.Scan0.ToPointer();
bool flag = palette.Length > 16;
for (int j = 0; j < height; j++)
{
byte* ptr3 = ptr2 + (nint)j * (nint)val2.Stride;
int num4 = 0;
while (num4 < width)
{
byte b = (byte)GetClosestColor(ptr[2], ptr[1], *ptr);
if (flag)
{
*ptr3 = b;
ptr3++;
}
else if (num4 % 2 == 0)
{
byte* intPtr = ptr3;
*intPtr |= (byte)(b << 4);
}
else
{
byte* intPtr2 = ptr3;
*intPtr2 |= b;
ptr3++;
}
num4++;
ptr += num;
}
ptr += num2;
}
val.UnlockBits(val2);
return val;
}
private int GetClosestColor(int red, int green, int blue)
{
Color key = Color.FromArgb(red, green, blue);
if (useCaching && cache.ContainsKey(key))
{
return cache[key];
}
int num = 0;
int num2 = int.MaxValue;
int i = 0;
for (int num3 = paletteToUse.Length; i < num3; i++)
{
int num4 = red - paletteToUse[i].R;
int num5 = green - paletteToUse[i].G;
int num6 = blue - paletteToUse[i].B;
int num7 = num4 * num4 + num5 * num5 + num6 * num6;
if (num7 < num2)
{
num2 = num7;
num = (byte)i;
}
}
if (useCaching)
{
cache.Add(key, num);
}
return num;
}
}

View File

@@ -0,0 +1,204 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.ColorReduction;
public abstract class ErrorDiffusionColorDithering
{
private bool useCaching;
protected int x;
protected int y;
protected int width;
protected int height;
protected int stride;
protected int pixelSize;
private Color[] colorTable = new Color[16]
{
Color.Black,
Color.DarkBlue,
Color.DarkGreen,
Color.DarkCyan,
Color.DarkRed,
Color.DarkMagenta,
Color.DarkKhaki,
Color.LightGray,
Color.Gray,
Color.Blue,
Color.Green,
Color.Cyan,
Color.Red,
Color.Magenta,
Color.Yellow,
Color.White
};
[NonSerialized]
private Dictionary<Color, byte> cache = new Dictionary<Color, byte>();
public Color[] ColorTable
{
get
{
return colorTable;
}
set
{
if (colorTable.Length < 2 || colorTable.Length > 256)
{
throw new ArgumentException("Color table length must be in the [2, 256] range.");
}
colorTable = value;
}
}
public bool UseCaching
{
get
{
return useCaching;
}
set
{
useCaching = value;
}
}
protected unsafe abstract void Diffuse(int rError, int gError, int bError, byte* ptr);
public Bitmap Apply(Bitmap sourceImage)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
BitmapData val = sourceImage.LockBits(new Rectangle(0, 0, ((Image)sourceImage).Width, ((Image)sourceImage).Height), (ImageLockMode)1, ((Image)sourceImage).PixelFormat);
Bitmap val2 = null;
try
{
val2 = Apply(new UnmanagedImage(val));
if (((Image)sourceImage).HorizontalResolution > 0f && ((Image)sourceImage).VerticalResolution > 0f)
{
val2.SetResolution(((Image)sourceImage).HorizontalResolution, ((Image)sourceImage).VerticalResolution);
}
}
finally
{
sourceImage.UnlockBits(val);
}
return val2;
}
public unsafe Bitmap Apply(UnmanagedImage sourceImage)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Invalid comparison between Unknown and I4
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Invalid comparison between Unknown and I4
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Expected O, but got Unknown
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Invalid comparison between Unknown and I4
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
if ((int)sourceImage.PixelFormat != 137224 && (int)sourceImage.PixelFormat != 139273 && (int)sourceImage.PixelFormat != 2498570 && (int)sourceImage.PixelFormat != 925707)
{
throw new UnsupportedImageFormatException("Unsupported pixel format of the source image.");
}
cache.Clear();
UnmanagedImage unmanagedImage = sourceImage.Clone();
width = sourceImage.Width;
height = sourceImage.Height;
stride = sourceImage.Stride;
pixelSize = Image.GetPixelFormatSize(sourceImage.PixelFormat) / 8;
int num = stride - width * pixelSize;
Bitmap val = new Bitmap(width, height, (PixelFormat)((colorTable.Length > 16) ? 198659 : 197634));
ColorPalette palette = ((Image)val).Palette;
int i = 0;
for (int num2 = colorTable.Length; i < num2; i++)
{
ref Color reference = ref palette.Entries[i];
reference = colorTable[i];
}
((Image)val).Palette = palette;
BitmapData val2 = val.LockBits(new Rectangle(0, 0, width, height), (ImageLockMode)3, ((Image)val).PixelFormat);
byte* ptr = (byte*)unmanagedImage.ImageData.ToPointer();
byte* ptr2 = (byte*)val2.Scan0.ToPointer();
bool flag = colorTable.Length > 16;
for (y = 0; y < height; y++)
{
byte* ptr3 = ptr2 + (nint)y * (nint)val2.Stride;
x = 0;
while (x < width)
{
int num3 = ptr[2];
int num4 = ptr[1];
int num5 = *ptr;
byte colorIndex;
Color closestColor = GetClosestColor(num3, num4, num5, out colorIndex);
Diffuse(num3 - closestColor.R, num4 - closestColor.G, num5 - closestColor.B, ptr);
if (flag)
{
*ptr3 = colorIndex;
ptr3++;
}
else if (x % 2 == 0)
{
byte* intPtr = ptr3;
*intPtr |= (byte)(colorIndex << 4);
}
else
{
byte* intPtr2 = ptr3;
*intPtr2 |= colorIndex;
ptr3++;
}
x++;
ptr += pixelSize;
}
ptr += num;
}
val.UnlockBits(val2);
unmanagedImage.Dispose();
return val;
}
private Color GetClosestColor(int red, int green, int blue, out byte colorIndex)
{
Color key = Color.FromArgb(red, green, blue);
if (useCaching && cache.ContainsKey(key))
{
colorIndex = cache[key];
}
else
{
colorIndex = 0;
int num = int.MaxValue;
int i = 0;
for (int num2 = colorTable.Length; i < num2; i++)
{
int num3 = red - colorTable[i].R;
int num4 = green - colorTable[i].G;
int num5 = blue - colorTable[i].B;
int num6 = num3 * num3 + num4 * num4 + num5 * num5;
if (num6 < num)
{
num = num6;
colorIndex = (byte)i;
}
}
if (useCaching)
{
cache.Add(key, colorIndex);
}
}
return colorTable[colorIndex];
}
}

View File

@@ -0,0 +1,13 @@
namespace AForge.Imaging.ColorReduction;
public sealed class FloydSteinbergColorDithering : ColorErrorDiffusionToAdjacentNeighbors
{
public FloydSteinbergColorDithering()
: base(new int[2][]
{
new int[1] { 7 },
new int[3] { 3, 5, 1 }
})
{
}
}

View File

@@ -0,0 +1,12 @@
using System.Drawing;
namespace AForge.Imaging.ColorReduction;
public interface IColorQuantizer
{
void AddColor(Color color);
Color[] GetPalette(int colorCount);
void Clear();
}

View File

@@ -0,0 +1,14 @@
namespace AForge.Imaging.ColorReduction;
public sealed class JarvisJudiceNinkeColorDithering : ColorErrorDiffusionToAdjacentNeighbors
{
public JarvisJudiceNinkeColorDithering()
: base(new int[3][]
{
new int[2] { 7, 5 },
new int[5] { 3, 5, 7, 5, 3 },
new int[5] { 1, 3, 5, 3, 1 }
})
{
}
}

View File

@@ -0,0 +1,134 @@
using System.Collections.Generic;
using System.Drawing;
namespace AForge.Imaging.ColorReduction;
internal class MedianCutCube
{
private class RedComparer : IComparer<Color>
{
public int Compare(Color c1, Color c2)
{
return c1.R.CompareTo(c2.R);
}
}
private class GreenComparer : IComparer<Color>
{
public int Compare(Color c1, Color c2)
{
return c1.G.CompareTo(c2.G);
}
}
private class BlueComparer : IComparer<Color>
{
public int Compare(Color c1, Color c2)
{
return c1.B.CompareTo(c2.B);
}
}
private List<Color> colors;
private readonly byte minR;
private readonly byte maxR;
private readonly byte minG;
private readonly byte maxG;
private readonly byte minB;
private readonly byte maxB;
private Color? cubeColor = null;
public int RedSize => maxR - minR;
public int GreenSize => maxG - minG;
public int BlueSize => maxB - minB;
public Color Color
{
get
{
if (!cubeColor.HasValue)
{
int num = 0;
int num2 = 0;
int num3 = 0;
foreach (Color color in colors)
{
num += color.R;
num2 += color.G;
num3 += color.B;
}
int count = colors.Count;
if (count != 0)
{
num /= count;
num2 /= count;
num3 /= count;
}
cubeColor = Color.FromArgb(num, num2, num3);
}
return cubeColor.Value;
}
}
public MedianCutCube(List<Color> colors)
{
this.colors = colors;
minR = (minG = (minB = byte.MaxValue));
maxR = (maxG = (maxB = 0));
foreach (Color color in colors)
{
if (color.R < minR)
{
minR = color.R;
}
if (color.R > maxR)
{
maxR = color.R;
}
if (color.G < minG)
{
minG = color.G;
}
if (color.G > maxG)
{
maxG = color.G;
}
if (color.B < minB)
{
minB = color.B;
}
if (color.B > maxB)
{
maxB = color.B;
}
}
}
public void SplitAtMedian(int rgbComponent, out MedianCutCube cube1, out MedianCutCube cube2)
{
switch (rgbComponent)
{
case 2:
colors.Sort(new RedComparer());
break;
case 1:
colors.Sort(new GreenComparer());
break;
case 0:
colors.Sort(new BlueComparer());
break;
}
int num = colors.Count / 2;
cube1 = new MedianCutCube(colors.GetRange(0, num));
cube2 = new MedianCutCube(colors.GetRange(num, colors.Count - num));
}
}

View File

@@ -0,0 +1,63 @@
using System.Collections.Generic;
using System.Drawing;
namespace AForge.Imaging.ColorReduction;
public class MedianCutQuantizer : IColorQuantizer
{
private List<Color> colors = new List<Color>();
public void AddColor(Color color)
{
colors.Add(color);
}
public Color[] GetPalette(int colorCount)
{
List<MedianCutCube> list = new List<MedianCutCube>();
list.Add(new MedianCutCube(colors));
SplitCubes(list, colorCount);
Color[] array = new Color[colorCount];
for (int i = 0; i < colorCount; i++)
{
ref Color reference = ref array[i];
reference = list[i].Color;
}
return array;
}
public void Clear()
{
colors.Clear();
}
private void SplitCubes(List<MedianCutCube> cubes, int count)
{
int num = cubes.Count - 1;
while (cubes.Count < count)
{
MedianCutCube medianCutCube = cubes[num];
MedianCutCube cube;
MedianCutCube cube2;
if (medianCutCube.RedSize >= medianCutCube.GreenSize && medianCutCube.RedSize >= medianCutCube.BlueSize)
{
medianCutCube.SplitAtMedian(2, out cube, out cube2);
}
else if (medianCutCube.GreenSize >= medianCutCube.BlueSize)
{
medianCutCube.SplitAtMedian(1, out cube, out cube2);
}
else
{
medianCutCube.SplitAtMedian(0, out cube, out cube2);
}
cubes.RemoveAt(num);
cubes.Insert(num, cube);
cubes.Insert(num, cube2);
if (--num < 0)
{
num = cubes.Count - 1;
}
}
}
}

View File

@@ -0,0 +1,232 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.ColorReduction;
public class OrderedColorDithering
{
private bool useCaching;
private Color[] colorTable = new Color[16]
{
Color.Black,
Color.DarkBlue,
Color.DarkGreen,
Color.DarkCyan,
Color.DarkRed,
Color.DarkMagenta,
Color.DarkKhaki,
Color.LightGray,
Color.Gray,
Color.Blue,
Color.Green,
Color.Cyan,
Color.Red,
Color.Magenta,
Color.Yellow,
Color.White
};
private byte[,] matrix = new byte[4, 4]
{
{ 2, 18, 6, 22 },
{ 26, 10, 30, 14 },
{ 8, 24, 4, 20 },
{ 32, 16, 28, 12 }
};
[NonSerialized]
private Dictionary<Color, byte> cache = new Dictionary<Color, byte>();
public byte[,] ThresholdMatrix
{
get
{
return (byte[,])matrix.Clone();
}
set
{
if (value == null)
{
throw new NullReferenceException("Threshold matrix cannot be set to null.");
}
matrix = value;
}
}
public Color[] ColorTable
{
get
{
return colorTable;
}
set
{
if (colorTable.Length < 2 || colorTable.Length > 256)
{
throw new ArgumentException("Color table length must be in the [2, 256] range.");
}
colorTable = value;
}
}
public bool UseCaching
{
get
{
return useCaching;
}
set
{
useCaching = value;
}
}
public OrderedColorDithering()
{
}
public OrderedColorDithering(byte[,] matrix)
{
ThresholdMatrix = matrix;
}
public Bitmap Apply(Bitmap sourceImage)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
BitmapData val = sourceImage.LockBits(new Rectangle(0, 0, ((Image)sourceImage).Width, ((Image)sourceImage).Height), (ImageLockMode)1, ((Image)sourceImage).PixelFormat);
Bitmap val2 = null;
try
{
val2 = Apply(new UnmanagedImage(val));
if (((Image)sourceImage).HorizontalResolution > 0f && ((Image)sourceImage).VerticalResolution > 0f)
{
val2.SetResolution(((Image)sourceImage).HorizontalResolution, ((Image)sourceImage).VerticalResolution);
}
}
finally
{
sourceImage.UnlockBits(val);
}
return val2;
}
public unsafe Bitmap Apply(UnmanagedImage sourceImage)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Invalid comparison between Unknown and I4
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Invalid comparison between Unknown and I4
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Expected O, but got Unknown
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Invalid comparison between Unknown and I4
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
if ((int)sourceImage.PixelFormat != 137224 && (int)sourceImage.PixelFormat != 139273 && (int)sourceImage.PixelFormat != 2498570 && (int)sourceImage.PixelFormat != 925707)
{
throw new UnsupportedImageFormatException("Unsupported pixel format of the source image.");
}
cache.Clear();
int width = sourceImage.Width;
int height = sourceImage.Height;
int stride = sourceImage.Stride;
int num = Image.GetPixelFormatSize(sourceImage.PixelFormat) / 8;
Bitmap val = new Bitmap(width, height, (PixelFormat)((colorTable.Length > 16) ? 198659 : 197634));
ColorPalette palette = ((Image)val).Palette;
int i = 0;
for (int num2 = colorTable.Length; i < num2; i++)
{
ref Color reference = ref palette.Entries[i];
reference = colorTable[i];
}
((Image)val).Palette = palette;
BitmapData val2 = val.LockBits(new Rectangle(0, 0, width, height), (ImageLockMode)3, ((Image)val).PixelFormat);
int length = matrix.GetLength(0);
int length2 = matrix.GetLength(1);
byte* ptr = (byte*)sourceImage.ImageData.ToPointer();
byte* ptr2 = (byte*)val2.Scan0.ToPointer();
bool flag = colorTable.Length > 16;
for (int j = 0; j < height; j++)
{
byte* ptr3 = ptr2 + (nint)j * (nint)val2.Stride;
int num3 = 0;
while (num3 < width)
{
int num4 = matrix[j % length, num3 % length2];
int num5 = ptr[2] + num4;
int num6 = ptr[1] + num4;
int num7 = *ptr + num4;
if (num5 > 255)
{
num5 = 255;
}
if (num6 > 255)
{
num6 = 255;
}
if (num7 > 255)
{
num7 = 255;
}
GetClosestColor(num5, num6, num7, out var colorIndex);
if (flag)
{
*ptr3 = colorIndex;
ptr3++;
}
else if (num3 % 2 == 0)
{
byte* intPtr = ptr3;
*intPtr |= (byte)(colorIndex << 4);
}
else
{
byte* intPtr2 = ptr3;
*intPtr2 |= colorIndex;
ptr3++;
}
num3++;
ptr += num;
}
}
val.UnlockBits(val2);
return val;
}
private Color GetClosestColor(int red, int green, int blue, out byte colorIndex)
{
Color key = Color.FromArgb(red, green, blue);
if (useCaching && cache.ContainsKey(key))
{
colorIndex = cache[key];
}
else
{
colorIndex = 0;
int num = int.MaxValue;
int i = 0;
for (int num2 = colorTable.Length; i < num2; i++)
{
int num3 = red - colorTable[i].R;
int num4 = green - colorTable[i].G;
int num5 = blue - colorTable[i].B;
int num6 = num3 * num3 + num4 * num4 + num5 * num5;
if (num6 < num)
{
num = num6;
colorIndex = (byte)i;
}
}
if (useCaching)
{
cache.Add(key, colorIndex);
}
}
return colorTable[colorIndex];
}
}

View File

@@ -0,0 +1,14 @@
namespace AForge.Imaging.ColorReduction;
public sealed class SierraColorDithering : ColorErrorDiffusionToAdjacentNeighbors
{
public SierraColorDithering()
: base(new int[3][]
{
new int[2] { 5, 3 },
new int[5] { 2, 4, 5, 4, 2 },
new int[3] { 2, 3, 2 }
})
{
}
}

View File

@@ -0,0 +1,14 @@
namespace AForge.Imaging.ColorReduction;
public sealed class StuckiColorDithering : ColorErrorDiffusionToAdjacentNeighbors
{
public StuckiColorDithering()
: base(new int[3][]
{
new int[2] { 8, 4 },
new int[5] { 2, 4, 8, 4, 2 },
new int[5] { 1, 2, 4, 2, 1 }
})
{
}
}

View File

@@ -0,0 +1,59 @@
using System;
using AForge.Math;
namespace AForge.Imaging.ComplexFilters;
public class FrequencyFilter : IComplexFilter
{
private IntRange frequencyRange = new IntRange(0, 1024);
public IntRange FrequencyRange
{
get
{
return frequencyRange;
}
set
{
frequencyRange = value;
}
}
public FrequencyFilter()
{
}
public FrequencyFilter(IntRange frequencyRange)
{
this.frequencyRange = frequencyRange;
}
public void Apply(ComplexImage complexImage)
{
if (!complexImage.FourierTransformed)
{
throw new ArgumentException("The source complex image should be Fourier transformed.");
}
int width = complexImage.Width;
int height = complexImage.Height;
int num = width >> 1;
int num2 = height >> 1;
int min = frequencyRange.Min;
int max = frequencyRange.Max;
Complex[,] data = complexImage.Data;
for (int i = 0; i < height; i++)
{
int num3 = i - num2;
for (int j = 0; j < width; j++)
{
int num4 = j - num;
int num5 = (int)System.Math.Sqrt(num4 * num4 + num3 * num3);
if (num5 > max || num5 < min)
{
data[i, j].Re = 0.0;
data[i, j].Im = 0.0;
}
}
}
}
}

View File

@@ -0,0 +1,6 @@
namespace AForge.Imaging.ComplexFilters;
public interface IComplexFilter
{
void Apply(ComplexImage complexImage);
}

View File

@@ -0,0 +1,164 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
using AForge.Math;
namespace AForge.Imaging;
public class ComplexImage : ICloneable
{
private Complex[,] data;
private int width;
private int height;
private bool fourierTransformed;
public int Width => width;
public int Height => height;
public bool FourierTransformed => fourierTransformed;
public Complex[,] Data => data;
protected ComplexImage(int width, int height)
{
this.width = width;
this.height = height;
data = new Complex[height, width];
fourierTransformed = false;
}
public object Clone()
{
ComplexImage complexImage = new ComplexImage(width, height);
Complex[,] array = complexImage.data;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
ref Complex reference = ref array[i, j];
reference = data[i, j];
}
}
complexImage.fourierTransformed = fourierTransformed;
return complexImage;
}
public static ComplexImage 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 (8bpp indexed) image only.");
}
BitmapData val = image.LockBits(new Rectangle(0, 0, ((Image)image).Width, ((Image)image).Height), (ImageLockMode)1, (PixelFormat)198659);
try
{
return FromBitmap(val);
}
finally
{
image.UnlockBits(val);
}
}
public unsafe static ComplexImage FromBitmap(BitmapData imageData)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
if ((int)imageData.PixelFormat != 198659)
{
throw new UnsupportedImageFormatException("Source image can be graysclae (8bpp indexed) image only.");
}
int num = imageData.Width;
int num2 = imageData.Height;
int num3 = imageData.Stride - num;
if (!Tools.IsPowerOf2(num) || !Tools.IsPowerOf2(num2))
{
throw new InvalidImagePropertiesException("Image width and height should be power of 2.");
}
ComplexImage complexImage = new ComplexImage(num, num2);
Complex[,] array = complexImage.data;
byte* ptr = (byte*)imageData.Scan0.ToPointer();
for (int i = 0; i < num2; i++)
{
int num4 = 0;
while (num4 < num)
{
array[i, num4].Re = (float)(int)(*ptr) / 255f;
num4++;
ptr++;
}
ptr += num3;
}
return complexImage;
}
public unsafe Bitmap ToBitmap()
{
Bitmap val = Image.CreateGrayscaleImage(width, height);
BitmapData val2 = val.LockBits(new Rectangle(0, 0, width, height), (ImageLockMode)3, (PixelFormat)198659);
int num = val2.Stride - width;
double num2 = (fourierTransformed ? System.Math.Sqrt(width * height) : 1.0);
byte* ptr = (byte*)val2.Scan0.ToPointer();
for (int i = 0; i < height; i++)
{
int num3 = 0;
while (num3 < width)
{
*ptr = (byte)System.Math.Max(0.0, System.Math.Min(255.0, data[i, num3].Magnitude * num2 * 255.0));
num3++;
ptr++;
}
ptr += num;
}
val.UnlockBits(val2);
return val;
}
public void ForwardFourierTransform()
{
if (fourierTransformed)
{
return;
}
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
if (((j + i) & 1) != 0)
{
data[i, j].Re *= -1.0;
data[i, j].Im *= -1.0;
}
}
}
FourierTransform.FFT2(data, FourierTransform.Direction.Forward);
fourierTransformed = true;
}
public void BackwardFourierTransform()
{
if (!fourierTransformed)
{
return;
}
FourierTransform.FFT2(data, FourierTransform.Direction.Backward);
fourierTransformed = false;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
if (((j + i) & 1) != 0)
{
data[i, j].Re *= -1.0;
data[i, j].Im *= -1.0;
}
}
}
}
}

View File

@@ -0,0 +1,295 @@
using System;
using System.Collections;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging;
public class DocumentSkewChecker
{
private int stepsPerDegree;
private int houghHeight;
private double thetaStep;
private double maxSkewToDetect;
private double[] sinMap;
private double[] cosMap;
private bool needToInitialize = true;
private short[,] houghMap;
private short maxMapIntensity;
private int localPeakRadius = 4;
private ArrayList lines = new ArrayList();
public int StepsPerDegree
{
get
{
return stepsPerDegree;
}
set
{
stepsPerDegree = System.Math.Max(1, System.Math.Min(10, value));
needToInitialize = true;
}
}
public double MaxSkewToDetect
{
get
{
return maxSkewToDetect;
}
set
{
maxSkewToDetect = System.Math.Max(0.0, System.Math.Min(45.0, value));
needToInitialize = true;
}
}
[Obsolete("The property is deprecated and setting it has not any effect. Use MaxSkewToDetect property instead.")]
public double MinBeta
{
get
{
return 0.0 - maxSkewToDetect;
}
set
{
}
}
[Obsolete("The property is deprecated and setting it has not any effect. Use MaxSkewToDetect property instead.")]
public double MaxBeta
{
get
{
return maxSkewToDetect;
}
set
{
}
}
public int LocalPeakRadius
{
get
{
return localPeakRadius;
}
set
{
localPeakRadius = System.Math.Max(1, System.Math.Min(10, value));
}
}
public DocumentSkewChecker()
{
StepsPerDegree = 10;
MaxSkewToDetect = 30.0;
}
public double GetSkewAngle(Bitmap image)
{
return GetSkewAngle(image, new Rectangle(0, 0, ((Image)image).Width, ((Image)image).Height));
}
public double GetSkewAngle(Bitmap image, Rectangle rect)
{
//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("Unsupported pixel format of the source image.");
}
BitmapData val = image.LockBits(new Rectangle(0, 0, ((Image)image).Width, ((Image)image).Height), (ImageLockMode)1, (PixelFormat)198659);
try
{
return GetSkewAngle(new UnmanagedImage(val), rect);
}
finally
{
image.UnlockBits(val);
}
}
public double GetSkewAngle(BitmapData imageData)
{
return GetSkewAngle(new UnmanagedImage(imageData), new Rectangle(0, 0, imageData.Width, imageData.Height));
}
public double GetSkewAngle(BitmapData imageData, Rectangle rect)
{
return GetSkewAngle(new UnmanagedImage(imageData), rect);
}
public double GetSkewAngle(UnmanagedImage image)
{
return GetSkewAngle(image, new Rectangle(0, 0, image.Width, image.Height));
}
public unsafe double GetSkewAngle(UnmanagedImage image, Rectangle rect)
{
//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 UnsupportedImageFormatException("Unsupported pixel format of the source image.");
}
InitHoughMap();
int width = image.Width;
int height = image.Height;
int num = width / 2;
int num2 = height / 2;
rect.Intersect(new Rectangle(0, 0, width, height));
int num3 = -num + rect.Left;
int num4 = -num2 + rect.Top;
int num5 = width - num - (width - rect.Right);
int num6 = height - num2 - (height - rect.Bottom) - 1;
int num7 = image.Stride - rect.Width;
int num8 = (int)System.Math.Sqrt(num * num + num2 * num2);
int num9 = num8 * 2;
houghMap = new short[houghHeight, num9];
byte* ptr = (byte*)image.ImageData.ToPointer() + (nint)rect.Top * (nint)image.Stride + rect.Left;
byte* ptr2 = ptr + image.Stride;
for (int i = num4; i < num6; i++)
{
int num10 = num3;
while (num10 < num5)
{
if (*ptr < 128 && *ptr2 >= 128)
{
for (int j = 0; j < houghHeight; j++)
{
int num11 = (int)(cosMap[j] * (double)num10 - sinMap[j] * (double)i) + num8;
if (num11 >= 0 && num11 < num9)
{
houghMap[j, num11]++;
}
}
}
num10++;
ptr++;
ptr2++;
}
ptr += num7;
ptr2 += num7;
}
maxMapIntensity = 0;
for (int k = 0; k < houghHeight; k++)
{
for (int l = 0; l < num9; l++)
{
if (houghMap[k, l] > maxMapIntensity)
{
maxMapIntensity = houghMap[k, l];
}
}
}
CollectLines((short)(width / 10));
HoughLine[] mostIntensiveLines = GetMostIntensiveLines(5);
double num12 = 0.0;
double num13 = 0.0;
HoughLine[] array = mostIntensiveLines;
foreach (HoughLine houghLine in array)
{
if (houghLine.RelativeIntensity > 0.5)
{
num12 += houghLine.Theta * houghLine.RelativeIntensity;
num13 += houghLine.RelativeIntensity;
}
}
if (mostIntensiveLines.Length > 0)
{
num12 /= num13;
}
return num12 - 90.0;
}
private HoughLine[] GetMostIntensiveLines(int count)
{
int num = System.Math.Min(count, lines.Count);
HoughLine[] array = new HoughLine[num];
lines.CopyTo(0, array, 0, num);
return array;
}
private void CollectLines(short minLineIntensity)
{
int length = houghMap.GetLength(0);
int length2 = houghMap.GetLength(1);
int num = length2 >> 1;
lines.Clear();
for (int i = 0; i < length; i++)
{
for (int j = 0; j < length2; j++)
{
short num2 = houghMap[i, j];
if (num2 < minLineIntensity)
{
continue;
}
bool flag = false;
int k = i - localPeakRadius;
for (int num3 = i + localPeakRadius; k < num3; k++)
{
if (k < 0)
{
continue;
}
if (k >= length || flag)
{
break;
}
int l = j - localPeakRadius;
for (int num4 = j + localPeakRadius; l < num4; l++)
{
if (l >= 0)
{
if (l >= length2)
{
break;
}
if (houghMap[k, l] > num2)
{
flag = true;
break;
}
}
}
}
if (!flag)
{
lines.Add(new HoughLine(90.0 - maxSkewToDetect + (double)i / (double)stepsPerDegree, (short)(j - num), num2, (double)num2 / (double)maxMapIntensity));
}
}
}
lines.Sort();
}
private void InitHoughMap()
{
if (needToInitialize)
{
needToInitialize = false;
houghHeight = (int)(2.0 * maxSkewToDetect * (double)stepsPerDegree);
thetaStep = 2.0 * maxSkewToDetect * System.Math.PI / 180.0 / (double)houghHeight;
sinMap = new double[houghHeight];
cosMap = new double[houghHeight];
double num = 90.0 - maxSkewToDetect;
for (int i = 0; i < houghHeight; i++)
{
sinMap[i] = System.Math.Sin(num * System.Math.PI / 180.0 + (double)i * thetaStep);
cosMap[i] = System.Math.Cos(num * System.Math.PI / 180.0 + (double)i * thetaStep);
}
}
}
}

View File

@@ -0,0 +1,381 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging;
public static class Drawing
{
public static void FillRectangle(BitmapData imageData, Rectangle rectangle, Color color)
{
FillRectangle(new UnmanagedImage(imageData), rectangle, color);
}
public unsafe static void FillRectangle(UnmanagedImage image, Rectangle rectangle, Color color)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Invalid comparison between Unknown and I4
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
//IL_0145: Invalid comparison between Unknown and I4
CheckPixelFormat(image.PixelFormat);
int num = Image.GetPixelFormatSize(image.PixelFormat) / 8;
int width = image.Width;
int height = image.Height;
int stride = image.Stride;
int x = rectangle.X;
int y = rectangle.Y;
int num2 = rectangle.X + rectangle.Width - 1;
int num3 = rectangle.Y + rectangle.Height - 1;
if (x >= width || y >= height || num2 < 0 || num3 < 0)
{
return;
}
int num4 = System.Math.Max(0, x);
int num5 = System.Math.Min(width - 1, num2);
int num6 = System.Math.Max(0, y);
int num7 = System.Math.Min(height - 1, num3);
byte* ptr = (byte*)image.ImageData.ToPointer() + (nint)num6 * (nint)stride + (nint)num4 * (nint)num;
if ((int)image.PixelFormat == 198659)
{
byte filler = (byte)(0.2125 * (double)(int)color.R + 0.7154 * (double)(int)color.G + 0.0721 * (double)(int)color.B);
int count = num5 - num4 + 1;
for (int i = num6; i <= num7; i++)
{
SystemTools.SetUnmanagedMemory(ptr, filler, count);
ptr += stride;
}
return;
}
if ((int)image.PixelFormat == 2498570)
{
double num8 = (double)(int)color.A / 255.0;
double num9 = 1.0 - num8;
double num10 = num8 * (double)(int)color.R;
double num11 = num8 * (double)(int)color.G;
double num12 = num8 * (double)(int)color.B;
int num13 = stride - (num5 - num4 + 1) * 4;
for (int j = num6; j <= num7; j++)
{
int num14 = num4;
while (num14 <= num5)
{
double num15 = (double)(int)ptr[3] / 255.0 * num9;
ptr[2] = (byte)(num10 + num15 * (double)(int)ptr[2]);
ptr[1] = (byte)(num11 + num15 * (double)(int)ptr[1]);
*ptr = (byte)(num12 + num15 * (double)(int)(*ptr));
ptr[3] = (byte)(255.0 * (num8 + num15));
num14++;
ptr += 4;
}
ptr += num13;
}
return;
}
byte r = color.R;
byte g = color.G;
byte b = color.B;
int num16 = stride - (num5 - num4 + 1) * num;
if (color.A == byte.MaxValue)
{
for (int k = num6; k <= num7; k++)
{
int num17 = num4;
while (num17 <= num5)
{
ptr[2] = r;
ptr[1] = g;
*ptr = b;
num17++;
ptr += num;
}
ptr += num16;
}
return;
}
int a = color.A;
int num18 = 255 - a;
int num19 = a * color.R;
int num20 = a * color.G;
int num21 = a * color.B;
for (int l = num6; l <= num7; l++)
{
int num22 = num4;
while (num22 <= num5)
{
ptr[2] = (byte)((num19 + num18 * ptr[2]) / 255);
ptr[1] = (byte)((num20 + num18 * ptr[1]) / 255);
*ptr = (byte)((num21 + num18 * *ptr) / 255);
num22++;
ptr += num;
}
ptr += num16;
}
}
public static void Rectangle(BitmapData imageData, Rectangle rectangle, Color color)
{
Rectangle(new UnmanagedImage(imageData), rectangle, color);
}
public static void Rectangle(UnmanagedImage image, Rectangle rectangle, Color color)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
CheckPixelFormat(image.PixelFormat);
_ = Image.GetPixelFormatSize(image.PixelFormat) / 8;
int width = image.Width;
int height = image.Height;
_ = image.Stride;
int x = rectangle.X;
int y = rectangle.Y;
int num = rectangle.X + rectangle.Width - 1;
int num2 = rectangle.Y + rectangle.Height - 1;
if (x < width && y < height && num >= 0 && num2 >= 0)
{
Line(image, new IntPoint(x, y), new IntPoint(num, y), color);
Line(image, new IntPoint(num, num2), new IntPoint(x, num2), color);
Line(image, new IntPoint(num, y + 1), new IntPoint(num, num2 - 1), color);
Line(image, new IntPoint(x, num2 - 1), new IntPoint(x, y + 1), color);
}
}
public static void Line(BitmapData imageData, IntPoint point1, IntPoint point2, Color color)
{
Line(new UnmanagedImage(imageData), point1, point2, color);
}
public unsafe static void Line(UnmanagedImage image, IntPoint point1, IntPoint point2, Color color)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_0116: Invalid comparison between Unknown and I4
//IL_045d: Unknown result type (might be due to invalid IL or missing references)
//IL_0467: Invalid comparison between Unknown and I4
//IL_0226: Unknown result type (might be due to invalid IL or missing references)
//IL_0230: Invalid comparison between Unknown and I4
//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
//IL_04ba: Invalid comparison between Unknown and I4
//IL_0279: Unknown result type (might be due to invalid IL or missing references)
//IL_0283: Invalid comparison between Unknown and I4
CheckPixelFormat(image.PixelFormat);
int num = Image.GetPixelFormatSize(image.PixelFormat) / 8;
int width = image.Width;
int height = image.Height;
int stride = image.Stride;
if ((point1.X < 0 && point2.X < 0) || (point1.Y < 0 && point2.Y < 0) || (point1.X >= width && point2.X >= width) || (point1.Y >= height && point2.Y >= height))
{
return;
}
CheckEndPoint(width, height, point1, ref point2);
CheckEndPoint(width, height, point2, ref point1);
if ((point1.X < 0 && point2.X < 0) || (point1.Y < 0 && point2.Y < 0) || (point1.X >= width && point2.X >= width) || (point1.Y >= height && point2.Y >= height))
{
return;
}
int x = point1.X;
int y = point1.Y;
int x2 = point2.X;
int y2 = point2.Y;
byte b = 0;
if ((int)image.PixelFormat == 198659)
{
b = (byte)(0.2125 * (double)(int)color.R + 0.7154 * (double)(int)color.G + 0.0721 * (double)(int)color.B);
}
double num2 = (double)(int)color.A / 255.0;
double num3 = 1.0 - num2;
double num4 = num2 * (double)(int)color.R;
double num5 = num2 * (double)(int)color.G;
double num6 = num2 * (double)(int)color.B;
int num7 = 255 - color.A;
int num8 = color.A * color.R;
int num9 = color.A * color.G;
int num10 = color.A * color.B;
int num11 = x2 - x;
int num12 = y2 - y;
if (System.Math.Abs(num11) >= System.Math.Abs(num12))
{
float num13 = ((num11 != 0) ? ((float)num12 / (float)num11) : 0f);
int num14 = ((num11 > 0) ? 1 : (-1));
num11 += num14;
if ((int)image.PixelFormat == 198659)
{
for (int i = 0; i != num11; i += num14)
{
int num15 = x + i;
int num16 = (int)((float)y + num13 * (float)i);
byte* ptr = (byte*)image.ImageData.ToPointer() + (nint)num16 * (nint)stride + num15;
*ptr = b;
}
}
else if ((int)image.PixelFormat == 2498570)
{
for (int j = 0; j != num11; j += num14)
{
int num17 = x + j;
int num18 = (int)((float)y + num13 * (float)j);
byte* ptr2 = (byte*)image.ImageData.ToPointer() + (nint)num18 * (nint)stride + (nint)num17 * (nint)4;
double num19 = (double)(int)ptr2[3] / 255.0 * num3;
ptr2[2] = (byte)(num4 + num19 * (double)(int)ptr2[2]);
ptr2[1] = (byte)(num5 + num19 * (double)(int)ptr2[1]);
*ptr2 = (byte)(num6 + num19 * (double)(int)(*ptr2));
ptr2[3] = (byte)(255.0 * (num2 + num19));
}
}
else if (color.A == byte.MaxValue)
{
for (int k = 0; k != num11; k += num14)
{
int num20 = x + k;
int num21 = (int)((float)y + num13 * (float)k);
byte* ptr3 = (byte*)image.ImageData.ToPointer() + (nint)num21 * (nint)stride + (nint)num20 * (nint)num;
ptr3[2] = color.R;
ptr3[1] = color.G;
*ptr3 = color.B;
}
}
else
{
for (int l = 0; l != num11; l += num14)
{
int num22 = x + l;
int num23 = (int)((float)y + num13 * (float)l);
byte* ptr4 = (byte*)image.ImageData.ToPointer() + (nint)num23 * (nint)stride + (nint)num22 * (nint)num;
ptr4[2] = (byte)((num8 + num7 * ptr4[2]) / 255);
ptr4[1] = (byte)((num9 + num7 * ptr4[1]) / 255);
*ptr4 = (byte)((num10 + num7 * *ptr4) / 255);
}
}
return;
}
float num24 = ((num12 != 0) ? ((float)num11 / (float)num12) : 0f);
int num25 = ((num12 > 0) ? 1 : (-1));
num12 += num25;
if ((int)image.PixelFormat == 198659)
{
for (int m = 0; m != num12; m += num25)
{
int num26 = (int)((float)x + num24 * (float)m);
int num27 = y + m;
byte* ptr5 = (byte*)image.ImageData.ToPointer() + (nint)num27 * (nint)stride + num26;
*ptr5 = b;
}
}
else if ((int)image.PixelFormat == 2498570)
{
for (int n = 0; n != num12; n += num25)
{
int num28 = (int)((float)x + num24 * (float)n);
int num29 = y + n;
byte* ptr6 = (byte*)image.ImageData.ToPointer() + (nint)num29 * (nint)stride + (nint)num28 * (nint)4;
double num30 = (double)(int)ptr6[3] / 255.0 * num3;
ptr6[2] = (byte)(num4 + num30 * (double)(int)ptr6[2]);
ptr6[1] = (byte)(num5 + num30 * (double)(int)ptr6[1]);
*ptr6 = (byte)(num6 + num30 * (double)(int)(*ptr6));
ptr6[3] = (byte)(255.0 * (num2 + num30));
}
}
else if (color.A == byte.MaxValue)
{
for (int num31 = 0; num31 != num12; num31 += num25)
{
int num32 = (int)((float)x + num24 * (float)num31);
int num33 = y + num31;
byte* ptr7 = (byte*)image.ImageData.ToPointer() + (nint)num33 * (nint)stride + (nint)num32 * (nint)num;
ptr7[2] = color.R;
ptr7[1] = color.G;
*ptr7 = color.B;
}
}
else
{
for (int num34 = 0; num34 != num12; num34 += num25)
{
int num35 = (int)((float)x + num24 * (float)num34);
int num36 = y + num34;
byte* ptr8 = (byte*)image.ImageData.ToPointer() + (nint)num36 * (nint)stride + (nint)num35 * (nint)num;
ptr8[2] = (byte)((num8 + num7 * ptr8[2]) / 255);
ptr8[1] = (byte)((num9 + num7 * ptr8[1]) / 255);
*ptr8 = (byte)((num10 + num7 * *ptr8) / 255);
}
}
}
public static void Polygon(BitmapData imageData, List<IntPoint> points, Color color)
{
Polygon(new UnmanagedImage(imageData), points, color);
}
public static void Polygon(UnmanagedImage image, List<IntPoint> points, Color color)
{
int i = 1;
for (int count = points.Count; i < count; i++)
{
Line(image, points[i - 1], points[i], color);
}
Line(image, points[points.Count - 1], points[0], color);
}
public static void Polyline(BitmapData imageData, List<IntPoint> points, Color color)
{
Polyline(new UnmanagedImage(imageData), points, color);
}
public static void Polyline(UnmanagedImage image, List<IntPoint> points, Color color)
{
int i = 1;
for (int count = points.Count; i < count; i++)
{
Line(image, points[i - 1], points[i], color);
}
}
private static void CheckPixelFormat(PixelFormat format)
{
//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
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Invalid comparison between Unknown and I4
if ((int)format != 137224 && (int)format != 198659 && (int)format != 2498570 && (int)format != 139273)
{
throw new UnsupportedImageFormatException("Unsupported pixel format of the source image.");
}
}
private static void CheckEndPoint(int width, int height, IntPoint start, ref IntPoint end)
{
if (end.X >= width)
{
int num = width - 1;
double num2 = (double)(num - start.X) / (double)(end.X - start.X);
end.Y = (int)((double)start.Y + num2 * (double)(end.Y - start.Y));
end.X = num;
}
if (end.Y >= height)
{
int num3 = height - 1;
double num4 = (double)(num3 - start.Y) / (double)(end.Y - start.Y);
end.X = (int)((double)start.X + num4 * (double)(end.X - start.X));
end.Y = num3;
}
if (end.X < 0)
{
double num5 = (double)(-start.X) / (double)(end.X - start.X);
end.Y = (int)((double)start.Y + num5 * (double)(end.Y - start.Y));
end.X = 0;
}
if (end.Y < 0)
{
double num6 = (double)(-start.Y) / (double)(end.Y - start.Y);
end.X = (int)((double)start.X + num6 * (double)(end.X - start.X));
end.Y = 0;
}
}
}

View File

@@ -0,0 +1,8 @@
namespace AForge.Imaging;
internal static class ExceptionMessage
{
public const string ColorHistogramException = "Cannot access color histogram since the last processed image was grayscale.";
public const string GrayHistogramException = "Cannot access gray histogram since the last processed image was color.";
}

View File

@@ -0,0 +1,198 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging;
public class ExhaustiveBlockMatching : IBlockMatching
{
private class MatchingsSorter : IComparer<BlockMatch>
{
public int Compare(BlockMatch x, BlockMatch y)
{
float num = y.Similarity - x.Similarity;
if (!(num > 0f))
{
if (!(num < 0f))
{
return 0;
}
return -1;
}
return 1;
}
}
private int blockSize = 16;
private int searchRadius = 12;
private float similarityThreshold = 0.9f;
public int SearchRadius
{
get
{
return searchRadius;
}
set
{
searchRadius = value;
}
}
public int BlockSize
{
get
{
return blockSize;
}
set
{
blockSize = value;
}
}
public float SimilarityThreshold
{
get
{
return similarityThreshold;
}
set
{
similarityThreshold = System.Math.Min(1f, System.Math.Max(0f, value));
}
}
public ExhaustiveBlockMatching()
{
}
public ExhaustiveBlockMatching(int blockSize, int searchRadius)
{
this.blockSize = blockSize;
this.searchRadius = searchRadius;
}
public List<BlockMatch> ProcessImage(Bitmap sourceImage, List<IntPoint> coordinates, Bitmap searchImage)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
BitmapData val = sourceImage.LockBits(new Rectangle(0, 0, ((Image)sourceImage).Width, ((Image)sourceImage).Height), (ImageLockMode)1, ((Image)sourceImage).PixelFormat);
BitmapData val2 = searchImage.LockBits(new Rectangle(0, 0, ((Image)searchImage).Width, ((Image)searchImage).Height), (ImageLockMode)1, ((Image)searchImage).PixelFormat);
try
{
return ProcessImage(new UnmanagedImage(val), coordinates, new UnmanagedImage(val2));
}
finally
{
sourceImage.UnlockBits(val);
searchImage.UnlockBits(val2);
}
}
public List<BlockMatch> ProcessImage(BitmapData sourceImageData, List<IntPoint> coordinates, BitmapData searchImageData)
{
return ProcessImage(new UnmanagedImage(sourceImageData), coordinates, new UnmanagedImage(searchImageData));
}
public unsafe List<BlockMatch> ProcessImage(UnmanagedImage sourceImage, List<IntPoint> coordinates, UnmanagedImage searchImage)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Invalid comparison between Unknown and I4
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Invalid comparison between Unknown and I4
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Invalid comparison between Unknown and I4
if (sourceImage.Width != searchImage.Width || sourceImage.Height != searchImage.Height)
{
throw new InvalidImagePropertiesException("Source and search images sizes must match");
}
if ((int)sourceImage.PixelFormat != 198659 && (int)sourceImage.PixelFormat != 137224)
{
throw new UnsupportedImageFormatException("Source images can be graysclae (8 bpp indexed) or color (24 bpp) image only");
}
if (sourceImage.PixelFormat != searchImage.PixelFormat)
{
throw new InvalidImagePropertiesException("Source and search images must have same pixel format");
}
int count = coordinates.Count;
List<BlockMatch> list = new List<BlockMatch>();
int width = sourceImage.Width;
int height = sourceImage.Height;
int stride = sourceImage.Stride;
int num = (((int)sourceImage.PixelFormat == 198659) ? 1 : 3);
int num2 = blockSize / 2;
int num3 = 2 * searchRadius;
int num4 = blockSize * num;
int num5 = stride - blockSize * num;
int num6 = blockSize * blockSize * num * 255;
int num7 = (int)(similarityThreshold * (float)num6);
byte* ptr = (byte*)sourceImage.ImageData.ToPointer();
byte* ptr2 = (byte*)searchImage.ImageData.ToPointer();
for (int i = 0; i < count; i++)
{
int x = coordinates[i].X;
int y = coordinates[i].Y;
if (x - num2 < 0 || x + num2 >= width || y - num2 < 0 || y + num2 >= height)
{
continue;
}
int num8 = x - num2 - searchRadius;
int num9 = y - num2 - searchRadius;
int x2 = x;
int y2 = y;
int num10 = int.MaxValue;
for (int j = 0; j < num3; j++)
{
if (num9 + j < 0 || num9 + j + blockSize >= height)
{
continue;
}
for (int k = 0; k < num3; k++)
{
int num11 = num8 + k;
int num12 = num9 + j;
if (num11 < 0 || num12 + blockSize >= width)
{
continue;
}
byte* ptr3 = ptr + (nint)(y - num2) * (nint)stride + (nint)(x - num2) * (nint)num;
byte* ptr4 = ptr2 + (nint)num12 * (nint)stride + (nint)num11 * (nint)num;
int num13 = 0;
for (int l = 0; l < blockSize; l++)
{
int num14 = 0;
while (num14 < num4)
{
int num15 = *ptr3 - *ptr4;
num13 = ((num15 <= 0) ? (num13 - num15) : (num13 + num15));
num14++;
ptr3++;
ptr4++;
}
ptr3 += num5;
ptr4 += num5;
}
if (num13 < num10)
{
num10 = num13;
x2 = num11 + num2;
y2 = num12 + num2;
}
}
}
int num16 = num6 - num10;
if (num16 >= num7)
{
list.Add(new BlockMatch(new IntPoint(x, y), new IntPoint(x2, y2), (float)num16 / (float)num6));
}
}
list.Sort(new MatchingsSorter());
return list;
}
}

View File

@@ -0,0 +1,200 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging;
public class ExhaustiveTemplateMatching : ITemplateMatching
{
private class MatchingsSorter : IComparer
{
public int Compare(object x, object y)
{
float num = ((TemplateMatch)y).Similarity - ((TemplateMatch)x).Similarity;
if (!(num > 0f))
{
if (!(num < 0f))
{
return 0;
}
return -1;
}
return 1;
}
}
private float similarityThreshold = 0.9f;
public float SimilarityThreshold
{
get
{
return similarityThreshold;
}
set
{
similarityThreshold = System.Math.Min(1f, System.Math.Max(0f, value));
}
}
public ExhaustiveTemplateMatching()
{
}
public ExhaustiveTemplateMatching(float similarityThreshold)
{
this.similarityThreshold = similarityThreshold;
}
public TemplateMatch[] ProcessImage(Bitmap image, Bitmap template)
{
return ProcessImage(image, template, new Rectangle(0, 0, ((Image)image).Width, ((Image)image).Height));
}
public TemplateMatch[] ProcessImage(Bitmap image, Bitmap template, Rectangle searchZone)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
//IL_001b: 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_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Invalid comparison between Unknown and I4
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
if (((int)((Image)image).PixelFormat != 198659 && (int)((Image)image).PixelFormat != 137224) || ((Image)image).PixelFormat != ((Image)template).PixelFormat)
{
throw new UnsupportedImageFormatException("Unsupported pixel format of the source or template image.");
}
if (((Image)template).Width > ((Image)image).Width || ((Image)template).Height > ((Image)image).Height)
{
throw new InvalidImagePropertiesException("Template's size should be smaller or equal to source image's size.");
}
BitmapData val = image.LockBits(new Rectangle(0, 0, ((Image)image).Width, ((Image)image).Height), (ImageLockMode)1, ((Image)image).PixelFormat);
BitmapData val2 = template.LockBits(new Rectangle(0, 0, ((Image)template).Width, ((Image)template).Height), (ImageLockMode)1, ((Image)template).PixelFormat);
try
{
return ProcessImage(new UnmanagedImage(val), new UnmanagedImage(val2), searchZone);
}
finally
{
image.UnlockBits(val);
template.UnlockBits(val2);
}
}
public TemplateMatch[] ProcessImage(BitmapData imageData, BitmapData templateData)
{
return ProcessImage(new UnmanagedImage(imageData), new UnmanagedImage(templateData), new Rectangle(0, 0, imageData.Width, imageData.Height));
}
public TemplateMatch[] ProcessImage(BitmapData imageData, BitmapData templateData, Rectangle searchZone)
{
return ProcessImage(new UnmanagedImage(imageData), new UnmanagedImage(templateData), searchZone);
}
public TemplateMatch[] ProcessImage(UnmanagedImage image, UnmanagedImage template)
{
return ProcessImage(image, template, new Rectangle(0, 0, image.Width, image.Height));
}
public unsafe TemplateMatch[] ProcessImage(UnmanagedImage image, UnmanagedImage template, Rectangle searchZone)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
//IL_001b: 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_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Invalid comparison between Unknown and I4
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Invalid comparison between Unknown and I4
if (((int)image.PixelFormat != 198659 && (int)image.PixelFormat != 137224) || image.PixelFormat != template.PixelFormat)
{
throw new UnsupportedImageFormatException("Unsupported pixel format of the source or template image.");
}
Rectangle rectangle = searchZone;
rectangle.Intersect(new Rectangle(0, 0, image.Width, image.Height));
int x = rectangle.X;
int y = rectangle.Y;
int width = rectangle.Width;
int height = rectangle.Height;
int width2 = template.Width;
int height2 = template.Height;
if (width2 > width || height2 > height)
{
throw new InvalidImagePropertiesException("Template's size should be smaller or equal to search zone.");
}
int num = (((int)image.PixelFormat == 198659) ? 1 : 3);
int stride = image.Stride;
int num2 = width - width2 + 1;
int num3 = height - height2 + 1;
int[,] array = new int[num3 + 4, num2 + 4];
int num4 = width2 * height2 * num * 255;
int num5 = (int)(similarityThreshold * (float)num4);
int num6 = width2 * num;
byte* ptr = (byte*)image.ImageData.ToPointer();
byte* ptr2 = (byte*)template.ImageData.ToPointer();
int num7 = image.Stride - width2 * num;
int num8 = template.Stride - width2 * num;
for (int i = 0; i < num3; i++)
{
for (int j = 0; j < num2; j++)
{
byte* ptr3 = ptr + (nint)stride * (nint)(i + y) + (nint)num * (nint)(j + x);
byte* ptr4 = ptr2;
int num9 = 0;
for (int k = 0; k < height2; k++)
{
int num10 = 0;
while (num10 < num6)
{
int num11 = *ptr3 - *ptr4;
num9 = ((num11 <= 0) ? (num9 - num11) : (num9 + num11));
num10++;
ptr3++;
ptr4++;
}
ptr3 += num7;
ptr4 += num8;
}
int num12 = num4 - num9;
if (num12 >= num5)
{
array[i + 2, j + 2] = num12;
}
}
}
List<TemplateMatch> list = new List<TemplateMatch>();
int l = 2;
for (int num13 = num3 + 2; l < num13; l++)
{
int m = 2;
for (int num14 = num2 + 2; m < num14; m++)
{
int num15 = array[l, m];
int num16 = -2;
while (num15 != 0 && num16 <= 2)
{
for (int n = -2; n <= 2; n++)
{
if (array[l + num16, m + n] > num15)
{
num15 = 0;
break;
}
}
num16++;
}
if (num15 != 0)
{
list.Add(new TemplateMatch(new Rectangle(m - 2 + x, l - 2 + y, width2, height2), (float)num15 / (float)num4));
}
}
}
TemplateMatch[] array2 = new TemplateMatch[list.Count];
list.CopyTo(array2);
Array.Sort(array2, new MatchingsSorter());
return array2;
}
}

View File

@@ -0,0 +1,128 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class AdaptiveSmoothing : BaseUsingCopyPartialFilter
{
private double factor = 3.0;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public double Factor
{
get
{
return factor;
}
set
{
factor = value;
}
}
public AdaptiveSmoothing()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
}
public AdaptiveSmoothing(double factor)
: this()
{
this.factor = factor;
}
protected unsafe override void ProcessFilter(UnmanagedImage source, UnmanagedImage destination, Rectangle rect)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
int num = Image.GetPixelFormatSize(source.PixelFormat) / 8;
int num2 = num * 2;
int left = rect.Left;
int top = rect.Top;
int num3 = left + rect.Width;
int num4 = top + rect.Height;
int num5 = left + 2;
int num6 = top + 2;
int num7 = num3 - 2;
int num8 = num4 - 2;
int stride = source.Stride;
int stride2 = destination.Stride;
int num9 = stride - rect.Width * num;
int num10 = stride2 - rect.Width * num;
double num11 = -8.0 * factor * factor;
byte* ptr = (byte*)source.ImageData.ToPointer() + (nint)stride * (nint)2;
byte* ptr2 = (byte*)destination.ImageData.ToPointer() + (nint)stride2 * (nint)2;
ptr += top * stride + left * num;
ptr2 += top * stride2 + left * num;
for (int i = num6; i < num8; i++)
{
ptr += num2;
ptr2 += num2;
for (int j = num5; j < num7; j++)
{
int num12 = 0;
while (num12 < num)
{
double num13 = 0.0;
double num14 = 0.0;
double num15 = ptr[-stride] - ptr[-num2 - stride];
double num16 = ptr[-num] - ptr[-num - 2 * stride];
double num17 = System.Math.Exp((num15 * num15 + num16 * num16) / num11);
num14 += num17 * (double)(int)ptr[-num - stride];
num13 += num17;
num15 = ptr[num - stride] - ptr[-num - stride];
num16 = *ptr - ptr[(nint)(-2) * (nint)stride];
num17 = System.Math.Exp((num15 * num15 + num16 * num16) / num11);
num14 += num17 * (double)(int)ptr[-stride];
num13 += num17;
num15 = ptr[num2 - stride] - ptr[-stride];
num16 = ptr[num] - ptr[num - 2 * stride];
num17 = System.Math.Exp((num15 * num15 + num16 * num16) / num11);
num14 += num17 * (double)(int)ptr[num - stride];
num13 += num17;
num15 = *ptr - ptr[-num2];
num16 = ptr[-num + stride] - ptr[-num - stride];
num17 = System.Math.Exp((num15 * num15 + num16 * num16) / num11);
num14 += num17 * (double)(int)ptr[-num];
num13 += num17;
num15 = ptr[num] - ptr[-num];
num16 = ptr[stride] - ptr[-stride];
num17 = System.Math.Exp((num15 * num15 + num16 * num16) / num11);
num14 += num17 * (double)(int)(*ptr);
num13 += num17;
num15 = ptr[num2] - *ptr;
num16 = ptr[num + stride] - ptr[num - stride];
num17 = System.Math.Exp((num15 * num15 + num16 * num16) / num11);
num14 += num17 * (double)(int)ptr[num];
num13 += num17;
num15 = ptr[stride] - ptr[-num2 + stride];
num16 = ptr[-num + 2 * stride] - ptr[-num];
num17 = System.Math.Exp((num15 * num15 + num16 * num16) / num11);
num14 += num17 * (double)(int)ptr[-num + stride];
num13 += num17;
num15 = ptr[num + stride] - ptr[-num + stride];
num16 = ptr[(nint)2 * (nint)stride] - *ptr;
num17 = System.Math.Exp((num15 * num15 + num16 * num16) / num11);
num14 += num17 * (double)(int)ptr[stride];
num13 += num17;
num15 = ptr[num2 + stride] - ptr[stride];
num16 = ptr[num + 2 * stride] - ptr[num];
num17 = System.Math.Exp((num15 * num15 + num16 * num16) / num11);
num14 += num17 * (double)(int)ptr[num + stride];
num13 += num17;
*ptr2 = ((num13 == 0.0) ? (*ptr) : ((byte)System.Math.Min(num14 / num13, 255.0)));
num12++;
ptr++;
ptr2++;
}
}
ptr += num9 + num2;
ptr2 += num10 + num2;
}
}
}

View File

@@ -0,0 +1,109 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public sealed class Add : BaseInPlaceFilter2
{
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public Add()
{
InitFormatTranslations();
}
public Add(Bitmap overlayImage)
: base(overlayImage)
{
InitFormatTranslations();
}
public Add(UnmanagedImage unmanagedOverlayImage)
: base(unmanagedOverlayImage)
{
InitFormatTranslations();
}
private void InitFormatTranslations()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
formatTranslations[(PixelFormat)1052676] = (PixelFormat)1052676;
formatTranslations[(PixelFormat)1060876] = (PixelFormat)1060876;
formatTranslations[(PixelFormat)3424269] = (PixelFormat)3424269;
}
protected unsafe override void ProcessFilter(UnmanagedImage image, UnmanagedImage overlay)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Invalid comparison between Unknown and I4
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Invalid comparison between Unknown and I4
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Invalid comparison between Unknown and I4
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Invalid comparison between Unknown and I4
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Invalid comparison between Unknown and I4
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Invalid comparison between Unknown and I4
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Invalid comparison between Unknown and I4
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Invalid comparison between Unknown and I4
PixelFormat pixelFormat = image.PixelFormat;
int width = image.Width;
int height = image.Height;
if ((int)pixelFormat == 198659 || (int)pixelFormat == 137224 || (int)pixelFormat == 139273 || (int)pixelFormat == 2498570)
{
int num = (((int)pixelFormat == 198659) ? 1 : (((int)pixelFormat == 137224) ? 3 : 4));
int num2 = width * num;
int num3 = image.Stride - num2;
int num4 = overlay.Stride - num2;
byte* ptr = (byte*)image.ImageData.ToPointer();
byte* ptr2 = (byte*)overlay.ImageData.ToPointer();
for (int i = 0; i < height; i++)
{
int num5 = 0;
while (num5 < num2)
{
int num6 = *ptr + *ptr2;
*ptr = ((num6 > 255) ? byte.MaxValue : ((byte)num6));
num5++;
ptr++;
ptr2++;
}
ptr += num3;
ptr2 += num4;
}
return;
}
int num7 = (((int)pixelFormat == 1052676) ? 1 : (((int)pixelFormat == 1060876) ? 3 : 4));
int num8 = width * num7;
int stride = image.Stride;
int stride2 = overlay.Stride;
byte* ptr3 = (byte*)image.ImageData.ToPointer();
byte* ptr4 = (byte*)overlay.ImageData.ToPointer();
for (int j = 0; j < height; j++)
{
ushort* ptr5 = (ushort*)(ptr3 + (nint)j * (nint)stride);
ushort* ptr6 = (ushort*)(ptr4 + (nint)j * (nint)stride2);
int num9 = 0;
while (num9 < num8)
{
int num10 = *ptr5 + *ptr6;
*ptr5 = ((num10 > 65535) ? ushort.MaxValue : ((ushort)num10));
num9++;
ptr5++;
ptr6++;
}
}
}
}

View File

@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using AForge.Math.Random;
namespace AForge.Imaging.Filters;
public class AdditiveNoise : BaseInPlacePartialFilter
{
private IRandomNumberGenerator generator = new UniformGenerator(new Range(-10f, 10f));
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public IRandomNumberGenerator Generator
{
get
{
return generator;
}
set
{
generator = value;
}
}
public AdditiveNoise()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
}
public AdditiveNoise(IRandomNumberGenerator generator)
: this()
{
this.generator = generator;
}
protected unsafe override void ProcessFilter(UnmanagedImage image, Rectangle rect)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
int num = (((int)image.PixelFormat == 198659) ? 1 : 3);
int top = rect.Top;
int num2 = top + rect.Height;
int num3 = rect.Left * num;
int num4 = num3 + rect.Width * num;
int num5 = image.Stride - (num4 - num3);
byte* ptr = (byte*)image.ImageData.ToPointer();
ptr += top * image.Stride + rect.Left * num;
for (int i = top; i < num2; i++)
{
int num6 = num3;
while (num6 < num4)
{
*ptr = (byte)System.Math.Max(0f, System.Math.Min(255f, (float)(int)(*ptr) + generator.Next()));
num6++;
ptr++;
}
ptr += num5;
}
}
}

View File

@@ -0,0 +1,308 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class ApplyMask : BaseInPlacePartialFilter
{
private Bitmap maskImage;
private UnmanagedImage unmanagedMaskImage;
private byte[,] mask;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public Bitmap MaskImage
{
get
{
return maskImage;
}
set
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Invalid comparison between Unknown and I4
if (maskImage != null && (int)((Image)maskImage).PixelFormat != 198659)
{
throw new ArgumentException("The mask image must be 8 bpp grayscale image.");
}
maskImage = value;
unmanagedMaskImage = null;
mask = null;
}
}
public UnmanagedImage UnmanagedMaskImage
{
get
{
return unmanagedMaskImage;
}
set
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Invalid comparison between Unknown and I4
if (unmanagedMaskImage != null && (int)unmanagedMaskImage.PixelFormat != 198659)
{
throw new ArgumentException("The mask image must be 8 bpp grayscale image.");
}
unmanagedMaskImage = value;
maskImage = null;
mask = null;
}
}
public byte[,] Mask
{
get
{
return mask;
}
set
{
mask = value;
maskImage = null;
unmanagedMaskImage = null;
}
}
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
private ApplyMask()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
formatTranslations[(PixelFormat)925707] = (PixelFormat)925707;
formatTranslations[(PixelFormat)1052676] = (PixelFormat)1052676;
formatTranslations[(PixelFormat)1060876] = (PixelFormat)1060876;
formatTranslations[(PixelFormat)3424269] = (PixelFormat)3424269;
formatTranslations[(PixelFormat)1851406] = (PixelFormat)1851406;
}
public ApplyMask(Bitmap maskImage)
: this()
{
MaskImage = maskImage;
}
public ApplyMask(UnmanagedImage unmanagedMaskImage)
: this()
{
UnmanagedMaskImage = unmanagedMaskImage;
}
public ApplyMask(byte[,] mask)
: this()
{
Mask = mask;
}
protected unsafe override void ProcessFilter(UnmanagedImage image, Rectangle rect)
{
if (mask != null)
{
if (image.Width != mask.GetLength(1) || image.Height != mask.GetLength(0))
{
throw new ArgumentException("Invalid size of mask array. Its size must be the same as the size of the image to mask.");
}
fixed (byte* ptr = mask)
{
ProcessImage(image, rect, ptr, mask.GetLength(1));
}
return;
}
if (unmanagedMaskImage != null)
{
if (image.Width != unmanagedMaskImage.Width || image.Height != unmanagedMaskImage.Height)
{
throw new ArgumentException("Invalid size of unmanaged mask image. Its size must be the same as the size of the image to mask.");
}
ProcessImage(image, rect, (byte*)unmanagedMaskImage.ImageData.ToPointer(), unmanagedMaskImage.Stride);
return;
}
if (maskImage != null)
{
if (image.Width != ((Image)maskImage).Width || image.Height != ((Image)maskImage).Height)
{
throw new ArgumentException("Invalid size of mask image. Its size must be the same as the size of the image to mask.");
}
BitmapData val = maskImage.LockBits(new Rectangle(0, 0, image.Width, image.Height), (ImageLockMode)1, (PixelFormat)198659);
try
{
ProcessImage(image, rect, (byte*)val.Scan0.ToPointer(), val.Stride);
return;
}
finally
{
maskImage.UnlockBits(val);
}
}
throw new NullReferenceException("None of the possible mask properties were set. Need to provide mask before applying the filter.");
}
private unsafe void ProcessImage(UnmanagedImage image, Rectangle rect, byte* mask, int maskLineSize)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
int num = Image.GetPixelFormatSize(image.PixelFormat) / 8;
int top = rect.Top;
int num2 = top + rect.Height;
int left = rect.Left;
int num3 = left + rect.Width;
int stride = image.Stride;
int num4 = maskLineSize - rect.Width;
mask += maskLineSize * top + left;
if (num <= 4 && num != 2)
{
byte* ptr = (byte*)image.ImageData.ToPointer() + (nint)stride * (nint)top + (nint)num * (nint)left;
int num5 = stride - rect.Width * num;
switch (num)
{
case 1:
{
for (int j = top; j < num2; j++)
{
int num7 = left;
while (num7 < num3)
{
if (*mask == 0)
{
*ptr = 0;
}
num7++;
ptr++;
mask++;
}
ptr += num5;
mask += num4;
}
break;
}
case 3:
{
for (int k = top; k < num2; k++)
{
int num8 = left;
while (num8 < num3)
{
if (*mask == 0)
{
ptr[2] = 0;
ptr[1] = 0;
*ptr = 0;
}
num8++;
ptr += 3;
mask++;
}
ptr += num5;
mask += num4;
}
break;
}
case 4:
{
for (int i = top; i < num2; i++)
{
int num6 = left;
while (num6 < num3)
{
if (*mask == 0)
{
ptr[2] = 0;
ptr[1] = 0;
*ptr = 0;
ptr[3] = 0;
}
num6++;
ptr += 4;
mask++;
}
ptr += num5;
mask += num4;
}
break;
}
case 2:
break;
}
return;
}
byte* ptr2 = (byte*)image.ImageData.ToPointer() + (nint)stride * (nint)top + (nint)num * (nint)left;
switch (num)
{
case 2:
{
for (int m = top; m < num2; m++)
{
ushort* ptr4 = (ushort*)ptr2;
int num10 = left;
while (num10 < num3)
{
if (*mask == 0)
{
*ptr4 = 0;
}
num10++;
ptr4++;
mask++;
}
ptr2 += stride;
mask += num4;
}
break;
}
case 6:
{
for (int n = top; n < num2; n++)
{
ushort* ptr5 = (ushort*)ptr2;
int num11 = left;
while (num11 < num3)
{
if (*mask == 0)
{
ptr5[2] = 0;
ptr5[1] = 0;
*ptr5 = 0;
}
num11++;
ptr5 += 3;
mask++;
}
ptr2 += stride;
mask += num4;
}
break;
}
case 8:
{
for (int l = top; l < num2; l++)
{
ushort* ptr3 = (ushort*)ptr2;
int num9 = left;
while (num9 < num3)
{
if (*mask == 0)
{
ptr3[2] = 0;
ptr3[1] = 0;
*ptr3 = 0;
ptr3[3] = 0;
}
num9++;
ptr3 += 4;
mask++;
}
ptr2 += stride;
mask += num4;
}
break;
}
}
}
}

View File

@@ -0,0 +1,276 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using AForge.Math.Geometry;
namespace AForge.Imaging.Filters;
public class BackwardQuadrilateralTransformation : BaseInPlaceFilter
{
private Bitmap sourceImage;
private UnmanagedImage sourceUnmanagedImage;
private List<IntPoint> destinationQuadrilateral;
private bool useInterpolation = true;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public Bitmap SourceImage
{
get
{
return sourceImage;
}
set
{
sourceImage = value;
if (value != null)
{
sourceUnmanagedImage = null;
}
}
}
public UnmanagedImage SourceUnmanagedImage
{
get
{
return sourceUnmanagedImage;
}
set
{
sourceUnmanagedImage = value;
if (value != null)
{
sourceImage = null;
}
}
}
public List<IntPoint> DestinationQuadrilateral
{
get
{
return destinationQuadrilateral;
}
set
{
destinationQuadrilateral = value;
}
}
public bool UseInterpolation
{
get
{
return useInterpolation;
}
set
{
useInterpolation = value;
}
}
public BackwardQuadrilateralTransformation()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
formatTranslations[(PixelFormat)925707] = (PixelFormat)925707;
}
public BackwardQuadrilateralTransformation(Bitmap sourceImage)
: this()
{
this.sourceImage = sourceImage;
}
public BackwardQuadrilateralTransformation(UnmanagedImage sourceUnmanagedImage)
: this()
{
this.sourceUnmanagedImage = sourceUnmanagedImage;
}
public BackwardQuadrilateralTransformation(Bitmap sourceImage, List<IntPoint> destinationQuadrilateral)
: this()
{
this.sourceImage = sourceImage;
this.destinationQuadrilateral = destinationQuadrilateral;
}
public BackwardQuadrilateralTransformation(UnmanagedImage sourceUnmanagedImage, List<IntPoint> destinationQuadrilateral)
: this()
{
this.sourceUnmanagedImage = sourceUnmanagedImage;
this.destinationQuadrilateral = destinationQuadrilateral;
}
protected override void ProcessFilter(UnmanagedImage image)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
if (destinationQuadrilateral == null)
{
throw new NullReferenceException("Destination quadrilateral was not set.");
}
if (sourceImage != null)
{
if (image.PixelFormat != ((Image)sourceImage).PixelFormat)
{
throw new InvalidImagePropertiesException("Source and destination images must have same pixel format.");
}
BitmapData val = sourceImage.LockBits(new Rectangle(0, 0, ((Image)sourceImage).Width, ((Image)sourceImage).Height), (ImageLockMode)1, ((Image)sourceImage).PixelFormat);
try
{
ProcessFilter(image, new UnmanagedImage(val));
return;
}
finally
{
sourceImage.UnlockBits(val);
}
}
if (sourceUnmanagedImage != null)
{
if (image.PixelFormat != sourceUnmanagedImage.PixelFormat)
{
throw new InvalidImagePropertiesException("Source and destination images must have same pixel format.");
}
ProcessFilter(image, sourceUnmanagedImage);
return;
}
throw new NullReferenceException("Source image is not set.");
}
private unsafe void ProcessFilter(UnmanagedImage dstImage, UnmanagedImage srcImage)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
int width = srcImage.Width;
int height = srcImage.Height;
int width2 = dstImage.Width;
int height2 = dstImage.Height;
int num = Image.GetPixelFormatSize(srcImage.PixelFormat) / 8;
int stride = srcImage.Stride;
int stride2 = dstImage.Stride;
PointsCloud.GetBoundingRectangle(destinationQuadrilateral, out var minXY, out var maxXY);
if (maxXY.X < 0 || maxXY.Y < 0 || minXY.X >= width2 || minXY.Y >= height2)
{
return;
}
if (minXY.X < 0)
{
minXY.X = 0;
}
if (minXY.Y < 0)
{
minXY.Y = 0;
}
if (maxXY.X >= width2)
{
maxXY.X = width2 - 1;
}
if (maxXY.Y >= height2)
{
maxXY.Y = height2 - 1;
}
int x = minXY.X;
int y = minXY.Y;
int num2 = maxXY.X + 1;
int num3 = maxXY.Y + 1;
int num4 = stride2 - (num2 - x) * num;
List<IntPoint> list = new List<IntPoint>();
list.Add(new IntPoint(0, 0));
list.Add(new IntPoint(width - 1, 0));
list.Add(new IntPoint(width - 1, height - 1));
list.Add(new IntPoint(0, height - 1));
double[,] array = QuadTransformationCalcs.MapQuadToQuad(destinationQuadrilateral, list);
byte* ptr = (byte*)dstImage.ImageData.ToPointer();
byte* ptr2 = (byte*)srcImage.ImageData.ToPointer();
ptr += y * stride2 + x * num;
if (!useInterpolation)
{
for (int i = y; i < num3; i++)
{
for (int j = x; j < num2; j++)
{
double num5 = array[2, 0] * (double)j + array[2, 1] * (double)i + array[2, 2];
double num6 = (array[0, 0] * (double)j + array[0, 1] * (double)i + array[0, 2]) / num5;
double num7 = (array[1, 0] * (double)j + array[1, 1] * (double)i + array[1, 2]) / num5;
if (num6 >= 0.0 && num7 >= 0.0 && num6 < (double)width && num7 < (double)height)
{
byte* ptr3 = ptr2 + (nint)(int)num7 * (nint)stride + (nint)(int)num6 * (nint)num;
int num8 = 0;
while (num8 < num)
{
*ptr = *ptr3;
num8++;
ptr++;
ptr3++;
}
}
else
{
ptr += num;
}
}
ptr += num4;
}
return;
}
int num9 = width - 1;
int num10 = height - 1;
for (int k = y; k < num3; k++)
{
for (int l = x; l < num2; l++)
{
double num11 = array[2, 0] * (double)l + array[2, 1] * (double)k + array[2, 2];
double num12 = (array[0, 0] * (double)l + array[0, 1] * (double)k + array[0, 2]) / num11;
double num13 = (array[1, 0] * (double)l + array[1, 1] * (double)k + array[1, 2]) / num11;
if (num12 >= 0.0 && num13 >= 0.0 && num12 < (double)width && num13 < (double)height)
{
int num14 = (int)num12;
int num15 = ((num14 == num9) ? num14 : (num14 + 1));
double num16 = num12 - (double)num14;
double num17 = 1.0 - num16;
int num18 = (int)num13;
int num19 = ((num18 == num10) ? num18 : (num18 + 1));
double num20 = num13 - (double)num18;
double num21 = 1.0 - num20;
byte* ptr5;
byte* ptr4 = (ptr5 = ptr2 + (nint)num18 * (nint)stride);
ptr4 += (nint)num14 * (nint)num;
ptr5 += (nint)num15 * (nint)num;
byte* ptr7;
byte* ptr6 = (ptr7 = ptr2 + (nint)num19 * (nint)stride);
ptr6 += (nint)num14 * (nint)num;
ptr7 += (nint)num15 * (nint)num;
int num22 = 0;
while (num22 < num)
{
*ptr = (byte)(num21 * (num17 * (double)(int)(*ptr4) + num16 * (double)(int)(*ptr5)) + num20 * (num17 * (double)(int)(*ptr6) + num16 * (double)(int)(*ptr7)));
num22++;
ptr++;
ptr4++;
ptr5++;
ptr6++;
ptr7++;
}
}
else
{
ptr += num;
}
}
ptr += num4;
}
}
}

View File

@@ -0,0 +1,98 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public abstract class BaseFilter : IFilter, IFilterInformation
{
public abstract Dictionary<PixelFormat, PixelFormat> FormatTranslations { get; }
public Bitmap Apply(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);
Bitmap val2 = null;
try
{
val2 = Apply(val);
if (((Image)image).HorizontalResolution > 0f && ((Image)image).VerticalResolution > 0f)
{
val2.SetResolution(((Image)image).HorizontalResolution, ((Image)image).VerticalResolution);
}
}
finally
{
image.UnlockBits(val);
}
return val2;
}
public Bitmap Apply(BitmapData imageData)
{
//IL_0002: 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_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Invalid comparison between Unknown and I4
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
CheckSourceFormat(imageData.PixelFormat);
int width = imageData.Width;
int height = imageData.Height;
PixelFormat val = FormatTranslations[imageData.PixelFormat];
Bitmap val2 = (Bitmap)(((int)val == 198659) ? ((object)Image.CreateGrayscaleImage(width, height)) : ((object)new Bitmap(width, height, val)));
BitmapData val3 = val2.LockBits(new Rectangle(0, 0, width, height), (ImageLockMode)3, val);
try
{
ProcessFilter(new UnmanagedImage(imageData), new UnmanagedImage(val3));
}
finally
{
val2.UnlockBits(val3);
}
return val2;
}
public UnmanagedImage Apply(UnmanagedImage image)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
CheckSourceFormat(image.PixelFormat);
UnmanagedImage unmanagedImage = UnmanagedImage.Create(image.Width, image.Height, FormatTranslations[image.PixelFormat]);
ProcessFilter(image, unmanagedImage);
return unmanagedImage;
}
public void Apply(UnmanagedImage sourceImage, UnmanagedImage destinationImage)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
CheckSourceFormat(sourceImage.PixelFormat);
if (destinationImage.PixelFormat != FormatTranslations[sourceImage.PixelFormat])
{
throw new InvalidImagePropertiesException("Destination pixel format is specified incorrectly.");
}
if (destinationImage.Width != sourceImage.Width || destinationImage.Height != sourceImage.Height)
{
throw new InvalidImagePropertiesException("Destination image must have the same width and height as source image.");
}
ProcessFilter(sourceImage, destinationImage);
}
protected abstract void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData);
private void CheckSourceFormat(PixelFormat pixelFormat)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
if (!FormatTranslations.ContainsKey(pixelFormat))
{
throw new UnsupportedImageFormatException("Source pixel format is not supported by the filter.");
}
}
}

View File

@@ -0,0 +1,109 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public abstract class BaseFilter2 : BaseFilter
{
private Bitmap overlayImage;
private UnmanagedImage unmanagedOverlayImage;
public Bitmap OverlayImage
{
get
{
return overlayImage;
}
set
{
overlayImage = value;
if (value != null)
{
unmanagedOverlayImage = null;
}
}
}
public UnmanagedImage UnmanagedOverlayImage
{
get
{
return unmanagedOverlayImage;
}
set
{
unmanagedOverlayImage = value;
if (value != null)
{
overlayImage = null;
}
}
}
protected BaseFilter2()
{
}
protected BaseFilter2(Bitmap overlayImage)
{
this.overlayImage = overlayImage;
}
protected BaseFilter2(UnmanagedImage unmanagedOverlayImage)
{
this.unmanagedOverlayImage = unmanagedOverlayImage;
}
protected override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
PixelFormat pixelFormat = sourceData.PixelFormat;
int width = sourceData.Width;
int height = sourceData.Height;
if (overlayImage != null)
{
if (pixelFormat != ((Image)overlayImage).PixelFormat)
{
throw new InvalidImagePropertiesException("Source and overlay images must have same pixel format.");
}
if (width != ((Image)overlayImage).Width || height != ((Image)overlayImage).Height)
{
throw new InvalidImagePropertiesException("Overlay image size must be equal to source image size.");
}
BitmapData val = overlayImage.LockBits(new Rectangle(0, 0, width, height), (ImageLockMode)1, pixelFormat);
try
{
ProcessFilter(sourceData, new UnmanagedImage(val), destinationData);
return;
}
finally
{
overlayImage.UnlockBits(val);
}
}
if (unmanagedOverlayImage != null)
{
if (pixelFormat != unmanagedOverlayImage.PixelFormat)
{
throw new InvalidImagePropertiesException("Source and overlay images must have same pixel format.");
}
if (width != unmanagedOverlayImage.Width || height != unmanagedOverlayImage.Height)
{
throw new InvalidImagePropertiesException("Overlay image size must be equal to source image size.");
}
ProcessFilter(sourceData, unmanagedOverlayImage, destinationData);
return;
}
throw new NullReferenceException("Overlay image is not set.");
}
protected abstract void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage overlay, UnmanagedImage destinationData);
}

View File

@@ -0,0 +1,139 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public abstract class BaseInPlaceFilter : IFilter, IInPlaceFilter, IFilterInformation
{
public abstract Dictionary<PixelFormat, PixelFormat> FormatTranslations { get; }
public Bitmap Apply(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);
Bitmap val2 = null;
try
{
val2 = Apply(val);
if (((Image)image).HorizontalResolution > 0f && ((Image)image).VerticalResolution > 0f)
{
val2.SetResolution(((Image)image).HorizontalResolution, ((Image)image).VerticalResolution);
}
}
finally
{
image.UnlockBits(val);
}
return val2;
}
public Bitmap Apply(BitmapData imageData)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Invalid comparison between Unknown and I4
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
PixelFormat pixelFormat = imageData.PixelFormat;
CheckSourceFormat(pixelFormat);
int width = imageData.Width;
int height = imageData.Height;
Bitmap val = (Bitmap)(((int)pixelFormat == 198659) ? ((object)Image.CreateGrayscaleImage(width, height)) : ((object)new Bitmap(width, height, pixelFormat)));
BitmapData val2 = val.LockBits(new Rectangle(0, 0, width, height), (ImageLockMode)3, pixelFormat);
SystemTools.CopyUnmanagedMemory(val2.Scan0, imageData.Scan0, imageData.Stride * height);
try
{
ProcessFilter(new UnmanagedImage(val2));
}
finally
{
val.UnlockBits(val2);
}
return val;
}
public UnmanagedImage Apply(UnmanagedImage image)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
CheckSourceFormat(image.PixelFormat);
UnmanagedImage unmanagedImage = UnmanagedImage.Create(image.Width, image.Height, image.PixelFormat);
Apply(image, unmanagedImage);
return unmanagedImage;
}
public unsafe void Apply(UnmanagedImage sourceImage, UnmanagedImage destinationImage)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
CheckSourceFormat(sourceImage.PixelFormat);
if (destinationImage.PixelFormat != sourceImage.PixelFormat)
{
throw new InvalidImagePropertiesException("Destination pixel format must be the same as pixel format of source image.");
}
if (destinationImage.Width != sourceImage.Width || destinationImage.Height != sourceImage.Height)
{
throw new InvalidImagePropertiesException("Destination image must have the same width and height as source image.");
}
int stride = destinationImage.Stride;
int stride2 = sourceImage.Stride;
int count = System.Math.Min(stride2, stride);
byte* ptr = (byte*)destinationImage.ImageData.ToPointer();
byte* ptr2 = (byte*)sourceImage.ImageData.ToPointer();
int i = 0;
for (int height = sourceImage.Height; i < height; i++)
{
SystemTools.CopyUnmanagedMemory(ptr, ptr2, count);
ptr += stride;
ptr2 += stride2;
}
ProcessFilter(destinationImage);
}
public void ApplyInPlace(Bitmap image)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: 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)3, ((Image)image).PixelFormat);
try
{
ProcessFilter(new UnmanagedImage(val));
}
finally
{
image.UnlockBits(val);
}
}
public void ApplyInPlace(BitmapData imageData)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
CheckSourceFormat(imageData.PixelFormat);
ProcessFilter(new UnmanagedImage(imageData));
}
public void ApplyInPlace(UnmanagedImage image)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
CheckSourceFormat(image.PixelFormat);
ProcessFilter(image);
}
protected abstract void ProcessFilter(UnmanagedImage image);
private void CheckSourceFormat(PixelFormat pixelFormat)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
if (!FormatTranslations.ContainsKey(pixelFormat))
{
throw new UnsupportedImageFormatException("Source pixel format is not supported by the filter.");
}
}
}

View File

@@ -0,0 +1,109 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public abstract class BaseInPlaceFilter2 : BaseInPlaceFilter
{
private Bitmap overlayImage;
private UnmanagedImage unmanagedOverlayImage;
public Bitmap OverlayImage
{
get
{
return overlayImage;
}
set
{
overlayImage = value;
if (value != null)
{
unmanagedOverlayImage = null;
}
}
}
public UnmanagedImage UnmanagedOverlayImage
{
get
{
return unmanagedOverlayImage;
}
set
{
unmanagedOverlayImage = value;
if (value != null)
{
overlayImage = null;
}
}
}
protected BaseInPlaceFilter2()
{
}
protected BaseInPlaceFilter2(Bitmap overlayImage)
{
this.overlayImage = overlayImage;
}
protected BaseInPlaceFilter2(UnmanagedImage unmanagedOverlayImage)
{
this.unmanagedOverlayImage = unmanagedOverlayImage;
}
protected override void ProcessFilter(UnmanagedImage image)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
PixelFormat pixelFormat = image.PixelFormat;
int width = image.Width;
int height = image.Height;
if (overlayImage != null)
{
if (pixelFormat != ((Image)overlayImage).PixelFormat)
{
throw new InvalidImagePropertiesException("Source and overlay images must have same pixel format.");
}
if (width != ((Image)overlayImage).Width || height != ((Image)overlayImage).Height)
{
throw new InvalidImagePropertiesException("Overlay image size must be equal to source image size.");
}
BitmapData val = overlayImage.LockBits(new Rectangle(0, 0, width, height), (ImageLockMode)1, pixelFormat);
try
{
ProcessFilter(image, new UnmanagedImage(val));
return;
}
finally
{
overlayImage.UnlockBits(val);
}
}
if (unmanagedOverlayImage != null)
{
if (pixelFormat != unmanagedOverlayImage.PixelFormat)
{
throw new InvalidImagePropertiesException("Source and overlay images must have same pixel format.");
}
if (width != unmanagedOverlayImage.Width || height != unmanagedOverlayImage.Height)
{
throw new InvalidImagePropertiesException("Overlay image size must be equal to source image size.");
}
ProcessFilter(image, unmanagedOverlayImage);
return;
}
throw new NullReferenceException("Overlay image is not set.");
}
protected abstract void ProcessFilter(UnmanagedImage image, UnmanagedImage overlay);
}

View File

@@ -0,0 +1,158 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public abstract class BaseInPlacePartialFilter : IFilter, IInPlaceFilter, IInPlacePartialFilter, IFilterInformation
{
public abstract Dictionary<PixelFormat, PixelFormat> FormatTranslations { get; }
public Bitmap Apply(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);
Bitmap val2 = null;
try
{
val2 = Apply(val);
if (((Image)image).HorizontalResolution > 0f && ((Image)image).VerticalResolution > 0f)
{
val2.SetResolution(((Image)image).HorizontalResolution, ((Image)image).VerticalResolution);
}
}
finally
{
image.UnlockBits(val);
}
return val2;
}
public Bitmap Apply(BitmapData imageData)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Invalid comparison between Unknown and I4
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
PixelFormat pixelFormat = imageData.PixelFormat;
CheckSourceFormat(pixelFormat);
int width = imageData.Width;
int height = imageData.Height;
Bitmap val = (Bitmap)(((int)pixelFormat == 198659) ? ((object)Image.CreateGrayscaleImage(width, height)) : ((object)new Bitmap(width, height, pixelFormat)));
BitmapData val2 = val.LockBits(new Rectangle(0, 0, width, height), (ImageLockMode)3, pixelFormat);
SystemTools.CopyUnmanagedMemory(val2.Scan0, imageData.Scan0, imageData.Stride * height);
try
{
ProcessFilter(new UnmanagedImage(val2), new Rectangle(0, 0, width, height));
}
finally
{
val.UnlockBits(val2);
}
return val;
}
public UnmanagedImage Apply(UnmanagedImage image)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
CheckSourceFormat(image.PixelFormat);
UnmanagedImage unmanagedImage = UnmanagedImage.Create(image.Width, image.Height, image.PixelFormat);
Apply(image, unmanagedImage);
return unmanagedImage;
}
public unsafe void Apply(UnmanagedImage sourceImage, UnmanagedImage destinationImage)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
CheckSourceFormat(sourceImage.PixelFormat);
if (destinationImage.PixelFormat != sourceImage.PixelFormat)
{
throw new InvalidImagePropertiesException("Destination pixel format must be the same as pixel format of source image.");
}
if (destinationImage.Width != sourceImage.Width || destinationImage.Height != sourceImage.Height)
{
throw new InvalidImagePropertiesException("Destination image must have the same width and height as source image.");
}
int stride = destinationImage.Stride;
int stride2 = sourceImage.Stride;
int count = System.Math.Min(stride2, stride);
byte* ptr = (byte*)destinationImage.ImageData.ToPointer();
byte* ptr2 = (byte*)sourceImage.ImageData.ToPointer();
int i = 0;
for (int height = sourceImage.Height; i < height; i++)
{
SystemTools.CopyUnmanagedMemory(ptr, ptr2, count);
ptr += stride;
ptr2 += stride2;
}
ProcessFilter(destinationImage, new Rectangle(0, 0, destinationImage.Width, destinationImage.Height));
}
public void ApplyInPlace(Bitmap image)
{
ApplyInPlace(image, new Rectangle(0, 0, ((Image)image).Width, ((Image)image).Height));
}
public void ApplyInPlace(BitmapData imageData)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
CheckSourceFormat(imageData.PixelFormat);
ProcessFilter(new UnmanagedImage(imageData), new Rectangle(0, 0, imageData.Width, imageData.Height));
}
public void ApplyInPlace(UnmanagedImage image)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
CheckSourceFormat(image.PixelFormat);
ProcessFilter(image, new Rectangle(0, 0, image.Width, image.Height));
}
public void ApplyInPlace(Bitmap image, Rectangle rect)
{
//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)3, ((Image)image).PixelFormat);
try
{
ApplyInPlace(new UnmanagedImage(val), rect);
}
finally
{
image.UnlockBits(val);
}
}
public void ApplyInPlace(BitmapData imageData, Rectangle rect)
{
ApplyInPlace(new UnmanagedImage(imageData), rect);
}
public void ApplyInPlace(UnmanagedImage image, Rectangle rect)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
CheckSourceFormat(image.PixelFormat);
rect.Intersect(new Rectangle(0, 0, image.Width, image.Height));
if ((rect.Width | rect.Height) != 0)
{
ProcessFilter(image, rect);
}
}
protected abstract void ProcessFilter(UnmanagedImage image, Rectangle rect);
private void CheckSourceFormat(PixelFormat pixelFormat)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
if (!FormatTranslations.ContainsKey(pixelFormat))
{
throw new UnsupportedImageFormatException("Source pixel format is not supported by the filter.");
}
}
}

View File

@@ -0,0 +1,46 @@
using System;
using System.Drawing;
namespace AForge.Imaging.Filters;
public abstract class BaseResizeFilter : BaseTransformationFilter
{
protected int newWidth;
protected int newHeight;
public int NewWidth
{
get
{
return newWidth;
}
set
{
newWidth = System.Math.Max(1, value);
}
}
public int NewHeight
{
get
{
return newHeight;
}
set
{
newHeight = System.Math.Max(1, value);
}
}
protected BaseResizeFilter(int newWidth, int newHeight)
{
this.newWidth = newWidth;
this.newHeight = newHeight;
}
protected override Size CalculateNewImageSize(UnmanagedImage sourceData)
{
return new Size(newWidth, newHeight);
}
}

View File

@@ -0,0 +1,84 @@
using System;
using System.Drawing;
namespace AForge.Imaging.Filters;
public abstract class BaseRotateFilter : BaseTransformationFilter
{
protected double angle;
protected bool keepSize;
protected Color fillColor = Color.FromArgb(0, 0, 0);
public double Angle
{
get
{
return angle;
}
set
{
angle = value % 360.0;
}
}
public bool KeepSize
{
get
{
return keepSize;
}
set
{
keepSize = value;
}
}
public Color FillColor
{
get
{
return fillColor;
}
set
{
fillColor = value;
}
}
public BaseRotateFilter(double angle)
{
this.angle = angle;
}
public BaseRotateFilter(double angle, bool keepSize)
{
this.angle = angle;
this.keepSize = keepSize;
}
protected override Size CalculateNewImageSize(UnmanagedImage sourceData)
{
if (keepSize)
{
return new Size(sourceData.Width, sourceData.Height);
}
double num = (0.0 - angle) * System.Math.PI / 180.0;
double num2 = System.Math.Cos(num);
double num3 = System.Math.Sin(num);
double num4 = (double)sourceData.Width / 2.0;
double num5 = (double)sourceData.Height / 2.0;
double val = num4 * num2;
double val2 = num4 * num3;
double val3 = num4 * num2 - num5 * num3;
double val4 = num4 * num3 + num5 * num2;
double val5 = (0.0 - num5) * num3;
double val6 = num5 * num2;
double val7 = 0.0;
double val8 = 0.0;
num4 = System.Math.Max(System.Math.Max(val, val3), System.Math.Max(val5, val7)) - System.Math.Min(System.Math.Min(val, val3), System.Math.Min(val5, val7));
num5 = System.Math.Max(System.Math.Max(val2, val4), System.Math.Max(val6, val8)) - System.Math.Min(System.Math.Min(val2, val4), System.Math.Min(val6, val8));
return new Size((int)(num4 * 2.0 + 0.5), (int)(num5 * 2.0 + 0.5));
}
}

View File

@@ -0,0 +1,101 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public abstract class BaseTransformationFilter : IFilter, IFilterInformation
{
public abstract Dictionary<PixelFormat, PixelFormat> FormatTranslations { get; }
public Bitmap Apply(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);
Bitmap val2 = null;
try
{
val2 = Apply(val);
if (((Image)image).HorizontalResolution > 0f && ((Image)image).VerticalResolution > 0f)
{
val2.SetResolution(((Image)image).HorizontalResolution, ((Image)image).VerticalResolution);
}
}
finally
{
image.UnlockBits(val);
}
return val2;
}
public Bitmap Apply(BitmapData imageData)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Invalid comparison between Unknown and I4
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
CheckSourceFormat(imageData.PixelFormat);
PixelFormat val = FormatTranslations[imageData.PixelFormat];
Size size = CalculateNewImageSize(new UnmanagedImage(imageData));
Bitmap val2 = (Bitmap)(((int)val == 198659) ? ((object)Image.CreateGrayscaleImage(size.Width, size.Height)) : ((object)new Bitmap(size.Width, size.Height, val)));
BitmapData val3 = val2.LockBits(new Rectangle(0, 0, size.Width, size.Height), (ImageLockMode)3, val);
try
{
ProcessFilter(new UnmanagedImage(imageData), new UnmanagedImage(val3));
}
finally
{
val2.UnlockBits(val3);
}
return val2;
}
public UnmanagedImage Apply(UnmanagedImage image)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
CheckSourceFormat(image.PixelFormat);
Size size = CalculateNewImageSize(image);
UnmanagedImage unmanagedImage = UnmanagedImage.Create(size.Width, size.Height, FormatTranslations[image.PixelFormat]);
ProcessFilter(image, unmanagedImage);
return unmanagedImage;
}
public void Apply(UnmanagedImage sourceImage, UnmanagedImage destinationImage)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
CheckSourceFormat(sourceImage.PixelFormat);
if (destinationImage.PixelFormat != FormatTranslations[sourceImage.PixelFormat])
{
throw new InvalidImagePropertiesException("Destination pixel format is specified incorrectly.");
}
Size size = CalculateNewImageSize(sourceImage);
if (destinationImage.Width != size.Width || destinationImage.Height != size.Height)
{
throw new InvalidImagePropertiesException("Destination image must have the size expected by the filter.");
}
ProcessFilter(sourceImage, destinationImage);
}
protected abstract Size CalculateNewImageSize(UnmanagedImage sourceData);
protected abstract void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData);
private void CheckSourceFormat(PixelFormat pixelFormat)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
if (!FormatTranslations.ContainsKey(pixelFormat))
{
throw new UnsupportedImageFormatException("Source pixel format is not supported by the filter.");
}
}
}

View File

@@ -0,0 +1,149 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public abstract class BaseUsingCopyPartialFilter : IFilter, IInPlaceFilter, IInPlacePartialFilter, IFilterInformation
{
public abstract Dictionary<PixelFormat, PixelFormat> FormatTranslations { get; }
public Bitmap Apply(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);
Bitmap val2 = null;
try
{
val2 = Apply(val);
if (((Image)image).HorizontalResolution > 0f && ((Image)image).VerticalResolution > 0f)
{
val2.SetResolution(((Image)image).HorizontalResolution, ((Image)image).VerticalResolution);
}
}
finally
{
image.UnlockBits(val);
}
return val2;
}
public Bitmap Apply(BitmapData imageData)
{
//IL_0002: 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_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Invalid comparison between Unknown and I4
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
CheckSourceFormat(imageData.PixelFormat);
int width = imageData.Width;
int height = imageData.Height;
PixelFormat val = FormatTranslations[imageData.PixelFormat];
Bitmap val2 = (Bitmap)(((int)val == 198659) ? ((object)Image.CreateGrayscaleImage(width, height)) : ((object)new Bitmap(width, height, val)));
BitmapData val3 = val2.LockBits(new Rectangle(0, 0, width, height), (ImageLockMode)3, val);
try
{
ProcessFilter(new UnmanagedImage(imageData), new UnmanagedImage(val3), new Rectangle(0, 0, width, height));
}
finally
{
val2.UnlockBits(val3);
}
return val2;
}
public UnmanagedImage Apply(UnmanagedImage image)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
CheckSourceFormat(image.PixelFormat);
UnmanagedImage unmanagedImage = UnmanagedImage.Create(image.Width, image.Height, FormatTranslations[image.PixelFormat]);
ProcessFilter(image, unmanagedImage, new Rectangle(0, 0, image.Width, image.Height));
return unmanagedImage;
}
public void Apply(UnmanagedImage sourceImage, UnmanagedImage destinationImage)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
CheckSourceFormat(sourceImage.PixelFormat);
if (destinationImage.PixelFormat != FormatTranslations[sourceImage.PixelFormat])
{
throw new InvalidImagePropertiesException("Destination pixel format is specified incorrectly.");
}
if (destinationImage.Width != sourceImage.Width || destinationImage.Height != sourceImage.Height)
{
throw new InvalidImagePropertiesException("Destination image must have the same width and height as source image.");
}
ProcessFilter(sourceImage, destinationImage, new Rectangle(0, 0, sourceImage.Width, sourceImage.Height));
}
public void ApplyInPlace(Bitmap image)
{
ApplyInPlace(image, new Rectangle(0, 0, ((Image)image).Width, ((Image)image).Height));
}
public void ApplyInPlace(BitmapData imageData)
{
ApplyInPlace(new UnmanagedImage(imageData), new Rectangle(0, 0, imageData.Width, imageData.Height));
}
public void ApplyInPlace(UnmanagedImage image)
{
ApplyInPlace(image, new Rectangle(0, 0, image.Width, image.Height));
}
public void ApplyInPlace(Bitmap image, Rectangle rect)
{
//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)3, ((Image)image).PixelFormat);
try
{
ApplyInPlace(new UnmanagedImage(val), rect);
}
finally
{
image.UnlockBits(val);
}
}
public void ApplyInPlace(BitmapData imageData, Rectangle rect)
{
ApplyInPlace(new UnmanagedImage(imageData), rect);
}
public void ApplyInPlace(UnmanagedImage image, Rectangle rect)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
CheckSourceFormat(image.PixelFormat);
rect.Intersect(new Rectangle(0, 0, image.Width, image.Height));
if ((rect.Width | rect.Height) != 0)
{
int num = image.Stride * image.Height;
IntPtr intPtr = MemoryManager.Alloc(num);
SystemTools.CopyUnmanagedMemory(intPtr, image.ImageData, num);
ProcessFilter(new UnmanagedImage(intPtr, image.Width, image.Height, image.Stride, image.PixelFormat), image, rect);
MemoryManager.Free(intPtr);
}
}
protected abstract void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData, Rectangle rect);
private void CheckSourceFormat(PixelFormat pixelFormat)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
if (!FormatTranslations.ContainsKey(pixelFormat))
{
throw new UnsupportedImageFormatException("Source pixel format is not supported by the filter.");
}
}
}

View File

@@ -0,0 +1,15 @@
namespace AForge.Imaging.Filters;
public sealed class BayerDithering : OrderedDithering
{
public BayerDithering()
: base(new byte[4, 4]
{
{ 0, 192, 48, 240 },
{ 128, 64, 176, 112 },
{ 32, 224, 16, 208 },
{ 160, 96, 144, 80 }
})
{
}
}

View File

@@ -0,0 +1,149 @@
using System.Collections.Generic;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class BayerFilter : BaseFilter
{
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
private bool performDemosaicing = true;
private int[,] bayerPattern = new int[2, 2]
{
{ 1, 2 },
{ 0, 1 }
};
public bool PerformDemosaicing
{
get
{
return performDemosaicing;
}
set
{
performDemosaicing = value;
}
}
public int[,] BayerPattern
{
get
{
return bayerPattern;
}
set
{
bayerPattern = value;
}
}
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public BayerFilter()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)137224;
}
protected unsafe override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData)
{
int width = sourceData.Width;
int height = sourceData.Height;
int num = width - 1;
int num2 = height - 1;
int stride = sourceData.Stride;
int num3 = stride - width;
int num4 = destinationData.Stride - width * 3;
byte* ptr = (byte*)sourceData.ImageData.ToPointer();
byte* ptr2 = (byte*)destinationData.ImageData.ToPointer();
int[] array = new int[3];
int[] array2 = new int[3];
if (!performDemosaicing)
{
for (int i = 0; i < height; i++)
{
int num5 = 0;
while (num5 < width)
{
ptr2[2] = (ptr2[1] = (*ptr2 = 0));
ptr2[bayerPattern[i & 1, num5 & 1]] = *ptr;
num5++;
ptr++;
ptr2 += 3;
}
ptr += num3;
ptr2 += num4;
}
return;
}
for (int j = 0; j < height; j++)
{
int num6 = 0;
while (num6 < width)
{
array[0] = (array[1] = (array[2] = 0));
array2[0] = (array2[1] = (array2[2] = 0));
int num7 = bayerPattern[j & 1, num6 & 1];
array[num7] += *ptr;
array2[num7]++;
if (num6 != 0)
{
num7 = bayerPattern[j & 1, (num6 - 1) & 1];
array[num7] += ptr[-1];
array2[num7]++;
}
if (num6 != num)
{
num7 = bayerPattern[j & 1, (num6 + 1) & 1];
array[num7] += ptr[1];
array2[num7]++;
}
if (j != 0)
{
num7 = bayerPattern[(j - 1) & 1, num6 & 1];
array[num7] += ptr[-stride];
array2[num7]++;
if (num6 != 0)
{
num7 = bayerPattern[(j - 1) & 1, (num6 - 1) & 1];
array[num7] += ptr[-stride - 1];
array2[num7]++;
}
if (num6 != num)
{
num7 = bayerPattern[(j - 1) & 1, (num6 + 1) & 1];
array[num7] += ptr[-stride + 1];
array2[num7]++;
}
}
if (j != num2)
{
num7 = bayerPattern[(j + 1) & 1, num6 & 1];
array[num7] += ptr[stride];
array2[num7]++;
if (num6 != 0)
{
num7 = bayerPattern[(j + 1) & 1, (num6 - 1) & 1];
array[num7] += ptr[stride - 1];
array2[num7]++;
}
if (num6 != num)
{
num7 = bayerPattern[(j + 1) & 1, (num6 + 1) & 1];
array[num7] += ptr[stride + 1];
array2[num7]++;
}
}
ptr2[2] = (byte)(array[2] / array2[2]);
ptr2[1] = (byte)(array[1] / array2[1]);
*ptr2 = (byte)(array[0] / array2[0]);
num6++;
ptr++;
ptr2 += 3;
}
ptr += num3;
ptr2 += num4;
}
}
}

View File

@@ -0,0 +1,271 @@
using System.Collections.Generic;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class BayerFilterOptimized : BaseFilter
{
private BayerPattern bayerPattern;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public BayerPattern Pattern
{
get
{
return bayerPattern;
}
set
{
bayerPattern = value;
}
}
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public BayerFilterOptimized()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)137224;
}
protected override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData)
{
int width = sourceData.Width;
int height = sourceData.Height;
if ((width & 1) == 1 || (height & 1) == 1 || width < 2 || height < 2)
{
throw new InvalidImagePropertiesException("Source image must have even width and height. Width and height can not be smaller than 2.");
}
switch (bayerPattern)
{
case BayerPattern.GRBG:
ApplyGRBG(sourceData, destinationData);
break;
case BayerPattern.BGGR:
ApplyBGGR(sourceData, destinationData);
break;
}
}
private unsafe void ApplyGRBG(UnmanagedImage sourceData, UnmanagedImage destinationData)
{
int width = sourceData.Width;
int height = sourceData.Height;
int num = width - 1;
int num2 = height - 1;
int stride = sourceData.Stride;
int stride2 = destinationData.Stride;
int num3 = stride + 1;
int num4 = stride - 1;
int num5 = -stride;
int num6 = num5 + 1;
int num7 = num5 - 1;
int num8 = stride - width;
int num9 = stride2 - width * 3;
byte* ptr = (byte*)sourceData.ImageData.ToPointer();
byte* ptr2 = (byte*)destinationData.ImageData.ToPointer();
ptr2[2] = ptr[1];
ptr2[1] = (byte)(*ptr + ptr[num3] >> 1);
*ptr2 = ptr[stride];
ptr++;
ptr2 += 3;
for (int i = 1; i < num; i += 2)
{
ptr2[2] = *ptr;
ptr2[1] = (byte)((ptr[stride] + ptr[-1] + ptr[1]) / 3);
*ptr2 = (byte)(ptr[num4] + ptr[num3] >> 1);
ptr++;
ptr2 += 3;
ptr2[2] = (byte)(ptr[-1] + ptr[1] >> 1);
ptr2[1] = (byte)((*ptr + ptr[num4] + ptr[num3]) / 3);
*ptr2 = ptr[stride];
ptr++;
ptr2 += 3;
}
ptr2[2] = *ptr;
ptr2[1] = (byte)(ptr[-1] + ptr[stride] >> 1);
*ptr2 = ptr[num4];
ptr += num8 + 1;
ptr2 += num9 + 3;
for (int j = 1; j < num2; j += 2)
{
ptr2[2] = (byte)(ptr[num6] + ptr[num3] >> 1);
ptr2[1] = (byte)((ptr[num5] + ptr[stride] + ptr[1]) / 3);
*ptr2 = *ptr;
ptr2 += stride2;
ptr += stride;
ptr2[2] = ptr[1];
ptr2[1] = (byte)((*ptr + ptr[num6] + ptr[num3]) / 3);
*ptr2 = (byte)(ptr[num5] + ptr[stride] >> 1);
ptr2 -= stride2;
ptr -= stride;
ptr++;
ptr2 += 3;
for (int k = 1; k < num; k += 2)
{
ptr2[2] = (byte)(ptr[num5] + ptr[stride] >> 1);
ptr2[1] = (byte)((*ptr + ptr[num7] + ptr[num6] + ptr[num4] + ptr[num3]) / 5);
*ptr2 = (byte)(ptr[-1] + ptr[1] >> 1);
ptr2 += stride2;
ptr += stride;
ptr2[2] = *ptr;
ptr2[1] = (byte)(ptr[num5] + ptr[stride] + ptr[-1] + ptr[1] >> 2);
*ptr2 = (byte)(ptr[num7] + ptr[num6] + ptr[num4] + ptr[num3] >> 2);
ptr2 += 3;
ptr++;
ptr2[2] = (byte)(ptr[-1] + ptr[1] >> 1);
ptr2[1] = (byte)((*ptr + ptr[num7] + ptr[num6] + ptr[num4] + ptr[num3]) / 5);
*ptr2 = (byte)(ptr[num5] + ptr[stride] >> 1);
ptr2 -= stride2;
ptr -= stride;
ptr2[2] = (byte)(ptr[num7] + ptr[num6] + ptr[num4] + ptr[num3] >> 2);
ptr2[1] = (byte)(ptr[num5] + ptr[stride] + ptr[-1] + ptr[1] >> 2);
*ptr2 = *ptr;
ptr2 += 3;
ptr++;
}
ptr2[2] = (byte)(ptr[num5] + ptr[stride] >> 1);
ptr2[1] = (byte)((*ptr + ptr[num7] + ptr[num4]) / 3);
*ptr2 = ptr[-1];
ptr += stride;
ptr2 += stride2;
ptr2[2] = *ptr;
ptr2[1] = (byte)((ptr[num5] + ptr[stride] + ptr[-1]) / 3);
*ptr2 = (byte)(ptr[num7] + ptr[num4] >> 1);
ptr += num8 + 1;
ptr2 += num9 + 3;
}
ptr2[2] = ptr[num6];
ptr2[1] = (byte)(ptr[num5] + ptr[1] >> 1);
*ptr2 = *ptr;
ptr++;
ptr2 += 3;
for (int l = 1; l < num; l += 2)
{
ptr2[2] = ptr[num5];
ptr2[1] = (byte)((ptr[num7] + ptr[num6] + *ptr) / 3);
*ptr2 = (byte)(ptr[-1] + ptr[1] >> 1);
ptr++;
ptr2 += 3;
ptr2[2] = (byte)(ptr[num7] + ptr[num6] >> 1);
ptr2[1] = (byte)((ptr[num5] + ptr[-1] + ptr[1]) / 3);
*ptr2 = *ptr;
ptr++;
ptr2 += 3;
}
ptr2[2] = ptr[num5];
ptr2[1] = (byte)(*ptr + ptr[num7] >> 1);
*ptr2 = ptr[-1];
}
private unsafe void ApplyBGGR(UnmanagedImage sourceData, UnmanagedImage destinationData)
{
int width = sourceData.Width;
int height = sourceData.Height;
int num = width - 1;
int num2 = height - 1;
int stride = sourceData.Stride;
int stride2 = destinationData.Stride;
int num3 = stride + 1;
int num4 = stride - 1;
int num5 = -stride;
int num6 = num5 + 1;
int num7 = num5 - 1;
int num8 = stride - width;
int num9 = stride2 - width * 3;
byte* ptr = (byte*)sourceData.ImageData.ToPointer();
byte* ptr2 = (byte*)destinationData.ImageData.ToPointer();
ptr2[2] = ptr[num3];
ptr2[1] = (byte)(ptr[1] + ptr[stride] >> 1);
*ptr2 = *ptr;
ptr++;
ptr2 += 3;
for (int i = 1; i < num; i += 2)
{
ptr2[2] = ptr[stride];
ptr2[1] = (byte)((*ptr + ptr[num4] + ptr[num3]) / 3);
*ptr2 = (byte)(ptr[-1] + ptr[1] >> 1);
ptr++;
ptr2 += 3;
ptr2[2] = (byte)(ptr[num4] + ptr[num3] >> 1);
ptr2[1] = (byte)((ptr[-1] + ptr[stride] + ptr[1]) / 3);
*ptr2 = *ptr;
ptr++;
ptr2 += 3;
}
ptr2[2] = ptr[stride];
ptr2[1] = (byte)(*ptr + ptr[num4] >> 1);
*ptr2 = ptr[-1];
ptr += num8 + 1;
ptr2 += num9 + 3;
for (int j = 1; j < num2; j += 2)
{
ptr2[2] = ptr[1];
ptr2[1] = (byte)((ptr[num6] + ptr[num3] + *ptr) / 3);
*ptr2 = (byte)(ptr[num5] + ptr[stride] >> 1);
ptr2 += stride2;
ptr += stride;
ptr2[2] = (byte)(ptr[num6] + ptr[num3] >> 1);
ptr2[1] = (byte)((ptr[1] + ptr[num5] + ptr[stride]) / 3);
*ptr2 = *ptr;
ptr2 -= stride2;
ptr -= stride;
ptr++;
ptr2 += 3;
for (int k = 1; k < num; k += 2)
{
ptr2[2] = *ptr;
ptr2[1] = (byte)(ptr[num5] + ptr[stride] + ptr[-1] + ptr[1] >> 2);
*ptr2 = (byte)(ptr[num7] + ptr[num6] + ptr[num4] + ptr[num3] >> 2);
ptr2 += stride2;
ptr += stride;
ptr2[2] = (byte)(ptr[num5] + ptr[stride] >> 1);
ptr2[1] = (byte)((*ptr + ptr[num7] + ptr[num6] + ptr[num4] + ptr[num3]) / 5);
*ptr2 = (byte)(ptr[-1] + ptr[1] >> 1);
ptr2 += 3;
ptr++;
ptr2[2] = (byte)(ptr[num7] + ptr[num6] + ptr[num4] + ptr[num3] >> 2);
ptr2[1] = (byte)(ptr[num5] + ptr[stride] + ptr[-1] + ptr[1] >> 2);
*ptr2 = *ptr;
ptr2 -= stride2;
ptr -= stride;
ptr2[2] = (byte)(ptr[-1] + ptr[1] >> 1);
ptr2[1] = (byte)((ptr[num7] + ptr[num6] + ptr[num4] + ptr[num3] + *ptr) / 5);
*ptr2 = (byte)(ptr[num5] + ptr[stride] >> 1);
ptr2 += 3;
ptr++;
}
ptr2[2] = *ptr;
ptr2[1] = (byte)((ptr[num5] + ptr[stride] + ptr[-1]) / 3);
*ptr2 = (byte)(ptr[num7] + ptr[num4] >> 1);
ptr += stride;
ptr2 += stride2;
ptr2[2] = (byte)(ptr[num5] + ptr[stride] >> 1);
ptr2[1] = (byte)((ptr[num7] + ptr[num4] + *ptr) / 3);
*ptr2 = ptr[-1];
ptr += num8 + 1;
ptr2 += num9 + 3;
}
ptr2[2] = ptr[1];
ptr2[1] = (byte)(ptr[num6] + *ptr >> 1);
*ptr2 = ptr[num5];
ptr++;
ptr2 += 3;
for (int l = 1; l < num; l += 2)
{
ptr2[2] = *ptr;
ptr2[1] = (byte)((ptr[-1] + ptr[1] + ptr[num5]) / 3);
*ptr2 = (byte)(ptr[num7] + ptr[num6] >> 1);
ptr++;
ptr2 += 3;
ptr2[2] = (byte)(ptr[-1] + ptr[1] >> 1);
ptr2[1] = (byte)((*ptr + ptr[num7] + ptr[num6]) / 3);
*ptr2 = ptr[num5];
ptr++;
ptr2 += 3;
}
ptr2[2] = *ptr;
ptr2[1] = (byte)(ptr[num5] + ptr[-1] >> 1);
*ptr2 = ptr[num7];
}
}

View File

@@ -0,0 +1,7 @@
namespace AForge.Imaging.Filters;
public enum BayerPattern
{
GRBG,
BGGR
}

View File

@@ -0,0 +1,581 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class BilateralSmoothing : BaseUsingCopyPartialFilter
{
private const int maxKernelSize = 255;
private const int colorsCount = 256;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
private int kernelSize = 9;
private double spatialFactor = 10.0;
private double spatialPower = 2.0;
private double colorFactor = 50.0;
private double colorPower = 2.0;
private bool spatialPropertiesChanged = true;
private bool colorPropertiesChanged = true;
private bool limitKernelSize = true;
private bool enableParallelProcessing;
private double[,] spatialFunc;
private double[,] colorFunc;
public bool LimitKernelSize
{
get
{
return limitKernelSize;
}
set
{
limitKernelSize = value;
}
}
public bool EnableParallelProcessing
{
get
{
return enableParallelProcessing;
}
set
{
enableParallelProcessing = value;
}
}
public int KernelSize
{
get
{
return kernelSize;
}
set
{
if (value > 255)
{
throw new ArgumentOutOfRangeException("Maximum allowed value of KernelSize property is " + 255);
}
if (limitKernelSize && value > 25)
{
throw new ArgumentOutOfRangeException("KernerlSize is larger then 25. Time for applying is significant and may lead to application freezing. In order to use any KernelSize value set property 'LimitKernelSize' to false.");
}
if (value < 3)
{
throw new ArgumentOutOfRangeException("KernelSize must be greater than 3");
}
if (value % 2 == 0)
{
throw new ArgumentException("KernerlSize must be an odd integer.");
}
kernelSize = value;
}
}
public double SpatialFactor
{
get
{
return spatialFactor;
}
set
{
spatialFactor = System.Math.Max(1.0, value);
spatialPropertiesChanged = true;
}
}
public double SpatialPower
{
get
{
return spatialPower;
}
set
{
spatialPower = System.Math.Max(1.0, value);
spatialPropertiesChanged = true;
}
}
public double ColorFactor
{
get
{
return colorFactor;
}
set
{
colorFactor = System.Math.Max(1.0, value);
colorPropertiesChanged = true;
}
}
public double ColorPower
{
get
{
return colorPower;
}
set
{
colorPower = System.Math.Max(1.0, value);
colorPropertiesChanged = true;
}
}
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public BilateralSmoothing()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
}
private void InitSpatialFunc()
{
if (spatialFunc != null && spatialFunc.Length == kernelSize * kernelSize && !spatialPropertiesChanged)
{
return;
}
if (spatialFunc == null || spatialFunc.Length != kernelSize * kernelSize)
{
spatialFunc = new double[kernelSize, kernelSize];
}
int num = kernelSize / 2;
for (int i = 0; i < kernelSize; i++)
{
int num2 = i - num;
int num3 = num2 * num2;
for (int j = 0; j < kernelSize; j++)
{
int num4 = j - num;
int num5 = num4 * num4;
spatialFunc[i, j] = System.Math.Exp(-0.5 * System.Math.Pow(System.Math.Sqrt((double)(num3 + num5) / spatialFactor), spatialPower));
}
}
spatialPropertiesChanged = false;
}
private void InitColorFunc()
{
if (colorFunc != null && !colorPropertiesChanged)
{
return;
}
if (colorFunc == null)
{
colorFunc = new double[256, 256];
}
for (int i = 0; i < 256; i++)
{
for (int j = 0; j < 256; j++)
{
colorFunc[i, j] = System.Math.Exp(-0.5 * System.Math.Pow((double)System.Math.Abs(i - j) / colorFactor, colorPower));
}
}
colorPropertiesChanged = false;
}
private void InitFilter()
{
InitSpatialFunc();
InitColorFunc();
}
protected override void ProcessFilter(UnmanagedImage source, UnmanagedImage destination, Rectangle rect)
{
int num = kernelSize / 2;
InitFilter();
if (rect.Width <= kernelSize || rect.Height <= kernelSize)
{
ProcessWithEdgeChecks(source, destination, rect);
return;
}
Rectangle rect2 = rect;
rect2.Inflate(-num, -num);
if (Environment.ProcessorCount > 1 && enableParallelProcessing)
{
ProcessWithoutChecksParallel(source, destination, rect2);
}
else
{
ProcessWithoutChecks(source, destination, rect2);
}
ProcessWithEdgeChecks(source, destination, new Rectangle(rect.Left, rect.Top, rect.Width, num));
ProcessWithEdgeChecks(source, destination, new Rectangle(rect.Left, rect.Bottom - num, rect.Width, num));
ProcessWithEdgeChecks(source, destination, new Rectangle(rect.Left, rect.Top + num, num, rect.Height - num * 2));
ProcessWithEdgeChecks(source, destination, new Rectangle(rect.Right - num, rect.Top + num, num, rect.Height - num * 2));
}
private unsafe void ProcessWithoutChecksParallel(UnmanagedImage source, UnmanagedImage destination, Rectangle rect)
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
int startX = rect.Left;
int top = rect.Top;
int stopX = rect.Right;
int bottom = rect.Bottom;
int pixelSize = Image.GetPixelFormatSize(source.PixelFormat) / 8;
int num = kernelSize / 2;
int num2 = kernelSize * pixelSize;
int srcStride = source.Stride;
int dstStride = destination.Stride;
_ = srcStride;
_ = rect.Width;
_ = pixelSize;
_ = dstStride;
_ = rect.Width;
_ = pixelSize;
int srcKernelFistPixelOffset = num * (srcStride + pixelSize);
int srcKernelOffset = srcStride - num2;
byte* srcBase = (byte*)source.ImageData.ToPointer();
byte* dstBase = (byte*)destination.ImageData.ToPointer();
srcBase += (nint)startX * (nint)pixelSize;
dstBase += (nint)startX * (nint)pixelSize;
if (pixelSize > 1)
{
Parallel.For(top, bottom, delegate(int y)
{
byte* ptr = srcBase + (nint)y * (nint)srcStride;
byte* ptr2 = dstBase + (nint)y * (nint)dstStride;
int num3 = startX;
while (num3 < stopX)
{
byte* ptr3 = ptr + srcKernelFistPixelOffset;
double num4 = 0.0;
double num5 = 0.0;
double num6 = 0.0;
double num7 = 0.0;
double num8 = 0.0;
double num9 = 0.0;
byte b = ptr[2];
byte b2 = ptr[1];
byte b3 = *ptr;
int num10 = kernelSize;
while (num10 != 0)
{
num10--;
int num11 = kernelSize;
while (num11 != 0)
{
num11--;
byte b4 = ptr3[2];
byte b5 = ptr3[1];
byte b6 = *ptr3;
double num12 = spatialFunc[num11, num10] * colorFunc[b4, b];
double num13 = spatialFunc[num11, num10] * colorFunc[b5, b2];
double num14 = spatialFunc[num11, num10] * colorFunc[b6, b3];
num4 += num12;
num5 += num13;
num6 += num14;
num7 += num12 * (double)(int)b4;
num8 += num13 * (double)(int)b5;
num9 += num14 * (double)(int)b6;
ptr3 -= pixelSize;
}
ptr3 -= srcKernelOffset;
}
ptr2[2] = (byte)(num7 / num4);
ptr2[1] = (byte)(num8 / num5);
*ptr2 = (byte)(num9 / num6);
num3++;
ptr += pixelSize;
ptr2 += pixelSize;
}
});
return;
}
Parallel.For(top, bottom, delegate(int y)
{
byte* ptr = srcBase + (nint)y * (nint)srcStride;
byte* ptr2 = dstBase + (nint)y * (nint)dstStride;
int num3 = startX;
while (num3 < stopX)
{
byte* ptr3 = ptr + srcKernelFistPixelOffset;
double num4 = 0.0;
double num5 = 0.0;
byte b = *ptr;
int num6 = kernelSize;
while (num6 != 0)
{
num6--;
int num7 = kernelSize;
while (num7 != 0)
{
num7--;
byte b2 = *ptr3;
double num8 = spatialFunc[num7, num6] * colorFunc[b2, b];
num4 += num8;
num5 += num8 * (double)(int)b2;
ptr3 -= pixelSize;
}
ptr3 -= srcKernelOffset;
}
*ptr2 = (byte)(num5 / num4);
num3++;
ptr++;
ptr2++;
}
});
}
private unsafe void ProcessWithoutChecks(UnmanagedImage source, UnmanagedImage destination, Rectangle rect)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
int left = rect.Left;
int top = rect.Top;
int right = rect.Right;
int bottom = rect.Bottom;
int num = Image.GetPixelFormatSize(source.PixelFormat) / 8;
int num2 = kernelSize / 2;
int num3 = kernelSize * num;
int stride = source.Stride;
int stride2 = destination.Stride;
int num4 = stride - rect.Width * num;
int num5 = stride2 - rect.Width * num;
int num6 = num2 * (stride + num);
int num7 = stride - num3;
byte* ptr = (byte*)source.ImageData.ToPointer();
byte* ptr2 = (byte*)destination.ImageData.ToPointer();
ptr += top * stride + left * num;
ptr2 += top * stride2 + left * num;
if (num > 1)
{
for (int i = top; i < bottom; i++)
{
int num8 = left;
while (num8 < right)
{
byte* ptr3 = ptr + num6;
double num9 = 0.0;
double num10 = 0.0;
double num11 = 0.0;
double num12 = 0.0;
double num13 = 0.0;
double num14 = 0.0;
byte b = ptr[2];
byte b2 = ptr[1];
byte b3 = *ptr;
int num15 = kernelSize;
while (num15 != 0)
{
num15--;
int num16 = kernelSize;
while (num16 != 0)
{
num16--;
byte b4 = ptr3[2];
byte b5 = ptr3[1];
byte b6 = *ptr3;
double num17 = spatialFunc[num16, num15] * colorFunc[b4, b];
double num18 = spatialFunc[num16, num15] * colorFunc[b5, b2];
double num19 = spatialFunc[num16, num15] * colorFunc[b6, b3];
num9 += num17;
num10 += num18;
num11 += num19;
num12 += num17 * (double)(int)b4;
num13 += num18 * (double)(int)b5;
num14 += num19 * (double)(int)b6;
ptr3 -= num;
}
ptr3 -= num7;
}
ptr2[2] = (byte)(num12 / num9);
ptr2[1] = (byte)(num13 / num10);
*ptr2 = (byte)(num14 / num11);
num8++;
ptr += num;
ptr2 += num;
}
ptr += num4;
ptr2 += num5;
}
return;
}
for (int j = top; j < bottom; j++)
{
int num20 = left;
while (num20 < right)
{
byte* ptr4 = ptr + num6;
double num21 = 0.0;
double num22 = 0.0;
byte b7 = *ptr;
int num15 = kernelSize;
while (num15 != 0)
{
num15--;
int num16 = kernelSize;
while (num16 != 0)
{
num16--;
byte b8 = *ptr4;
double num23 = spatialFunc[num16, num15] * colorFunc[b8, b7];
num21 += num23;
num22 += num23 * (double)(int)b8;
ptr4 -= num;
}
ptr4 -= num7;
}
*ptr2 = (byte)(num22 / num21);
num20++;
ptr++;
ptr2++;
}
ptr += num4;
ptr2 += num5;
}
}
private unsafe void ProcessWithEdgeChecks(UnmanagedImage source, UnmanagedImage destination, Rectangle rect)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
int width = source.Width;
int height = source.Height;
int left = rect.Left;
int top = rect.Top;
int right = rect.Right;
int bottom = rect.Bottom;
int num = Image.GetPixelFormatSize(source.PixelFormat) / 8;
int num2 = kernelSize / 2;
int num3 = kernelSize * num;
int stride = source.Stride;
int stride2 = destination.Stride;
int num4 = stride - rect.Width * num;
int num5 = stride2 - rect.Width * num;
int num6 = num2 * (stride + num);
int num7 = stride - num3;
byte* ptr = (byte*)source.ImageData.ToPointer();
byte* ptr2 = (byte*)destination.ImageData.ToPointer();
ptr += top * stride + left * num;
ptr2 += top * stride2 + left * num;
if (num > 1)
{
for (int i = top; i < bottom; i++)
{
int num8 = left;
while (num8 < right)
{
byte* ptr3 = ptr + num6;
double num9 = 0.0;
double num10 = 0.0;
double num11 = 0.0;
double num12 = 0.0;
double num13 = 0.0;
double num14 = 0.0;
byte b = ptr[2];
byte b2 = ptr[1];
byte b3 = *ptr;
int num15 = kernelSize;
while (num15 != 0)
{
num15--;
int num16 = num15 - num2;
if (num16 + i >= height || num16 + i < 0)
{
ptr3 -= stride;
continue;
}
int num17 = kernelSize;
while (num17 != 0)
{
num17--;
int num18 = num17 - num2;
if (num18 + num8 >= width || num18 + num8 < 0)
{
ptr3 -= num;
continue;
}
byte b4 = ptr3[2];
byte b5 = ptr3[1];
byte b6 = *ptr3;
double num19 = spatialFunc[num17, num15] * colorFunc[b4, b];
double num20 = spatialFunc[num17, num15] * colorFunc[b5, b2];
double num21 = spatialFunc[num17, num15] * colorFunc[b6, b3];
num9 += num19;
num10 += num20;
num11 += num21;
num12 += num19 * (double)(int)b4;
num13 += num20 * (double)(int)b5;
num14 += num21 * (double)(int)b6;
ptr3 -= num;
}
ptr3 -= num7;
}
ptr2[2] = (byte)(num12 / num9);
ptr2[1] = (byte)(num13 / num10);
*ptr2 = (byte)(num14 / num11);
num8++;
ptr += num;
ptr2 += num;
}
ptr += num4;
ptr2 += num5;
}
return;
}
for (int j = top; j < bottom; j++)
{
int num22 = left;
while (num22 < right)
{
byte* ptr4 = ptr + num6;
double num23 = 0.0;
double num24 = 0.0;
byte b7 = *ptr;
int num15 = kernelSize;
while (num15 != 0)
{
num15--;
int num16 = num15 - num2;
if (num16 + j >= height || num16 + j < 0)
{
ptr4 -= stride;
continue;
}
int num17 = kernelSize;
while (num17 != 0)
{
num17--;
int num18 = num17 - num2;
if (num18 + num22 >= source.Width || num18 + num22 < 0)
{
ptr4 -= num;
continue;
}
byte b8 = *ptr4;
double num25 = spatialFunc[num17, num15] * colorFunc[b8, b7];
num23 += num25;
num24 += num25 * (double)(int)b8;
ptr4 -= num;
}
ptr4 -= num7;
}
*ptr2 = (byte)(num24 / num23);
num22++;
ptr++;
ptr2++;
}
ptr += num4;
ptr2 += num5;
}
}
}

View File

@@ -0,0 +1,80 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class BinaryDilatation3x3 : BaseUsingCopyPartialFilter
{
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public BinaryDilatation3x3()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
}
protected unsafe override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData, Rectangle rect)
{
if (rect.Width < 3 || rect.Height < 3)
{
throw new InvalidImagePropertiesException("Processing rectangle mast be at least 3x3 in size.");
}
int num = rect.Left + 1;
int num2 = rect.Top + 1;
int num3 = rect.Right - 1;
int num4 = rect.Bottom - 1;
int stride = destinationData.Stride;
int stride2 = sourceData.Stride;
int num5 = stride - rect.Width + 1;
int num6 = stride2 - rect.Width + 1;
byte* ptr = (byte*)sourceData.ImageData.ToPointer();
byte* ptr2 = (byte*)destinationData.ImageData.ToPointer();
ptr += num - 1 + (num2 - 1) * stride2;
ptr2 += num - 1 + (num2 - 1) * stride;
*ptr2 = (byte)(*ptr | ptr[1] | ptr[stride2] | ptr[stride2 + 1]);
ptr++;
ptr2++;
int num7 = num;
while (num7 < num3)
{
*ptr2 = (byte)(*ptr | ptr[-1] | ptr[1] | ptr[stride2] | ptr[stride2 - 1] | ptr[stride2 + 1]);
num7++;
ptr++;
ptr2++;
}
*ptr2 = (byte)(*ptr | ptr[-1] | ptr[stride2] | ptr[stride2 - 1]);
ptr += num6;
ptr2 += num5;
for (int i = num2; i < num4; i++)
{
*ptr2 = (byte)(*ptr | ptr[1] | ptr[-stride2] | ptr[-stride2 + 1] | ptr[stride2] | ptr[stride2 + 1]);
ptr++;
ptr2++;
int num8 = num;
while (num8 < num3)
{
*ptr2 = (byte)(*ptr | ptr[-1] | ptr[1] | ptr[-stride2] | ptr[-stride2 - 1] | ptr[-stride2 + 1] | ptr[stride2] | ptr[stride2 - 1] | ptr[stride2 + 1]);
num8++;
ptr++;
ptr2++;
}
*ptr2 = (byte)(*ptr | ptr[-1] | ptr[-stride2] | ptr[-stride2 - 1] | ptr[stride2] | ptr[stride2 - 1]);
ptr += num6;
ptr2 += num5;
}
*ptr2 = (byte)(*ptr | ptr[1] | ptr[-stride2] | ptr[-stride2 + 1]);
ptr++;
ptr2++;
int num9 = num;
while (num9 < num3)
{
*ptr2 = (byte)(*ptr | ptr[-1] | ptr[1] | ptr[-stride2] | ptr[-stride2 - 1] | ptr[-stride2 + 1]);
num9++;
ptr++;
ptr2++;
}
*ptr2 = (byte)(*ptr | ptr[-1] | ptr[-stride2] | ptr[-stride2 - 1]);
}
}

View File

@@ -0,0 +1,74 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class BinaryErosion3x3 : BaseUsingCopyPartialFilter
{
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public BinaryErosion3x3()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
}
protected unsafe override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData, Rectangle rect)
{
if (rect.Width < 3 || rect.Height < 3)
{
throw new InvalidImagePropertiesException("Processing rectangle mast be at least 3x3 in size.");
}
int num = rect.Left + 1;
int num2 = rect.Top + 1;
int num3 = rect.Right - 1;
int num4 = rect.Bottom - 1;
int stride = destinationData.Stride;
int stride2 = sourceData.Stride;
int num5 = stride - rect.Width + 1;
int num6 = stride2 - rect.Width + 1;
byte* ptr = (byte*)sourceData.ImageData.ToPointer();
byte* ptr2 = (byte*)destinationData.ImageData.ToPointer();
ptr += num - 1 + (num2 - 1) * stride2;
ptr2 += num - 1 + (num2 - 1) * stride;
int num7 = num - 1;
while (num7 < num3)
{
*ptr2 = 0;
num7++;
ptr++;
ptr2++;
}
*ptr2 = 0;
ptr += num6;
ptr2 += num5;
for (int i = num2; i < num4; i++)
{
*ptr2 = 0;
ptr++;
ptr2++;
int num8 = num;
while (num8 < num3)
{
*ptr2 = (byte)(*ptr & ptr[-1] & ptr[1] & ptr[-stride2] & ptr[-stride2 - 1] & ptr[-stride2 + 1] & ptr[stride2] & ptr[stride2 - 1] & ptr[stride2 + 1]);
num8++;
ptr++;
ptr2++;
}
*ptr2 = 0;
ptr += num6;
ptr2 += num5;
}
int num9 = num - 1;
while (num9 < num3)
{
*ptr2 = 0;
num9++;
ptr++;
ptr2++;
}
*ptr2 = 0;
}
}

View File

@@ -0,0 +1,173 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class BlobsFiltering : BaseInPlaceFilter
{
private BlobCounter blobCounter = new BlobCounter();
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public bool CoupledSizeFiltering
{
get
{
return blobCounter.CoupledSizeFiltering;
}
set
{
blobCounter.CoupledSizeFiltering = value;
}
}
public int MinWidth
{
get
{
return blobCounter.MinWidth;
}
set
{
blobCounter.MinWidth = value;
}
}
public int MinHeight
{
get
{
return blobCounter.MinHeight;
}
set
{
blobCounter.MinHeight = value;
}
}
public int MaxWidth
{
get
{
return blobCounter.MaxWidth;
}
set
{
blobCounter.MaxWidth = value;
}
}
public int MaxHeight
{
get
{
return blobCounter.MaxHeight;
}
set
{
blobCounter.MaxHeight = value;
}
}
public IBlobsFilter BlobsFilter
{
get
{
return blobCounter.BlobsFilter;
}
set
{
blobCounter.BlobsFilter = value;
}
}
public BlobsFiltering()
{
blobCounter.FilterBlobs = true;
blobCounter.MinWidth = 1;
blobCounter.MinHeight = 1;
blobCounter.MaxWidth = int.MaxValue;
blobCounter.MaxHeight = int.MaxValue;
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
formatTranslations[(PixelFormat)925707] = (PixelFormat)925707;
}
public BlobsFiltering(int minWidth, int minHeight, int maxWidth, int maxHeight)
: this(minWidth, minHeight, maxWidth, maxHeight, coupledSizeFiltering: false)
{
}
public BlobsFiltering(int minWidth, int minHeight, int maxWidth, int maxHeight, bool coupledSizeFiltering)
: this()
{
blobCounter.MinWidth = minWidth;
blobCounter.MinHeight = minHeight;
blobCounter.MaxWidth = maxWidth;
blobCounter.MaxHeight = maxHeight;
blobCounter.CoupledSizeFiltering = coupledSizeFiltering;
}
public BlobsFiltering(IBlobsFilter blobsFilter)
: this()
{
blobCounter.BlobsFilter = blobsFilter;
}
protected unsafe override void ProcessFilter(UnmanagedImage image)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Invalid comparison between Unknown and I4
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
blobCounter.ProcessImage(image);
int[] objectLabels = blobCounter.ObjectLabels;
int width = image.Width;
int height = image.Height;
byte* ptr = (byte*)image.ImageData.ToPointer();
if ((int)image.PixelFormat == 198659)
{
int num = image.Stride - width;
int i = 0;
int num2 = 0;
for (; i < height; i++)
{
int num3 = 0;
while (num3 < width)
{
if (objectLabels[num2] == 0)
{
*ptr = 0;
}
num3++;
ptr++;
num2++;
}
ptr += num;
}
return;
}
int num4 = Image.GetPixelFormatSize(image.PixelFormat) / 8;
int num5 = image.Stride - width * num4;
int j = 0;
int num6 = 0;
for (; j < height; j++)
{
int num7 = 0;
while (num7 < width)
{
if (objectLabels[num6] == 0)
{
ptr[2] = (ptr[1] = (*ptr = 0));
}
num7++;
ptr += num4;
num6++;
}
ptr += num5;
}
}
}

View File

@@ -0,0 +1,17 @@
namespace AForge.Imaging.Filters;
public sealed class Blur : Convolution
{
public Blur()
: base(new int[5, 5]
{
{ 1, 2, 3, 2, 1 },
{ 2, 4, 5, 4, 2 },
{ 3, 5, 6, 5, 3 },
{ 2, 4, 5, 4, 2 },
{ 1, 2, 3, 2, 1 }
})
{
base.ProcessAlpha = true;
}
}

View File

@@ -0,0 +1,38 @@
using System.Collections.Generic;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class BottomHat : BaseInPlaceFilter
{
private Closing closing = new Closing();
private Subtract subtract = new Subtract();
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public BottomHat()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)1052676] = (PixelFormat)1052676;
formatTranslations[(PixelFormat)1060876] = (PixelFormat)1060876;
}
public BottomHat(short[,] se)
: this()
{
closing = new Closing(se);
}
protected override void ProcessFilter(UnmanagedImage image)
{
UnmanagedImage unmanagedImage = image.Clone();
closing.ApplyInPlace(image);
subtract.UnmanagedOverlayImage = unmanagedImage;
subtract.ApplyInPlace(image);
unmanagedImage.Dispose();
}
}

View File

@@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class BradleyLocalThresholding : BaseInPlaceFilter
{
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
private int windowSize = 41;
private float pixelBrightnessDifferenceLimit = 0.15f;
public int WindowSize
{
get
{
return windowSize;
}
set
{
windowSize = System.Math.Max(3, value | 1);
}
}
public float PixelBrightnessDifferenceLimit
{
get
{
return pixelBrightnessDifferenceLimit;
}
set
{
pixelBrightnessDifferenceLimit = System.Math.Max(0f, System.Math.Min(1f, value));
}
}
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public BradleyLocalThresholding()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
}
protected unsafe override void ProcessFilter(UnmanagedImage image)
{
IntegralImage integralImage = IntegralImage.FromBitmap(image);
int width = image.Width;
int height = image.Height;
int num = width - 1;
int num2 = height - 1;
int num3 = image.Stride - width;
int num4 = windowSize / 2;
float num5 = 1f - pixelBrightnessDifferenceLimit;
byte* ptr = (byte*)image.ImageData.ToPointer();
for (int i = 0; i < height; i++)
{
int num6 = i - num4;
int num7 = i + num4;
if (num6 < 0)
{
num6 = 0;
}
if (num7 > num2)
{
num7 = num2;
}
int num8 = 0;
while (num8 < width)
{
int num9 = num8 - num4;
int num10 = num8 + num4;
if (num9 < 0)
{
num9 = 0;
}
if (num10 > num)
{
num10 = num;
}
*ptr = (byte)((*ptr >= (int)(integralImage.GetRectangleMeanUnsafe(num9, num6, num10, num7) * num5)) ? 255u : 0u);
num8++;
ptr++;
}
ptr += num3;
}
}
}

View File

@@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class BrightnessCorrection : BaseInPlacePartialFilter
{
private LevelsLinear baseFilter = new LevelsLinear();
private int adjustValue;
public int AdjustValue
{
get
{
return adjustValue;
}
set
{
adjustValue = System.Math.Max(-255, System.Math.Min(255, value));
if (adjustValue > 0)
{
LevelsLinear levelsLinear = baseFilter;
LevelsLinear levelsLinear2 = baseFilter;
LevelsLinear levelsLinear3 = baseFilter;
IntRange intRange = (baseFilter.InGray = new IntRange(0, 255 - adjustValue));
IntRange intRange3 = (levelsLinear3.InBlue = intRange);
IntRange inRed = (levelsLinear2.InGreen = intRange3);
levelsLinear.InRed = inRed;
LevelsLinear levelsLinear4 = baseFilter;
LevelsLinear levelsLinear5 = baseFilter;
LevelsLinear levelsLinear6 = baseFilter;
IntRange intRange6 = (baseFilter.OutGray = new IntRange(adjustValue, 255));
IntRange intRange8 = (levelsLinear6.OutBlue = intRange6);
IntRange outRed = (levelsLinear5.OutGreen = intRange8);
levelsLinear4.OutRed = outRed;
}
else
{
LevelsLinear levelsLinear7 = baseFilter;
LevelsLinear levelsLinear8 = baseFilter;
LevelsLinear levelsLinear9 = baseFilter;
IntRange intRange11 = (baseFilter.InGray = new IntRange(-adjustValue, 255));
IntRange intRange13 = (levelsLinear9.InBlue = intRange11);
IntRange inRed2 = (levelsLinear8.InGreen = intRange13);
levelsLinear7.InRed = inRed2;
LevelsLinear levelsLinear10 = baseFilter;
LevelsLinear levelsLinear11 = baseFilter;
LevelsLinear levelsLinear12 = baseFilter;
IntRange intRange16 = (baseFilter.OutGray = new IntRange(0, 255 + adjustValue));
IntRange intRange18 = (levelsLinear12.OutBlue = intRange16);
IntRange outRed2 = (levelsLinear11.OutGreen = intRange18);
levelsLinear10.OutRed = outRed2;
}
}
}
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => baseFilter.FormatTranslations;
public BrightnessCorrection()
{
AdjustValue = 10;
}
public BrightnessCorrection(int adjustValue)
{
AdjustValue = adjustValue;
}
protected override void ProcessFilter(UnmanagedImage image, Rectangle rect)
{
baseFilter.ApplyInPlace(image, rect);
}
}

View File

@@ -0,0 +1,13 @@
namespace AForge.Imaging.Filters;
public sealed class BurkesDithering : ErrorDiffusionToAdjacentNeighbors
{
public BurkesDithering()
: base(new int[2][]
{
new int[2] { 8, 4 },
new int[5] { 2, 4, 8, 4, 2 }
})
{
}
}

View File

@@ -0,0 +1,207 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class CannyEdgeDetector : BaseUsingCopyPartialFilter
{
private GaussianBlur gaussianFilter = new GaussianBlur();
private byte lowThreshold = 20;
private byte highThreshold = 100;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public byte LowThreshold
{
get
{
return lowThreshold;
}
set
{
lowThreshold = value;
}
}
public byte HighThreshold
{
get
{
return highThreshold;
}
set
{
highThreshold = value;
}
}
public double GaussianSigma
{
get
{
return gaussianFilter.Sigma;
}
set
{
gaussianFilter.Sigma = value;
}
}
public int GaussianSize
{
get
{
return gaussianFilter.Size;
}
set
{
gaussianFilter.Size = value;
}
}
public CannyEdgeDetector()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
}
public CannyEdgeDetector(byte lowThreshold, byte highThreshold)
: this()
{
this.lowThreshold = lowThreshold;
this.highThreshold = highThreshold;
}
public CannyEdgeDetector(byte lowThreshold, byte highThreshold, double sigma)
: this()
{
this.lowThreshold = lowThreshold;
this.highThreshold = highThreshold;
gaussianFilter.Sigma = sigma;
}
protected unsafe override void ProcessFilter(UnmanagedImage source, UnmanagedImage destination, Rectangle rect)
{
int num = rect.Left + 1;
int num2 = rect.Top + 1;
int num3 = num + rect.Width - 2;
int num4 = num2 + rect.Height - 2;
int num5 = rect.Width - 2;
int num6 = rect.Height - 2;
int stride = destination.Stride;
int stride2 = source.Stride;
int num7 = stride - rect.Width + 2;
int num8 = stride2 - rect.Width + 2;
double num9 = 180.0 / System.Math.PI;
float num10 = 0f;
float num11 = 0f;
UnmanagedImage unmanagedImage = gaussianFilter.Apply(source);
byte[] array = new byte[num5 * num6];
float[,] array2 = new float[source.Width, source.Height];
float num12 = float.NegativeInfinity;
byte* ptr = (byte*)unmanagedImage.ImageData.ToPointer();
ptr += stride2 * num2 + num;
int num13 = 0;
for (int i = num2; i < num4; i++)
{
int num14 = num;
while (num14 < num3)
{
int num15 = ptr[-stride2 + 1] + ptr[stride2 + 1] - ptr[-stride2 - 1] - ptr[stride2 - 1] + 2 * (ptr[1] - ptr[-1]);
int num16 = ptr[-stride2 - 1] + ptr[-stride2 + 1] - ptr[stride2 - 1] - ptr[stride2 + 1] + 2 * (ptr[-stride2] - ptr[stride2]);
array2[num14, i] = (float)System.Math.Sqrt(num15 * num15 + num16 * num16);
if (array2[num14, i] > num12)
{
num12 = array2[num14, i];
}
double num17;
if (num15 == 0)
{
num17 = ((num16 != 0) ? 90 : 0);
}
else
{
double num18 = (double)num16 / (double)num15;
num17 = ((!(num18 < 0.0)) ? (System.Math.Atan(num18) * num9) : (180.0 - System.Math.Atan(0.0 - num18) * num9));
num17 = ((!(num17 < 22.5)) ? ((!(num17 < 67.5)) ? ((!(num17 < 112.5)) ? ((!(num17 < 157.5)) ? 0.0 : 135.0) : 90.0) : 45.0) : 0.0);
}
array[num13] = (byte)num17;
num14++;
ptr++;
num13++;
}
ptr += num8;
}
byte* ptr2 = (byte*)destination.ImageData.ToPointer();
ptr2 += stride * num2 + num;
num13 = 0;
for (int j = num2; j < num4; j++)
{
int num19 = num;
while (num19 < num3)
{
switch (array[num13])
{
case 0:
num10 = array2[num19 - 1, j];
num11 = array2[num19 + 1, j];
break;
case 45:
num10 = array2[num19 - 1, j + 1];
num11 = array2[num19 + 1, j - 1];
break;
case 90:
num10 = array2[num19, j + 1];
num11 = array2[num19, j - 1];
break;
case 135:
num10 = array2[num19 + 1, j + 1];
num11 = array2[num19 - 1, j - 1];
break;
}
if (array2[num19, j] < num10 || array2[num19, j] < num11)
{
*ptr2 = 0;
}
else
{
*ptr2 = (byte)(array2[num19, j] / num12 * 255f);
}
num19++;
ptr2++;
num13++;
}
ptr2 += num7;
}
ptr2 = (byte*)destination.ImageData.ToPointer();
ptr2 += stride * num2 + num;
for (int k = num2; k < num4; k++)
{
int num20 = num;
while (num20 < num3)
{
if (*ptr2 < highThreshold)
{
if (*ptr2 < lowThreshold)
{
*ptr2 = 0;
}
else if (ptr2[-1] < highThreshold && ptr2[1] < highThreshold && ptr2[-stride - 1] < highThreshold && ptr2[-stride] < highThreshold && ptr2[-stride + 1] < highThreshold && ptr2[stride - 1] < highThreshold && ptr2[stride] < highThreshold && ptr2[stride + 1] < highThreshold)
{
*ptr2 = 0;
}
}
num20++;
ptr2++;
}
ptr2 += num7;
}
Drawing.Rectangle(destination, rect, Color.Black);
unmanagedImage.Dispose();
}
}

View File

@@ -0,0 +1,146 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class CanvasCrop : BaseInPlaceFilter
{
private byte fillRed = byte.MaxValue;
private byte fillGreen = byte.MaxValue;
private byte fillBlue = byte.MaxValue;
private byte fillGray = byte.MaxValue;
private Rectangle region;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public Color FillColorRGB
{
get
{
return Color.FromArgb(fillRed, fillGreen, fillBlue);
}
set
{
fillRed = value.R;
fillGreen = value.G;
fillBlue = value.B;
}
}
public byte FillColorGray
{
get
{
return fillGray;
}
set
{
fillGray = value;
}
}
public Rectangle Region
{
get
{
return region;
}
set
{
region = value;
}
}
private CanvasCrop()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
}
public CanvasCrop(Rectangle region)
: this()
{
this.region = region;
}
public CanvasCrop(Rectangle region, Color fillColorRGB)
: this()
{
this.region = region;
fillRed = fillColorRGB.R;
fillGreen = fillColorRGB.G;
fillBlue = fillColorRGB.B;
}
public CanvasCrop(Rectangle region, byte fillColorGray)
: this()
{
this.region = region;
fillGray = fillColorGray;
}
public CanvasCrop(Rectangle region, Color fillColorRGB, byte fillColorGray)
: this()
{
this.region = region;
fillRed = fillColorRGB.R;
fillGreen = fillColorRGB.G;
fillBlue = fillColorRGB.B;
fillGray = fillColorGray;
}
protected unsafe override void ProcessFilter(UnmanagedImage image)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Invalid comparison between Unknown and I4
int num = Image.GetPixelFormatSize(image.PixelFormat) / 8;
int width = image.Width;
int height = image.Height;
int num2 = image.Stride - width * num;
byte* ptr = (byte*)image.ImageData.ToPointer();
if ((int)image.PixelFormat == 198659)
{
for (int i = 0; i < height; i++)
{
int num3 = 0;
while (num3 < width)
{
if (!region.Contains(num3, i))
{
*ptr = fillGray;
}
num3++;
ptr++;
}
ptr += num2;
}
return;
}
for (int j = 0; j < height; j++)
{
int num4 = 0;
while (num4 < width)
{
if (!region.Contains(num4, j))
{
ptr[2] = fillRed;
ptr[1] = fillGreen;
*ptr = fillBlue;
}
num4++;
ptr += num;
}
ptr += num2;
}
}
}

View File

@@ -0,0 +1,149 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class CanvasFill : BaseInPlaceFilter
{
private byte fillRed = byte.MaxValue;
private byte fillGreen = byte.MaxValue;
private byte fillBlue = byte.MaxValue;
private byte fillGray = byte.MaxValue;
private Rectangle region;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public Color FillColorRGB
{
get
{
return Color.FromArgb(fillRed, fillGreen, fillBlue);
}
set
{
fillRed = value.R;
fillGreen = value.G;
fillBlue = value.B;
}
}
public byte FillColorGray
{
get
{
return fillGray;
}
set
{
fillGray = value;
}
}
public Rectangle Region
{
get
{
return region;
}
set
{
region = value;
}
}
private CanvasFill()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
}
public CanvasFill(Rectangle region)
: this()
{
this.region = region;
}
public CanvasFill(Rectangle region, Color fillColorRGB)
: this()
{
this.region = region;
fillRed = fillColorRGB.R;
fillGreen = fillColorRGB.G;
fillBlue = fillColorRGB.B;
}
public CanvasFill(Rectangle region, byte fillColorGray)
: this()
{
this.region = region;
fillGray = fillColorGray;
}
public CanvasFill(Rectangle region, Color fillColorRGB, byte fillColorGray)
: this()
{
this.region = region;
fillRed = fillColorRGB.R;
fillGreen = fillColorRGB.G;
fillBlue = fillColorRGB.B;
fillGray = fillColorGray;
}
protected unsafe override void ProcessFilter(UnmanagedImage image)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Invalid comparison between Unknown and I4
int num = Image.GetPixelFormatSize(image.PixelFormat) / 8;
int width = image.Width;
int height = image.Height;
int num2 = System.Math.Max(0, region.X);
int num3 = System.Math.Max(0, region.Y);
if (num2 >= width || num3 >= height)
{
return;
}
int num4 = System.Math.Min(width, region.Right);
int num5 = System.Math.Min(height, region.Bottom);
if (num4 <= num2 || num5 <= num3)
{
return;
}
int stride = image.Stride;
byte* ptr = (byte*)image.ImageData.ToPointer() + (nint)num3 * (nint)stride + (nint)num2 * (nint)num;
if ((int)image.PixelFormat == 198659)
{
int count = num4 - num2;
for (int i = num3; i < num5; i++)
{
SystemTools.SetUnmanagedMemory(ptr, fillGray, count);
ptr += stride;
}
return;
}
int num6 = stride - (num4 - num2) * num;
for (int j = num3; j < num5; j++)
{
int num7 = num2;
while (num7 < num4)
{
ptr[2] = fillRed;
ptr[1] = fillGreen;
*ptr = fillBlue;
num7++;
ptr += num;
}
ptr += num6;
}
}
}

View File

@@ -0,0 +1,297 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class CanvasMove : BaseInPlaceFilter
{
private byte fillRed = byte.MaxValue;
private byte fillGreen = byte.MaxValue;
private byte fillBlue = byte.MaxValue;
private byte fillAlpha = byte.MaxValue;
private byte fillGray = byte.MaxValue;
private IntPoint movePoint;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public Color FillColorRGB
{
get
{
return Color.FromArgb(fillAlpha, fillRed, fillGreen, fillBlue);
}
set
{
fillRed = value.R;
fillGreen = value.G;
fillBlue = value.B;
fillAlpha = value.A;
}
}
public byte FillColorGray
{
get
{
return fillGray;
}
set
{
fillGray = value;
}
}
public IntPoint MovePoint
{
get
{
return movePoint;
}
set
{
movePoint = value;
}
}
private CanvasMove()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)1052676] = (PixelFormat)1052676;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
formatTranslations[(PixelFormat)1060876] = (PixelFormat)1060876;
formatTranslations[(PixelFormat)3424269] = (PixelFormat)3424269;
}
public CanvasMove(IntPoint movePoint)
: this()
{
this.movePoint = movePoint;
}
public CanvasMove(IntPoint movePoint, Color fillColorRGB)
: this()
{
this.movePoint = movePoint;
fillRed = fillColorRGB.R;
fillGreen = fillColorRGB.G;
fillBlue = fillColorRGB.B;
fillAlpha = fillColorRGB.A;
}
public CanvasMove(IntPoint movePoint, byte fillColorGray)
: this()
{
this.movePoint = movePoint;
fillGray = fillColorGray;
}
public CanvasMove(IntPoint movePoint, Color fillColorRGB, byte fillColorGray)
: this()
{
this.movePoint = movePoint;
fillRed = fillColorRGB.R;
fillGreen = fillColorRGB.G;
fillBlue = fillColorRGB.B;
fillAlpha = fillColorRGB.A;
fillGray = fillColorGray;
}
protected override void ProcessFilter(UnmanagedImage image)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
switch (Image.GetPixelFormatSize(image.PixelFormat) / 8)
{
case 1:
case 3:
case 4:
ProcessFilter8bpc(image);
break;
case 2:
case 6:
case 8:
ProcessFilter16bpc(image);
break;
case 5:
case 7:
break;
}
}
private unsafe void ProcessFilter8bpc(UnmanagedImage image)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Invalid comparison between Unknown and I4
int num = Image.GetPixelFormatSize(image.PixelFormat) / 8;
bool flag = num == 4;
int width = image.Width;
int height = image.Height;
int stride = image.Stride;
int x = movePoint.X;
int y = movePoint.Y;
Rectangle rectangle = Rectangle.Intersect(new Rectangle(0, 0, width, height), new Rectangle(x, y, width, height));
int num2 = 0;
int num3 = height;
int num4 = 1;
int num5 = 0;
int num6 = width;
int num7 = 1;
if (y > 0)
{
num2 = height - 1;
num3 = -1;
num4 = -1;
}
if (x > 0)
{
num5 = width - 1;
num6 = -1;
num7 = -1;
}
byte* ptr = (byte*)image.ImageData.ToPointer();
if ((int)image.PixelFormat == 198659)
{
for (int i = num2; i != num3; i += num4)
{
for (int j = num5; j != num6; j += num7)
{
byte* ptr2 = ptr + (nint)i * (nint)stride + j;
if (rectangle.Contains(j, i))
{
byte* ptr3 = ptr + (nint)(i - y) * (nint)stride + (j - x);
*ptr2 = *ptr3;
}
else
{
*ptr2 = fillGray;
}
}
}
return;
}
for (int k = num2; k != num3; k += num4)
{
for (int l = num5; l != num6; l += num7)
{
byte* ptr2 = ptr + (nint)k * (nint)stride + (nint)l * (nint)num;
if (rectangle.Contains(l, k))
{
byte* ptr3 = ptr + (nint)(k - y) * (nint)stride + (nint)(l - x) * (nint)num;
ptr2[2] = ptr3[2];
ptr2[1] = ptr3[1];
*ptr2 = *ptr3;
if (flag)
{
ptr2[3] = ptr3[3];
}
}
else
{
ptr2[2] = fillRed;
ptr2[1] = fillGreen;
*ptr2 = fillBlue;
if (flag)
{
ptr2[3] = fillAlpha;
}
}
}
}
}
private unsafe void ProcessFilter16bpc(UnmanagedImage image)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Invalid comparison between Unknown and I4
int num = Image.GetPixelFormatSize(image.PixelFormat) / 8;
bool flag = num == 8;
ushort num2 = (ushort)(fillRed << 8);
ushort num3 = (ushort)(fillGreen << 8);
ushort num4 = (ushort)(fillBlue << 8);
ushort num5 = (ushort)(fillAlpha << 8);
int width = image.Width;
int height = image.Height;
int stride = image.Stride;
int x = movePoint.X;
int y = movePoint.Y;
Rectangle rectangle = Rectangle.Intersect(new Rectangle(0, 0, width, height), new Rectangle(x, y, width, height));
int num6 = 0;
int num7 = height;
int num8 = 1;
int num9 = 0;
int num10 = width;
int num11 = 1;
if (y > 0)
{
num6 = height - 1;
num7 = -1;
num8 = -1;
}
if (x > 0)
{
num9 = width - 1;
num10 = -1;
num11 = -1;
}
byte* ptr = (byte*)image.ImageData.ToPointer();
if ((int)image.PixelFormat == 1052676)
{
for (int i = num6; i != num7; i += num8)
{
for (int j = num9; j != num10; j += num11)
{
ushort* ptr2 = (ushort*)(ptr + (nint)i * (nint)stride) + j;
if (rectangle.Contains(j, i))
{
ushort* ptr3 = (ushort*)(ptr + (nint)(i - y) * (nint)stride) + (j - x);
*ptr2 = *ptr3;
}
else
{
*ptr2 = fillGray;
}
}
}
return;
}
for (int k = num6; k != num7; k += num8)
{
for (int l = num9; l != num10; l += num11)
{
ushort* ptr2 = (ushort*)(ptr + (nint)k * (nint)stride + (nint)l * (nint)num);
if (rectangle.Contains(l, k))
{
ushort* ptr3 = (ushort*)(ptr + (nint)(k - y) * (nint)stride + (nint)(l - x) * (nint)num);
ptr2[2] = ptr3[2];
ptr2[1] = ptr3[1];
*ptr2 = *ptr3;
if (flag)
{
ptr2[3] = ptr3[3];
}
}
else
{
ptr2[2] = num2;
ptr2[1] = num3;
*ptr2 = num4;
if (flag)
{
ptr2[3] = num5;
}
}
}
}
}
}

View File

@@ -0,0 +1,210 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class ChannelFiltering : BaseInPlacePartialFilter
{
private IntRange red = new IntRange(0, 255);
private IntRange green = new IntRange(0, 255);
private IntRange blue = new IntRange(0, 255);
private byte fillR;
private byte fillG;
private byte fillB;
private bool redFillOutsideRange = true;
private bool greenFillOutsideRange = true;
private bool blueFillOutsideRange = true;
private byte[] mapRed = new byte[256];
private byte[] mapGreen = new byte[256];
private byte[] mapBlue = new byte[256];
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public IntRange Red
{
get
{
return red;
}
set
{
red = value;
CalculateMap(red, fillR, redFillOutsideRange, mapRed);
}
}
public byte FillRed
{
get
{
return fillR;
}
set
{
fillR = value;
CalculateMap(red, fillR, redFillOutsideRange, mapRed);
}
}
public IntRange Green
{
get
{
return green;
}
set
{
green = value;
CalculateMap(green, fillG, greenFillOutsideRange, mapGreen);
}
}
public byte FillGreen
{
get
{
return fillG;
}
set
{
fillG = value;
CalculateMap(green, fillG, greenFillOutsideRange, mapGreen);
}
}
public IntRange Blue
{
get
{
return blue;
}
set
{
blue = value;
CalculateMap(blue, fillB, blueFillOutsideRange, mapBlue);
}
}
public byte FillBlue
{
get
{
return fillB;
}
set
{
fillB = value;
CalculateMap(blue, fillB, blueFillOutsideRange, mapBlue);
}
}
public bool RedFillOutsideRange
{
get
{
return redFillOutsideRange;
}
set
{
redFillOutsideRange = value;
CalculateMap(red, fillR, redFillOutsideRange, mapRed);
}
}
public bool GreenFillOutsideRange
{
get
{
return greenFillOutsideRange;
}
set
{
greenFillOutsideRange = value;
CalculateMap(green, fillG, greenFillOutsideRange, mapGreen);
}
}
public bool BlueFillOutsideRange
{
get
{
return blueFillOutsideRange;
}
set
{
blueFillOutsideRange = value;
CalculateMap(blue, fillB, blueFillOutsideRange, mapBlue);
}
}
public ChannelFiltering()
: this(new IntRange(0, 255), new IntRange(0, 255), new IntRange(0, 255))
{
}
public ChannelFiltering(IntRange red, IntRange green, IntRange blue)
{
Red = red;
Green = green;
Blue = blue;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
}
protected unsafe override void ProcessFilter(UnmanagedImage image, Rectangle rect)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
int num = (((int)image.PixelFormat == 137224) ? 3 : 4);
int left = rect.Left;
int top = rect.Top;
int num2 = left + rect.Width;
int num3 = top + rect.Height;
int num4 = image.Stride - rect.Width * num;
byte* ptr = (byte*)image.ImageData.ToPointer();
ptr += top * image.Stride + left * num;
for (int i = top; i < num3; i++)
{
int num5 = left;
while (num5 < num2)
{
ptr[2] = mapRed[ptr[2]];
ptr[1] = mapGreen[ptr[1]];
*ptr = mapBlue[*ptr];
num5++;
ptr += num;
}
ptr += num4;
}
}
private void CalculateMap(IntRange range, byte fill, bool fillOutsideRange, byte[] map)
{
for (int i = 0; i < 256; i++)
{
if (i >= range.Min && i <= range.Max)
{
map[i] = (fillOutsideRange ? ((byte)i) : fill);
}
else
{
map[i] = (fillOutsideRange ? fill : ((byte)i));
}
}
}
}

View File

@@ -0,0 +1,89 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class Closing : IFilter, IInPlaceFilter, IInPlacePartialFilter, IFilterInformation
{
private Erosion errosion = new Erosion();
private Dilatation dilatation = new Dilatation();
public Dictionary<PixelFormat, PixelFormat> FormatTranslations => errosion.FormatTranslations;
public Closing()
{
}
public Closing(short[,] se)
{
errosion = new Erosion(se);
dilatation = new Dilatation(se);
}
public Bitmap Apply(Bitmap image)
{
Bitmap val = dilatation.Apply(image);
Bitmap result = errosion.Apply(val);
((Image)val).Dispose();
return result;
}
public Bitmap Apply(BitmapData imageData)
{
Bitmap val = dilatation.Apply(imageData);
Bitmap result = errosion.Apply(val);
((Image)val).Dispose();
return result;
}
public UnmanagedImage Apply(UnmanagedImage image)
{
UnmanagedImage unmanagedImage = dilatation.Apply(image);
errosion.ApplyInPlace(unmanagedImage);
return unmanagedImage;
}
public void Apply(UnmanagedImage sourceImage, UnmanagedImage destinationImage)
{
dilatation.Apply(sourceImage, destinationImage);
errosion.ApplyInPlace(destinationImage);
}
public void ApplyInPlace(Bitmap image)
{
dilatation.ApplyInPlace(image);
errosion.ApplyInPlace(image);
}
public void ApplyInPlace(BitmapData imageData)
{
dilatation.ApplyInPlace(imageData);
errosion.ApplyInPlace(imageData);
}
public void ApplyInPlace(UnmanagedImage image)
{
dilatation.ApplyInPlace(image);
errosion.ApplyInPlace(image);
}
public void ApplyInPlace(Bitmap image, Rectangle rect)
{
dilatation.ApplyInPlace(image, rect);
errosion.ApplyInPlace(image, rect);
}
public void ApplyInPlace(BitmapData imageData, Rectangle rect)
{
dilatation.ApplyInPlace(imageData, rect);
errosion.ApplyInPlace(imageData, rect);
}
public void ApplyInPlace(UnmanagedImage image, Rectangle rect)
{
dilatation.ApplyInPlace(image, rect);
errosion.ApplyInPlace(image, rect);
}
}

View File

@@ -0,0 +1,145 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class ColorFiltering : BaseInPlacePartialFilter
{
private IntRange red = new IntRange(0, 255);
private IntRange green = new IntRange(0, 255);
private IntRange blue = new IntRange(0, 255);
private byte fillR;
private byte fillG;
private byte fillB;
private bool fillOutsideRange = true;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public IntRange Red
{
get
{
return red;
}
set
{
red = value;
}
}
public IntRange Green
{
get
{
return green;
}
set
{
green = value;
}
}
public IntRange Blue
{
get
{
return blue;
}
set
{
blue = value;
}
}
public RGB FillColor
{
get
{
return new RGB(fillR, fillG, fillB);
}
set
{
fillR = value.Red;
fillG = value.Green;
fillB = value.Blue;
}
}
public bool FillOutsideRange
{
get
{
return fillOutsideRange;
}
set
{
fillOutsideRange = value;
}
}
public ColorFiltering()
{
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
}
public ColorFiltering(IntRange red, IntRange green, IntRange blue)
: this()
{
this.red = red;
this.green = green;
this.blue = blue;
}
protected unsafe override void ProcessFilter(UnmanagedImage image, Rectangle rect)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
int num = (((int)image.PixelFormat == 137224) ? 3 : 4);
int left = rect.Left;
int top = rect.Top;
int num2 = left + rect.Width;
int num3 = top + rect.Height;
int num4 = image.Stride - rect.Width * num;
byte* ptr = (byte*)image.ImageData.ToPointer();
ptr += top * image.Stride + left * num;
for (int i = top; i < num3; i++)
{
int num5 = left;
while (num5 < num2)
{
byte b = ptr[2];
byte b2 = ptr[1];
byte b3 = *ptr;
if (b >= red.Min && b <= red.Max && b2 >= green.Min && b2 <= green.Max && b3 >= blue.Min && b3 <= blue.Max)
{
if (!fillOutsideRange)
{
ptr[2] = fillR;
ptr[1] = fillG;
*ptr = fillB;
}
}
else if (fillOutsideRange)
{
ptr[2] = fillR;
ptr[1] = fillG;
*ptr = fillB;
}
num5++;
ptr += num;
}
ptr += num4;
}
}
}

View File

@@ -0,0 +1,158 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class ColorRemapping : BaseInPlacePartialFilter
{
private byte[] redMap;
private byte[] greenMap;
private byte[] blueMap;
private byte[] grayMap;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public byte[] RedMap
{
get
{
return redMap;
}
set
{
if (value == null || value.Length != 256)
{
throw new ArgumentException("A map should be array with 256 value.");
}
redMap = value;
}
}
public byte[] GreenMap
{
get
{
return greenMap;
}
set
{
if (value == null || value.Length != 256)
{
throw new ArgumentException("A map should be array with 256 value.");
}
greenMap = value;
}
}
public byte[] BlueMap
{
get
{
return blueMap;
}
set
{
if (value == null || value.Length != 256)
{
throw new ArgumentException("A map should be array with 256 value.");
}
blueMap = value;
}
}
public byte[] GrayMap
{
get
{
return grayMap;
}
set
{
if (value == null || value.Length != 256)
{
throw new ArgumentException("A map should be array with 256 value.");
}
grayMap = value;
}
}
public ColorRemapping()
{
redMap = new byte[256];
greenMap = new byte[256];
blueMap = new byte[256];
grayMap = new byte[256];
for (int i = 0; i < 256; i++)
{
redMap[i] = (greenMap[i] = (blueMap[i] = (grayMap[i] = (byte)i)));
}
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
}
public ColorRemapping(byte[] redMap, byte[] greenMap, byte[] blueMap)
: this()
{
RedMap = redMap;
GreenMap = greenMap;
BlueMap = blueMap;
}
public ColorRemapping(byte[] grayMap)
: this()
{
GrayMap = grayMap;
}
protected unsafe override void ProcessFilter(UnmanagedImage image, Rectangle rect)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Invalid comparison between Unknown and I4
int num = Image.GetPixelFormatSize(image.PixelFormat) / 8;
int left = rect.Left;
int top = rect.Top;
int num2 = left + rect.Width;
int num3 = top + rect.Height;
int num4 = image.Stride - rect.Width * num;
byte* ptr = (byte*)image.ImageData.ToPointer();
ptr += top * image.Stride + left * num;
if ((int)image.PixelFormat == 198659)
{
for (int i = top; i < num3; i++)
{
int num5 = left;
while (num5 < num2)
{
*ptr = grayMap[*ptr];
num5++;
ptr++;
}
ptr += num4;
}
return;
}
for (int j = top; j < num3; j++)
{
int num6 = left;
while (num6 < num2)
{
ptr[2] = redMap[ptr[2]];
ptr[1] = greenMap[ptr[1]];
*ptr = blueMap[*ptr];
num6++;
ptr += num;
}
ptr += num4;
}
}
}

View File

@@ -0,0 +1,185 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class ConnectedComponentsLabeling : BaseFilter
{
private static Color[] colorTable = new Color[32]
{
Color.Red,
Color.Green,
Color.Blue,
Color.Yellow,
Color.Violet,
Color.Brown,
Color.Olive,
Color.Cyan,
Color.Magenta,
Color.Gold,
Color.Indigo,
Color.Ivory,
Color.HotPink,
Color.DarkRed,
Color.DarkGreen,
Color.DarkBlue,
Color.DarkSeaGreen,
Color.Gray,
Color.DarkKhaki,
Color.DarkGray,
Color.LimeGreen,
Color.Tomato,
Color.SteelBlue,
Color.SkyBlue,
Color.Silver,
Color.Salmon,
Color.SaddleBrown,
Color.RosyBrown,
Color.PowderBlue,
Color.Plum,
Color.PapayaWhip,
Color.Orange
};
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
private BlobCounterBase blobCounter = new BlobCounter();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public BlobCounterBase BlobCounter
{
get
{
return blobCounter;
}
set
{
blobCounter = value;
}
}
public static Color[] ColorTable
{
get
{
return colorTable;
}
set
{
colorTable = value;
}
}
public bool FilterBlobs
{
get
{
return blobCounter.FilterBlobs;
}
set
{
blobCounter.FilterBlobs = value;
}
}
public bool CoupledSizeFiltering
{
get
{
return blobCounter.CoupledSizeFiltering;
}
set
{
blobCounter.CoupledSizeFiltering = value;
}
}
public int MinWidth
{
get
{
return blobCounter.MinWidth;
}
set
{
blobCounter.MinWidth = value;
}
}
public int MinHeight
{
get
{
return blobCounter.MinHeight;
}
set
{
blobCounter.MinHeight = value;
}
}
public int MaxWidth
{
get
{
return blobCounter.MaxWidth;
}
set
{
blobCounter.MaxWidth = value;
}
}
public int MaxHeight
{
get
{
return blobCounter.MaxHeight;
}
set
{
blobCounter.MaxHeight = value;
}
}
public int ObjectCount => blobCounter.ObjectsCount;
public ConnectedComponentsLabeling()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)137224;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)137224;
formatTranslations[(PixelFormat)925707] = (PixelFormat)137224;
}
protected unsafe override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData)
{
blobCounter.ProcessImage(sourceData);
int[] objectLabels = blobCounter.ObjectLabels;
int width = sourceData.Width;
int height = sourceData.Height;
int num = destinationData.Stride - width * 3;
byte* ptr = (byte*)destinationData.ImageData.ToPointer();
int num2 = 0;
for (int i = 0; i < height; i++)
{
int num3 = 0;
while (num3 < width)
{
if (objectLabels[num2] != 0)
{
Color color = colorTable[(objectLabels[num2] - 1) % colorTable.Length];
ptr[2] = color.R;
ptr[1] = color.G;
*ptr = color.B;
}
num3++;
ptr += 3;
num2++;
}
ptr += num;
}
}
}

View File

@@ -0,0 +1,183 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class ConservativeSmoothing : BaseUsingCopyPartialFilter
{
private int size = 3;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public int KernelSize
{
get
{
return size;
}
set
{
size = System.Math.Max(3, System.Math.Min(25, value | 1));
}
}
public ConservativeSmoothing()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
}
public ConservativeSmoothing(int size)
: this()
{
KernelSize = size;
}
protected unsafe override void ProcessFilter(UnmanagedImage source, UnmanagedImage destination, Rectangle rect)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Invalid comparison between Unknown and I4
int num = Image.GetPixelFormatSize(source.PixelFormat) / 8;
int left = rect.Left;
int top = rect.Top;
int num2 = left + rect.Width;
int num3 = top + rect.Height;
int stride = source.Stride;
int stride2 = destination.Stride;
int num4 = stride - rect.Width * num;
int num5 = stride2 - rect.Width * num;
int num6 = size >> 1;
byte* ptr = (byte*)source.ImageData.ToPointer();
byte* ptr2 = (byte*)destination.ImageData.ToPointer();
ptr += top * stride + left * num;
ptr2 += top * stride2 + left * num;
if ((int)destination.PixelFormat == 198659)
{
for (int i = top; i < num3; i++)
{
int num7 = left;
while (num7 < num2)
{
byte b = byte.MaxValue;
byte b2 = 0;
byte b3;
for (int j = -num6; j <= num6; j++)
{
int num8 = i + j;
if (num8 < top)
{
continue;
}
if (num8 >= num3)
{
break;
}
for (int k = -num6; k <= num6; k++)
{
num8 = num7 + k;
if (num8 >= left && j != k && num8 < num2)
{
b3 = ptr[j * stride + k];
if (b3 < b)
{
b = b3;
}
if (b3 > b2)
{
b2 = b3;
}
}
}
}
b3 = *ptr;
*ptr2 = ((b3 > b2) ? b2 : ((b3 < b) ? b : b3));
num7++;
ptr++;
ptr2++;
}
ptr += num4;
ptr2 += num5;
}
return;
}
for (int l = top; l < num3; l++)
{
int num9 = left;
while (num9 < num2)
{
byte b;
byte b5;
byte b4 = (b = (b5 = byte.MaxValue));
byte b2;
byte b7;
byte b6 = (b2 = (b7 = 0));
byte b3;
for (int j = -num6; j <= num6; j++)
{
int num8 = l + j;
if (num8 < top)
{
continue;
}
if (num8 >= num3)
{
break;
}
for (int k = -num6; k <= num6; k++)
{
num8 = num9 + k;
if (num8 >= left && j != k && num8 < num2)
{
byte* ptr3 = ptr + (j * stride + k * num);
b3 = ptr3[2];
if (b3 < b4)
{
b4 = b3;
}
if (b3 > b6)
{
b6 = b3;
}
b3 = ptr3[1];
if (b3 < b)
{
b = b3;
}
if (b3 > b2)
{
b2 = b3;
}
b3 = *ptr3;
if (b3 < b5)
{
b5 = b3;
}
if (b3 > b7)
{
b7 = b3;
}
}
}
}
b3 = ptr[2];
ptr2[2] = ((b3 > b6) ? b6 : ((b3 < b4) ? b4 : b3));
b3 = ptr[1];
ptr2[1] = ((b3 > b2) ? b2 : ((b3 < b) ? b : b3));
b3 = *ptr;
*ptr2 = ((b3 > b7) ? b7 : ((b3 < b5) ? b5 : b3));
num9++;
ptr += num;
ptr2 += num;
}
ptr += num4;
ptr2 += num5;
}
}
}

View File

@@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class ContrastCorrection : BaseInPlacePartialFilter
{
private LevelsLinear baseFilter = new LevelsLinear();
private int factor;
public int Factor
{
get
{
return factor;
}
set
{
factor = System.Math.Max(-127, System.Math.Min(127, value));
if (factor > 0)
{
LevelsLinear levelsLinear = baseFilter;
LevelsLinear levelsLinear2 = baseFilter;
LevelsLinear levelsLinear3 = baseFilter;
IntRange intRange = (baseFilter.InGray = new IntRange(factor, 255 - factor));
IntRange intRange3 = (levelsLinear3.InBlue = intRange);
IntRange inRed = (levelsLinear2.InGreen = intRange3);
levelsLinear.InRed = inRed;
LevelsLinear levelsLinear4 = baseFilter;
LevelsLinear levelsLinear5 = baseFilter;
LevelsLinear levelsLinear6 = baseFilter;
IntRange intRange6 = (baseFilter.OutGray = new IntRange(0, 255));
IntRange intRange8 = (levelsLinear6.OutBlue = intRange6);
IntRange outRed = (levelsLinear5.OutGreen = intRange8);
levelsLinear4.OutRed = outRed;
}
else
{
LevelsLinear levelsLinear7 = baseFilter;
LevelsLinear levelsLinear8 = baseFilter;
LevelsLinear levelsLinear9 = baseFilter;
IntRange intRange11 = (baseFilter.OutGray = new IntRange(-factor, 255 + factor));
IntRange intRange13 = (levelsLinear9.OutBlue = intRange11);
IntRange outRed2 = (levelsLinear8.OutGreen = intRange13);
levelsLinear7.OutRed = outRed2;
LevelsLinear levelsLinear10 = baseFilter;
LevelsLinear levelsLinear11 = baseFilter;
LevelsLinear levelsLinear12 = baseFilter;
IntRange intRange16 = (baseFilter.InGray = new IntRange(0, 255));
IntRange intRange18 = (levelsLinear12.InBlue = intRange16);
IntRange inRed2 = (levelsLinear11.InGreen = intRange18);
levelsLinear10.InRed = inRed2;
}
}
}
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => baseFilter.FormatTranslations;
public ContrastCorrection()
{
Factor = 10;
}
public ContrastCorrection(int factor)
{
Factor = factor;
}
protected override void ProcessFilter(UnmanagedImage image, Rectangle rect)
{
baseFilter.ApplyInPlace(image, rect);
}
}

View File

@@ -0,0 +1,113 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class ContrastStretch : BaseInPlacePartialFilter
{
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public ContrastStretch()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
}
protected unsafe override void ProcessFilter(UnmanagedImage image, Rectangle rect)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Invalid comparison between Unknown and I4
int num = Image.GetPixelFormatSize(image.PixelFormat) / 8;
int left = rect.Left;
int top = rect.Top;
int num2 = left + rect.Width;
int num3 = top + rect.Height;
int stride = image.Stride;
int num4 = stride - rect.Width * num;
LevelsLinear levelsLinear = new LevelsLinear();
byte* ptr = (byte*)image.ImageData.ToPointer();
if ((int)image.PixelFormat == 198659)
{
ptr += top * stride + left;
byte b = byte.MaxValue;
byte b2 = 0;
for (int i = top; i < num3; i++)
{
int num5 = left;
while (num5 < num2)
{
byte b3 = *ptr;
if (b3 < b)
{
b = b3;
}
if (b3 > b2)
{
b2 = b3;
}
num5++;
ptr++;
}
ptr += num4;
}
levelsLinear.InGray = new IntRange(b, b2);
}
else
{
ptr += top * stride + left * num;
byte b4 = byte.MaxValue;
byte b5 = byte.MaxValue;
byte b6 = byte.MaxValue;
byte b7 = 0;
byte b8 = 0;
byte b9 = 0;
for (int j = top; j < num3; j++)
{
int num6 = left;
while (num6 < num2)
{
byte b10 = ptr[2];
if (b10 < b4)
{
b4 = b10;
}
if (b10 > b7)
{
b7 = b10;
}
b10 = ptr[1];
if (b10 < b5)
{
b5 = b10;
}
if (b10 > b8)
{
b8 = b10;
}
b10 = *ptr;
if (b10 < b6)
{
b6 = b10;
}
if (b10 > b9)
{
b9 = b10;
}
num6++;
ptr += num;
}
ptr += num4;
}
levelsLinear.InRed = new IntRange(b4, b7);
levelsLinear.InGreen = new IntRange(b5, b8);
levelsLinear.InBlue = new IntRange(b6, b9);
}
levelsLinear.ApplyInPlace(image, rect);
}
}

View File

@@ -0,0 +1,614 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class Convolution : BaseUsingCopyPartialFilter
{
private int[,] kernel;
private int divisor = 1;
private int threshold;
private int size;
private bool dynamicDivisorForEdges = true;
private bool processAlpha;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public int[,] Kernel
{
get
{
return kernel;
}
set
{
int length = value.GetLength(0);
if (length != value.GetLength(1) || length < 3 || length > 99 || length % 2 == 0)
{
throw new ArgumentException("Invalid kernel size.");
}
kernel = value;
size = length;
}
}
public int Divisor
{
get
{
return divisor;
}
set
{
if (value == 0)
{
throw new ArgumentException("Divisor can not be equal to zero.");
}
divisor = value;
}
}
public int Threshold
{
get
{
return threshold;
}
set
{
threshold = value;
}
}
public bool DynamicDivisorForEdges
{
get
{
return dynamicDivisorForEdges;
}
set
{
dynamicDivisorForEdges = value;
}
}
public bool ProcessAlpha
{
get
{
return processAlpha;
}
set
{
processAlpha = value;
}
}
protected Convolution()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)1052676] = (PixelFormat)1052676;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
formatTranslations[(PixelFormat)1060876] = (PixelFormat)1060876;
formatTranslations[(PixelFormat)3424269] = (PixelFormat)3424269;
}
public Convolution(int[,] kernel)
: this()
{
Kernel = kernel;
divisor = 0;
int i = 0;
for (int length = kernel.GetLength(0); i < length; i++)
{
int j = 0;
for (int length2 = kernel.GetLength(1); j < length2; j++)
{
divisor += kernel[i, j];
}
}
if (divisor == 0)
{
divisor = 1;
}
}
public Convolution(int[,] kernel, int divisor)
: this()
{
Kernel = kernel;
Divisor = divisor;
}
protected unsafe override void ProcessFilter(UnmanagedImage source, UnmanagedImage destination, Rectangle rect)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_0166: Invalid comparison between Unknown and I4
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Invalid comparison between Unknown and I4
int num = Image.GetPixelFormatSize(source.PixelFormat) / 8;
int left = rect.Left;
int top = rect.Top;
int stopX = left + rect.Width;
int stopY = top + rect.Height;
if (num <= 4 && num != 2)
{
int stride = source.Stride;
int stride2 = destination.Stride;
int srcOffset = stride - rect.Width * num;
int dstOffset = stride2 - rect.Width * num;
byte* ptr = (byte*)source.ImageData.ToPointer();
byte* ptr2 = (byte*)destination.ImageData.ToPointer();
ptr += top * stride + left * num;
ptr2 += top * stride2 + left * num;
if ((int)destination.PixelFormat == 198659)
{
Process8bppImage(ptr, ptr2, stride, stride2, srcOffset, dstOffset, left, top, stopX, stopY);
}
else if (num == 3 || !processAlpha)
{
Process24bppImage(ptr, ptr2, stride, stride2, srcOffset, dstOffset, left, top, stopX, stopY, num);
}
else
{
Process32bppImage(ptr, ptr2, stride, stride2, srcOffset, dstOffset, left, top, stopX, stopY);
}
}
else
{
num /= 2;
int dstStride = destination.Stride / 2;
int srcStride = source.Stride / 2;
ushort* ptr3 = (ushort*)source.ImageData.ToPointer();
ushort* ptr4 = (ushort*)destination.ImageData.ToPointer();
ptr3 += left * num;
ptr4 += left * num;
if ((int)source.PixelFormat == 1052676)
{
Process16bppImage(ptr3, ptr4, srcStride, dstStride, left, top, stopX, stopY);
}
else if (num == 3 || !processAlpha)
{
Process48bppImage(ptr3, ptr4, srcStride, dstStride, left, top, stopX, stopY, num);
}
else
{
Process64bppImage(ptr3, ptr4, srcStride, dstStride, left, top, stopX, stopY);
}
}
}
private unsafe void Process8bppImage(byte* src, byte* dst, int srcStride, int dstStride, int srcOffset, int dstOffset, int startX, int startY, int stopX, int stopY)
{
int num = size >> 1;
int num2 = size * size;
for (int i = startY; i < stopY; i++)
{
int num3 = startX;
while (num3 < stopX)
{
long num5;
int num6;
long num4 = (num5 = (num6 = 0));
for (int j = 0; j < size; j++)
{
int num7 = j - num;
int num8 = i + num7;
if (num8 < startY)
{
continue;
}
if (num8 >= stopY)
{
break;
}
for (int k = 0; k < size; k++)
{
int num9 = k - num;
num8 = num3 + num9;
if (num8 >= startX && num8 < stopX)
{
int num10 = kernel[j, k];
num5 += num10;
num4 += num10 * src[num7 * srcStride + num9];
num6++;
}
}
}
if (num6 == num2)
{
num5 = divisor;
}
else if (!dynamicDivisorForEdges)
{
num5 = divisor;
}
if (num5 != 0)
{
num4 /= num5;
}
num4 += threshold;
*dst = (byte)((num4 > 255) ? 255 : ((num4 < 0) ? 0 : num4));
num3++;
src++;
dst++;
}
src += srcOffset;
dst += dstOffset;
}
}
private unsafe void Process24bppImage(byte* src, byte* dst, int srcStride, int dstStride, int srcOffset, int dstOffset, int startX, int startY, int stopX, int stopY, int pixelSize)
{
int num = size >> 1;
int num2 = size * size;
for (int i = startY; i < stopY; i++)
{
int num3 = startX;
while (num3 < stopX)
{
long num7;
int num8;
long num5;
long num6;
long num4 = (num5 = (num6 = (num7 = (num8 = 0))));
for (int j = 0; j < size; j++)
{
int num9 = j - num;
int num10 = i + num9;
if (num10 < startY)
{
continue;
}
if (num10 >= stopY)
{
break;
}
for (int k = 0; k < size; k++)
{
int num11 = k - num;
num10 = num3 + num11;
if (num10 >= startX && num10 < stopX)
{
int num12 = kernel[j, k];
byte* ptr = src + (num9 * srcStride + num11 * pixelSize);
num7 += num12;
num4 += num12 * ptr[2];
num5 += num12 * ptr[1];
num6 += num12 * *ptr;
num8++;
}
}
}
if (num8 == num2)
{
num7 = divisor;
}
else if (!dynamicDivisorForEdges)
{
num7 = divisor;
}
if (num7 != 0)
{
num4 /= num7;
num5 /= num7;
num6 /= num7;
}
num4 += threshold;
num5 += threshold;
num6 += threshold;
dst[2] = (byte)((num4 > 255) ? 255 : ((num4 < 0) ? 0 : num4));
dst[1] = (byte)((num5 > 255) ? 255 : ((num5 < 0) ? 0 : num5));
*dst = (byte)((num6 > 255) ? 255 : ((num6 < 0) ? 0 : num6));
if (pixelSize == 4)
{
dst[3] = src[3];
}
num3++;
src += pixelSize;
dst += pixelSize;
}
src += srcOffset;
dst += dstOffset;
}
}
private unsafe void Process32bppImage(byte* src, byte* dst, int srcStride, int dstStride, int srcOffset, int dstOffset, int startX, int startY, int stopX, int stopY)
{
int num = size >> 1;
int num2 = size * size;
for (int i = startY; i < stopY; i++)
{
int num3 = startX;
while (num3 < stopX)
{
long num8;
int num9;
long num5;
long num6;
long num7;
long num4 = (num5 = (num6 = (num7 = (num8 = (num9 = 0)))));
for (int j = 0; j < size; j++)
{
int num10 = j - num;
int num11 = i + num10;
if (num11 < startY)
{
continue;
}
if (num11 >= stopY)
{
break;
}
for (int k = 0; k < size; k++)
{
int num12 = k - num;
num11 = num3 + num12;
if (num11 >= startX && num11 < stopX)
{
int num13 = kernel[j, k];
byte* ptr = src + (num10 * srcStride + num12 * 4);
num8 += num13;
num4 += num13 * ptr[2];
num5 += num13 * ptr[1];
num6 += num13 * *ptr;
num7 += num13 * ptr[3];
num9++;
}
}
}
if (num9 == num2)
{
num8 = divisor;
}
else if (!dynamicDivisorForEdges)
{
num8 = divisor;
}
if (num8 != 0)
{
num4 /= num8;
num5 /= num8;
num6 /= num8;
num7 /= num8;
}
num4 += threshold;
num5 += threshold;
num6 += threshold;
num7 += threshold;
dst[2] = (byte)((num4 > 255) ? 255 : ((num4 < 0) ? 0 : num4));
dst[1] = (byte)((num5 > 255) ? 255 : ((num5 < 0) ? 0 : num5));
*dst = (byte)((num6 > 255) ? 255 : ((num6 < 0) ? 0 : num6));
dst[3] = (byte)((num7 > 255) ? 255 : ((num7 < 0) ? 0 : num7));
num3++;
src += 4;
dst += 4;
}
src += srcOffset;
dst += dstOffset;
}
}
private unsafe void Process16bppImage(ushort* baseSrc, ushort* baseDst, int srcStride, int dstStride, int startX, int startY, int stopX, int stopY)
{
int num = size >> 1;
int num2 = size * size;
for (int i = startY; i < stopY; i++)
{
ushort* ptr = baseSrc + i * srcStride;
ushort* ptr2 = baseDst + i * dstStride;
int num3 = startX;
while (num3 < stopX)
{
long num5;
int num6;
long num4 = (num5 = (num6 = 0));
for (int j = 0; j < size; j++)
{
int num7 = j - num;
int num8 = i + num7;
if (num8 < startY)
{
continue;
}
if (num8 >= stopY)
{
break;
}
for (int k = 0; k < size; k++)
{
int num9 = k - num;
num8 = num3 + num9;
if (num8 >= startX && num8 < stopX)
{
int num10 = kernel[j, k];
num5 += num10;
num4 += num10 * ptr[num7 * srcStride + num9];
num6++;
}
}
}
if (num6 == num2)
{
num5 = divisor;
}
else if (!dynamicDivisorForEdges)
{
num5 = divisor;
}
if (num5 != 0)
{
num4 /= num5;
}
num4 += threshold;
*ptr2 = (ushort)((num4 > 65535) ? 65535 : ((num4 < 0) ? 0 : num4));
num3++;
ptr++;
ptr2++;
}
}
}
private unsafe void Process48bppImage(ushort* baseSrc, ushort* baseDst, int srcStride, int dstStride, int startX, int startY, int stopX, int stopY, int pixelSize)
{
int num = size >> 1;
int num2 = size * size;
for (int i = startY; i < stopY; i++)
{
ushort* ptr = baseSrc + i * srcStride;
ushort* ptr2 = baseDst + i * dstStride;
int num3 = startX;
while (num3 < stopX)
{
long num7;
int num8;
long num5;
long num6;
long num4 = (num5 = (num6 = (num7 = (num8 = 0))));
for (int j = 0; j < size; j++)
{
int num9 = j - num;
int num10 = i + num9;
if (num10 < startY)
{
continue;
}
if (num10 >= stopY)
{
break;
}
for (int k = 0; k < size; k++)
{
int num11 = k - num;
num10 = num3 + num11;
if (num10 >= startX && num10 < stopX)
{
int num12 = kernel[j, k];
ushort* ptr3 = ptr + (num9 * srcStride + num11 * pixelSize);
num7 += num12;
num4 += num12 * ptr3[2];
num5 += num12 * ptr3[1];
num6 += num12 * *ptr3;
num8++;
}
}
}
if (num8 == num2)
{
num7 = divisor;
}
else if (!dynamicDivisorForEdges)
{
num7 = divisor;
}
if (num7 != 0)
{
num4 /= num7;
num5 /= num7;
num6 /= num7;
}
num4 += threshold;
num5 += threshold;
num6 += threshold;
ptr2[2] = (ushort)((num4 > 65535) ? 65535 : ((num4 < 0) ? 0 : num4));
ptr2[1] = (ushort)((num5 > 65535) ? 65535 : ((num5 < 0) ? 0 : num5));
*ptr2 = (ushort)((num6 > 65535) ? 65535 : ((num6 < 0) ? 0 : num6));
if (pixelSize == 4)
{
ptr2[3] = ptr[3];
}
num3++;
ptr += pixelSize;
ptr2 += pixelSize;
}
}
}
private unsafe void Process64bppImage(ushort* baseSrc, ushort* baseDst, int srcStride, int dstStride, int startX, int startY, int stopX, int stopY)
{
int num = size >> 1;
int num2 = size * size;
for (int i = startY; i < stopY; i++)
{
ushort* ptr = baseSrc + i * srcStride;
ushort* ptr2 = baseDst + i * dstStride;
int num3 = startX;
while (num3 < stopX)
{
long num8;
int num9;
long num5;
long num6;
long num7;
long num4 = (num5 = (num6 = (num7 = (num8 = (num9 = 0)))));
for (int j = 0; j < size; j++)
{
int num10 = j - num;
int num11 = i + num10;
if (num11 < startY)
{
continue;
}
if (num11 >= stopY)
{
break;
}
for (int k = 0; k < size; k++)
{
int num12 = k - num;
num11 = num3 + num12;
if (num11 >= startX && num11 < stopX)
{
int num13 = kernel[j, k];
ushort* ptr3 = ptr + (num10 * srcStride + num12 * 4);
num8 += num13;
num4 += num13 * ptr3[2];
num5 += num13 * ptr3[1];
num6 += num13 * *ptr3;
num7 += num13 * ptr3[3];
num9++;
}
}
}
if (num9 == num2)
{
num8 = divisor;
}
else if (!dynamicDivisorForEdges)
{
num8 = divisor;
}
if (num8 != 0)
{
num4 /= num8;
num5 /= num8;
num6 /= num8;
num7 /= num8;
}
num4 += threshold;
num5 += threshold;
num6 += threshold;
num7 += threshold;
ptr2[2] = (ushort)((num4 > 65535) ? 65535 : ((num4 < 0) ? 0 : num4));
ptr2[1] = (ushort)((num5 > 65535) ? 65535 : ((num5 < 0) ? 0 : num5));
*ptr2 = (ushort)((num6 > 65535) ? 65535 : ((num6 < 0) ? 0 : num6));
ptr2[3] = (ushort)((num7 > 65535) ? 65535 : ((num7 < 0) ? 0 : num7));
num3++;
ptr += 4;
ptr2 += 4;
}
}
}
}

View File

@@ -0,0 +1,64 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class CornersMarker : BaseInPlaceFilter
{
private Color markerColor = Color.White;
private ICornersDetector detector;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public Color MarkerColor
{
get
{
return markerColor;
}
set
{
markerColor = value;
}
}
public ICornersDetector Detector
{
get
{
return detector;
}
set
{
detector = value;
}
}
public CornersMarker(ICornersDetector detector)
: this(detector, Color.White)
{
}
public CornersMarker(ICornersDetector detector, Color markerColor)
{
this.detector = detector;
this.markerColor = markerColor;
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
}
protected override void ProcessFilter(UnmanagedImage image)
{
List<IntPoint> list = detector.ProcessImage(image);
foreach (IntPoint item in list)
{
Drawing.FillRectangle(image, new Rectangle(item.X - 1, item.Y - 1, 3, 3), markerColor);
}
}
}

View File

@@ -0,0 +1,74 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class Crop : BaseTransformationFilter
{
private Rectangle rect;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public Rectangle Rectangle
{
get
{
return rect;
}
set
{
rect = value;
}
}
public Crop(Rectangle rect)
{
this.rect = rect;
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
formatTranslations[(PixelFormat)1052676] = (PixelFormat)1052676;
formatTranslations[(PixelFormat)1060876] = (PixelFormat)1060876;
formatTranslations[(PixelFormat)3424269] = (PixelFormat)3424269;
}
protected override Size CalculateNewImageSize(UnmanagedImage sourceData)
{
return new Size(rect.Width, rect.Height);
}
protected unsafe override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData)
{
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
Rectangle rectangle = rect;
rectangle.Intersect(new Rectangle(0, 0, sourceData.Width, sourceData.Height));
int left = rectangle.Left;
int top = rectangle.Top;
int num = rectangle.Bottom - 1;
int width = rectangle.Width;
int stride = sourceData.Stride;
int stride2 = destinationData.Stride;
int num2 = Image.GetPixelFormatSize(sourceData.PixelFormat) / 8;
int count = width * num2;
byte* ptr = (byte*)sourceData.ImageData.ToPointer() + (nint)top * (nint)stride + (nint)left * (nint)num2;
byte* ptr2 = (byte*)destinationData.ImageData.ToPointer();
if (rect.Top < 0)
{
ptr2 -= (nint)stride2 * (nint)rect.Top;
}
if (rect.Left < 0)
{
ptr2 -= (nint)num2 * (nint)rect.Left;
}
for (int i = top; i <= num; i++)
{
SystemTools.CopyUnmanagedMemory(ptr2, ptr, count);
ptr += stride;
ptr2 += stride2;
}
}
}

View File

@@ -0,0 +1,109 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public sealed class Difference : BaseInPlaceFilter2
{
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public Difference()
{
InitFormatTranslations();
}
public Difference(Bitmap overlayImage)
: base(overlayImage)
{
InitFormatTranslations();
}
public Difference(UnmanagedImage unmanagedOverlayImage)
: base(unmanagedOverlayImage)
{
InitFormatTranslations();
}
private void InitFormatTranslations()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
formatTranslations[(PixelFormat)1052676] = (PixelFormat)1052676;
formatTranslations[(PixelFormat)1060876] = (PixelFormat)1060876;
formatTranslations[(PixelFormat)3424269] = (PixelFormat)3424269;
}
protected unsafe override void ProcessFilter(UnmanagedImage image, UnmanagedImage overlay)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Invalid comparison between Unknown and I4
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Invalid comparison between Unknown and I4
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Invalid comparison between Unknown and I4
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Invalid comparison between Unknown and I4
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Invalid comparison between Unknown and I4
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Invalid comparison between Unknown and I4
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Invalid comparison between Unknown and I4
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_00f1: Invalid comparison between Unknown and I4
PixelFormat pixelFormat = image.PixelFormat;
int width = image.Width;
int height = image.Height;
if ((int)pixelFormat == 198659 || (int)pixelFormat == 137224 || (int)pixelFormat == 139273 || (int)pixelFormat == 2498570)
{
int num = (((int)pixelFormat == 198659) ? 1 : (((int)pixelFormat == 137224) ? 3 : 4));
int num2 = width * num;
int num3 = image.Stride - num2;
int num4 = overlay.Stride - num2;
byte* ptr = (byte*)image.ImageData.ToPointer();
byte* ptr2 = (byte*)overlay.ImageData.ToPointer();
for (int i = 0; i < height; i++)
{
int num5 = 0;
while (num5 < num2)
{
int num6 = *ptr - *ptr2;
*ptr = ((num6 < 0) ? ((byte)(-num6)) : ((byte)num6));
num5++;
ptr++;
ptr2++;
}
ptr += num3;
ptr2 += num4;
}
return;
}
int num7 = (((int)pixelFormat == 1052676) ? 1 : (((int)pixelFormat == 1060876) ? 3 : 4));
int num8 = width * num7;
int stride = image.Stride;
int stride2 = overlay.Stride;
byte* ptr3 = (byte*)image.ImageData.ToPointer();
byte* ptr4 = (byte*)overlay.ImageData.ToPointer();
for (int j = 0; j < height; j++)
{
ushort* ptr5 = (ushort*)(ptr3 + (nint)j * (nint)stride);
ushort* ptr6 = (ushort*)(ptr4 + (nint)j * (nint)stride2);
int num9 = 0;
while (num9 < num8)
{
int num6 = *ptr5 - *ptr6;
*ptr5 = ((num6 < 0) ? ((ushort)(-num6)) : ((ushort)num6));
num9++;
ptr5++;
ptr6++;
}
}
}
}

View File

@@ -0,0 +1,79 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class DifferenceEdgeDetector : BaseUsingCopyPartialFilter
{
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public DifferenceEdgeDetector()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
}
protected unsafe override void ProcessFilter(UnmanagedImage source, UnmanagedImage destination, Rectangle rect)
{
int num = rect.Left + 1;
int num2 = rect.Top + 1;
int num3 = num + rect.Width - 2;
int num4 = num2 + rect.Height - 2;
int stride = destination.Stride;
int stride2 = source.Stride;
int num5 = stride - rect.Width + 2;
int num6 = stride2 - rect.Width + 2;
byte* ptr = (byte*)source.ImageData.ToPointer();
byte* ptr2 = (byte*)destination.ImageData.ToPointer();
ptr += stride2 * num2 + num;
ptr2 += stride * num2 + num;
for (int i = num2; i < num4; i++)
{
int num7 = num;
while (num7 < num3)
{
int num8 = ptr[-stride2 - 1] - ptr[stride2 + 1];
if (num8 < 0)
{
num8 = -num8;
}
int num9 = ptr[-stride2 + 1] - ptr[stride2 - 1];
if (num9 < 0)
{
num9 = -num9;
}
if (num9 > num8)
{
num8 = num9;
}
num9 = ptr[-stride2] - ptr[stride2];
if (num9 < 0)
{
num9 = -num9;
}
if (num9 > num8)
{
num8 = num9;
}
num9 = ptr[-1] - ptr[1];
if (num9 < 0)
{
num9 = -num9;
}
if (num9 > num8)
{
num8 = num9;
}
*ptr2 = (byte)num8;
num7++;
ptr++;
ptr2++;
}
ptr += num6;
ptr2 += num5;
}
Drawing.Rectangle(destination, rect, Color.Black);
}
}

View File

@@ -0,0 +1,282 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class Dilatation : BaseUsingCopyPartialFilter
{
private short[,] se = new short[3, 3]
{
{ 1, 1, 1 },
{ 1, 1, 1 },
{ 1, 1, 1 }
};
private int size = 3;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public Dilatation()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)1052676] = (PixelFormat)1052676;
formatTranslations[(PixelFormat)1060876] = (PixelFormat)1060876;
}
public Dilatation(short[,] se)
: this()
{
int length = se.GetLength(0);
if (length != se.GetLength(1) || length < 3 || length > 99 || length % 2 == 0)
{
throw new ArgumentException("Invalid size of structuring element.");
}
this.se = se;
size = length;
}
protected unsafe override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData, Rectangle rect)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Invalid comparison between Unknown and I4
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Invalid comparison between Unknown and I4
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Invalid comparison between Unknown and I4
//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
//IL_02b9: Invalid comparison between Unknown and I4
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Invalid comparison between Unknown and I4
//IL_030f: Unknown result type (might be due to invalid IL or missing references)
//IL_0315: Invalid comparison between Unknown and I4
PixelFormat pixelFormat = sourceData.PixelFormat;
int left = rect.Left;
int top = rect.Top;
int num = left + rect.Width;
int num2 = top + rect.Height;
int num3 = size >> 1;
if ((int)pixelFormat == 198659 || (int)pixelFormat == 137224)
{
int num4 = (((int)pixelFormat == 198659) ? 1 : 3);
int stride = destinationData.Stride;
int stride2 = sourceData.Stride;
byte* ptr = (byte*)sourceData.ImageData.ToPointer();
byte* ptr2 = (byte*)destinationData.ImageData.ToPointer();
ptr += (nint)left * (nint)num4;
ptr2 += (nint)left * (nint)num4;
if ((int)pixelFormat == 198659)
{
for (int i = top; i < num2; i++)
{
byte* ptr3 = ptr + (nint)i * (nint)stride2;
byte* ptr4 = ptr2 + (nint)i * (nint)stride;
int num5 = left;
while (num5 < num)
{
byte b = 0;
for (int j = 0; j < size; j++)
{
int num6 = j - num3;
int num7 = i + num6;
if (num7 < top)
{
continue;
}
if (num7 >= num2)
{
break;
}
for (int k = 0; k < size; k++)
{
int num8 = k - num3;
num7 = num5 + num8;
if (num7 >= left && num7 < num && se[j, k] == 1)
{
byte b2 = ptr3[num6 * stride2 + num8];
if (b2 > b)
{
b = b2;
}
}
}
}
*ptr4 = b;
num5++;
ptr3++;
ptr4++;
}
}
return;
}
for (int l = top; l < num2; l++)
{
byte* ptr5 = ptr + (nint)l * (nint)stride2;
byte* ptr6 = ptr2 + (nint)l * (nint)stride;
int num9 = left;
while (num9 < num)
{
byte b4;
byte b5;
byte b3 = (b4 = (b5 = 0));
for (int m = 0; m < size; m++)
{
int num10 = m - num3;
int num11 = l + num10;
if (num11 < top)
{
continue;
}
if (num11 >= num2)
{
break;
}
for (int n = 0; n < size; n++)
{
int num12 = n - num3;
num11 = num9 + num12;
if (num11 >= left && num11 < num && se[m, n] == 1)
{
byte* ptr7 = ptr5 + (num10 * stride2 + num12 * 3);
byte b6 = ptr7[2];
if (b6 > b3)
{
b3 = b6;
}
b6 = ptr7[1];
if (b6 > b4)
{
b4 = b6;
}
b6 = *ptr7;
if (b6 > b5)
{
b5 = b6;
}
}
}
}
ptr6[2] = b3;
ptr6[1] = b4;
*ptr6 = b5;
num9++;
ptr5 += 3;
ptr6 += 3;
}
}
return;
}
int num13 = (((int)pixelFormat == 1052676) ? 1 : 3);
int num14 = destinationData.Stride / 2;
int num15 = sourceData.Stride / 2;
ushort* ptr8 = (ushort*)sourceData.ImageData.ToPointer();
ushort* ptr9 = (ushort*)destinationData.ImageData.ToPointer();
ptr8 += left * num13;
ptr9 += left * num13;
if ((int)pixelFormat == 1052676)
{
for (int num16 = top; num16 < num2; num16++)
{
ushort* ptr10 = ptr8 + num16 * num15;
ushort* ptr11 = ptr9 + num16 * num14;
int num17 = left;
while (num17 < num)
{
ushort num18 = 0;
for (int num19 = 0; num19 < size; num19++)
{
int num20 = num19 - num3;
int num21 = num16 + num20;
if (num21 < top)
{
continue;
}
if (num21 >= num2)
{
break;
}
for (int num22 = 0; num22 < size; num22++)
{
int num23 = num22 - num3;
num21 = num17 + num23;
if (num21 >= left && num21 < num && se[num19, num22] == 1)
{
ushort num24 = ptr10[num20 * num15 + num23];
if (num24 > num18)
{
num18 = num24;
}
}
}
}
*ptr11 = num18;
num17++;
ptr10++;
ptr11++;
}
}
return;
}
for (int num25 = top; num25 < num2; num25++)
{
ushort* ptr12 = ptr8 + num25 * num15;
ushort* ptr13 = ptr9 + num25 * num14;
int num26 = left;
while (num26 < num)
{
ushort num28;
ushort num29;
ushort num27 = (num28 = (num29 = 0));
for (int num30 = 0; num30 < size; num30++)
{
int num31 = num30 - num3;
int num32 = num25 + num31;
if (num32 < top)
{
continue;
}
if (num32 >= num2)
{
break;
}
for (int num33 = 0; num33 < size; num33++)
{
int num34 = num33 - num3;
num32 = num26 + num34;
if (num32 >= left && num32 < num && se[num30, num33] == 1)
{
ushort* ptr14 = ptr12 + (num31 * num15 + num34 * 3);
ushort num35 = ptr14[2];
if (num35 > num27)
{
num27 = num35;
}
num35 = ptr14[1];
if (num35 > num28)
{
num28 = num35;
}
num35 = *ptr14;
if (num35 > num29)
{
num29 = num35;
}
}
}
}
ptr13[2] = num27;
ptr13[1] = num28;
*ptr13 = num29;
num26++;
ptr12 += 3;
ptr13 += 3;
}
}
}
}

View File

@@ -0,0 +1,250 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class Dilatation3x3 : BaseUsingCopyPartialFilter
{
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public Dilatation3x3()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
}
protected unsafe override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData, Rectangle rect)
{
if (rect.Width < 3 || rect.Height < 3)
{
throw new InvalidImagePropertiesException("Processing rectangle mast be at least 3x3 in size.");
}
int num = rect.Left + 1;
int num2 = rect.Top + 1;
int num3 = rect.Right - 1;
int num4 = rect.Bottom - 1;
int stride = destinationData.Stride;
int stride2 = sourceData.Stride;
int num5 = stride - rect.Width + 1;
int num6 = stride2 - rect.Width + 1;
byte* ptr = (byte*)sourceData.ImageData.ToPointer();
byte* ptr2 = (byte*)destinationData.ImageData.ToPointer();
ptr += num - 1 + (num2 - 1) * stride2;
ptr2 += num - 1 + (num2 - 1) * stride;
byte b = *ptr;
if (ptr[1] > b)
{
b = ptr[1];
}
if (ptr[stride2] > b)
{
b = ptr[stride2];
}
if (ptr[stride2 + 1] > b)
{
b = ptr[stride2 + 1];
}
*ptr2 = b;
ptr++;
ptr2++;
int num7 = num;
while (num7 < num3)
{
b = *ptr;
if (ptr[-1] > b)
{
b = ptr[-1];
}
if (ptr[1] > b)
{
b = ptr[1];
}
if (ptr[stride2 - 1] > b)
{
b = ptr[stride2 - 1];
}
if (ptr[stride2] > b)
{
b = ptr[stride2];
}
if (ptr[stride2 + 1] > b)
{
b = ptr[stride2 + 1];
}
*ptr2 = b;
num7++;
ptr++;
ptr2++;
}
b = *ptr;
if (ptr[-1] > b)
{
b = ptr[-1];
}
if (ptr[stride2 - 1] > b)
{
b = ptr[stride2 - 1];
}
if (ptr[stride2] > b)
{
b = ptr[stride2];
}
*ptr2 = b;
ptr += num6;
ptr2 += num5;
for (int i = num2; i < num4; i++)
{
b = *ptr;
if (ptr[1] > b)
{
b = ptr[1];
}
if (ptr[-stride2] > b)
{
b = ptr[-stride2];
}
if (ptr[-stride2 + 1] > b)
{
b = ptr[-stride2 + 1];
}
if (ptr[stride2] > b)
{
b = ptr[stride2];
}
if (ptr[stride2 + 1] > b)
{
b = ptr[stride2 + 1];
}
*ptr2 = b;
ptr++;
ptr2++;
int num8 = num;
while (num8 < num3)
{
b = *ptr;
if (ptr[-1] > b)
{
b = ptr[-1];
}
if (ptr[1] > b)
{
b = ptr[1];
}
if (ptr[-stride2 - 1] > b)
{
b = ptr[-stride2 - 1];
}
if (ptr[-stride2] > b)
{
b = ptr[-stride2];
}
if (ptr[-stride2 + 1] > b)
{
b = ptr[-stride2 + 1];
}
if (ptr[stride2 - 1] > b)
{
b = ptr[stride2 - 1];
}
if (ptr[stride2] > b)
{
b = ptr[stride2];
}
if (ptr[stride2 + 1] > b)
{
b = ptr[stride2 + 1];
}
*ptr2 = b;
num8++;
ptr++;
ptr2++;
}
b = *ptr;
if (ptr[-1] > b)
{
b = ptr[-1];
}
if (ptr[-stride2 - 1] > b)
{
b = ptr[-stride2 - 1];
}
if (ptr[-stride2] > b)
{
b = ptr[-stride2];
}
if (ptr[stride2 - 1] > b)
{
b = ptr[stride2 - 1];
}
if (ptr[stride2] > b)
{
b = ptr[stride2];
}
*ptr2 = b;
ptr += num6;
ptr2 += num5;
}
*ptr2 = (byte)(*ptr | ptr[1] | ptr[-stride2] | ptr[-stride2 + 1]);
b = *ptr;
if (ptr[1] > b)
{
b = ptr[1];
}
if (ptr[-stride2] > b)
{
b = ptr[-stride2];
}
if (ptr[-stride2 + 1] > b)
{
b = ptr[-stride2 + 1];
}
*ptr2 = b;
ptr++;
ptr2++;
int num9 = num;
while (num9 < num3)
{
b = *ptr;
if (ptr[-1] > b)
{
b = ptr[-1];
}
if (ptr[1] > b)
{
b = ptr[1];
}
if (ptr[-stride2 - 1] > b)
{
b = ptr[-stride2 - 1];
}
if (ptr[-stride2] > b)
{
b = ptr[-stride2];
}
if (ptr[-stride2 + 1] > b)
{
b = ptr[-stride2 + 1];
}
*ptr2 = b;
num9++;
ptr++;
ptr2++;
}
b = *ptr;
if (ptr[-1] > b)
{
b = ptr[-1];
}
if (ptr[-stride2 - 1] > b)
{
b = ptr[-stride2 - 1];
}
if (ptr[-stride2] > b)
{
b = ptr[-stride2];
}
*ptr2 = b;
}
}

View File

@@ -0,0 +1,14 @@
namespace AForge.Imaging.Filters;
public sealed class Edges : Convolution
{
public Edges()
: base(new int[3, 3]
{
{ 0, -1, 0 },
{ -1, 4, -1 },
{ 0, -1, 0 }
})
{
}
}

View File

@@ -0,0 +1,282 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class Erosion : BaseUsingCopyPartialFilter
{
private short[,] se = new short[3, 3]
{
{ 1, 1, 1 },
{ 1, 1, 1 },
{ 1, 1, 1 }
};
private int size = 3;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public Erosion()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)1052676] = (PixelFormat)1052676;
formatTranslations[(PixelFormat)1060876] = (PixelFormat)1060876;
}
public Erosion(short[,] se)
: this()
{
int length = se.GetLength(0);
if (length != se.GetLength(1) || length < 3 || length > 99 || length % 2 == 0)
{
throw new ArgumentException("Invalid size of structuring element.");
}
this.se = se;
size = length;
}
protected unsafe override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData, Rectangle rect)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Invalid comparison between Unknown and I4
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Invalid comparison between Unknown and I4
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Invalid comparison between Unknown and I4
//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
//IL_02c1: Invalid comparison between Unknown and I4
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Invalid comparison between Unknown and I4
//IL_0317: Unknown result type (might be due to invalid IL or missing references)
//IL_031d: Invalid comparison between Unknown and I4
PixelFormat pixelFormat = sourceData.PixelFormat;
int left = rect.Left;
int top = rect.Top;
int num = left + rect.Width;
int num2 = top + rect.Height;
int num3 = size >> 1;
if ((int)pixelFormat == 198659 || (int)pixelFormat == 137224)
{
int num4 = (((int)pixelFormat == 198659) ? 1 : 3);
int stride = destinationData.Stride;
int stride2 = sourceData.Stride;
byte* ptr = (byte*)sourceData.ImageData.ToPointer();
byte* ptr2 = (byte*)destinationData.ImageData.ToPointer();
ptr += (nint)left * (nint)num4;
ptr2 += (nint)left * (nint)num4;
if ((int)pixelFormat == 198659)
{
for (int i = top; i < num2; i++)
{
byte* ptr3 = ptr + (nint)i * (nint)stride2;
byte* ptr4 = ptr2 + (nint)i * (nint)stride;
int num5 = left;
while (num5 < num)
{
byte b = byte.MaxValue;
for (int j = 0; j < size; j++)
{
int num6 = j - num3;
int num7 = i + num6;
if (num7 < top)
{
continue;
}
if (num7 >= num2)
{
break;
}
for (int k = 0; k < size; k++)
{
int num8 = k - num3;
num7 = num5 + num8;
if (num7 >= left && num7 < num && se[j, k] == 1)
{
byte b2 = ptr3[num6 * stride2 + num8];
if (b2 < b)
{
b = b2;
}
}
}
}
*ptr4 = b;
num5++;
ptr3++;
ptr4++;
}
}
return;
}
for (int l = top; l < num2; l++)
{
byte* ptr5 = ptr + (nint)l * (nint)stride2;
byte* ptr6 = ptr2 + (nint)l * (nint)stride;
int num9 = left;
while (num9 < num)
{
byte b4;
byte b5;
byte b3 = (b4 = (b5 = byte.MaxValue));
for (int m = 0; m < size; m++)
{
int num10 = m - num3;
int num11 = l + num10;
if (num11 < top)
{
continue;
}
if (num11 >= num2)
{
break;
}
for (int n = 0; n < size; n++)
{
int num12 = n - num3;
num11 = num9 + num12;
if (num11 >= left && num11 < num && se[m, n] == 1)
{
byte* ptr7 = ptr5 + (num10 * stride2 + num12 * 3);
byte b6 = ptr7[2];
if (b6 < b3)
{
b3 = b6;
}
b6 = ptr7[1];
if (b6 < b4)
{
b4 = b6;
}
b6 = *ptr7;
if (b6 < b5)
{
b5 = b6;
}
}
}
}
ptr6[2] = b3;
ptr6[1] = b4;
*ptr6 = b5;
num9++;
ptr5 += 3;
ptr6 += 3;
}
}
return;
}
int num13 = (((int)pixelFormat == 1052676) ? 1 : 3);
int num14 = destinationData.Stride / 2;
int num15 = sourceData.Stride / 2;
ushort* ptr8 = (ushort*)sourceData.ImageData.ToPointer();
ushort* ptr9 = (ushort*)destinationData.ImageData.ToPointer();
ptr8 += left * num13;
ptr9 += left * num13;
if ((int)pixelFormat == 1052676)
{
for (int num16 = top; num16 < num2; num16++)
{
ushort* ptr10 = ptr8 + num16 * num15;
ushort* ptr11 = ptr9 + num16 * num14;
int num17 = left;
while (num17 < num)
{
ushort num18 = ushort.MaxValue;
for (int num19 = 0; num19 < size; num19++)
{
int num20 = num19 - num3;
int num21 = num16 + num20;
if (num21 < top)
{
continue;
}
if (num21 >= num2)
{
break;
}
for (int num22 = 0; num22 < size; num22++)
{
int num23 = num22 - num3;
num21 = num17 + num23;
if (num21 >= left && num21 < num && se[num19, num22] == 1)
{
ushort num24 = ptr10[num20 * num15 + num23];
if (num24 < num18)
{
num18 = num24;
}
}
}
}
*ptr11 = num18;
num17++;
ptr10++;
ptr11++;
}
}
return;
}
for (int num25 = top; num25 < num2; num25++)
{
ushort* ptr12 = ptr8 + num25 * num15;
ushort* ptr13 = ptr9 + num25 * num14;
int num26 = left;
while (num26 < num)
{
ushort num28;
ushort num29;
ushort num27 = (num28 = (num29 = ushort.MaxValue));
for (int num30 = 0; num30 < size; num30++)
{
int num31 = num30 - num3;
int num32 = num25 + num31;
if (num32 < top)
{
continue;
}
if (num32 >= num2)
{
break;
}
for (int num33 = 0; num33 < size; num33++)
{
int num34 = num33 - num3;
num32 = num26 + num34;
if (num32 >= left && num32 < num && se[num30, num33] == 1)
{
ushort* ptr14 = ptr12 + (num31 * num15 + num34 * 3);
ushort num35 = ptr14[2];
if (num35 < num27)
{
num27 = num35;
}
num35 = ptr14[1];
if (num35 < num28)
{
num28 = num35;
}
num35 = *ptr14;
if (num35 < num29)
{
num29 = num35;
}
}
}
}
ptr13[2] = num27;
ptr13[1] = num28;
*ptr13 = num29;
num26++;
ptr12 += 3;
ptr13 += 3;
}
}
}
}

View File

@@ -0,0 +1,250 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class Erosion3x3 : BaseUsingCopyPartialFilter
{
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public Erosion3x3()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
}
protected unsafe override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData, Rectangle rect)
{
if (rect.Width < 3 || rect.Height < 3)
{
throw new InvalidImagePropertiesException("Processing rectangle mast be at least 3x3 in size.");
}
int num = rect.Left + 1;
int num2 = rect.Top + 1;
int num3 = rect.Right - 1;
int num4 = rect.Bottom - 1;
int stride = destinationData.Stride;
int stride2 = sourceData.Stride;
int num5 = stride - rect.Width + 1;
int num6 = stride2 - rect.Width + 1;
byte* ptr = (byte*)sourceData.ImageData.ToPointer();
byte* ptr2 = (byte*)destinationData.ImageData.ToPointer();
ptr += num - 1 + (num2 - 1) * stride2;
ptr2 += num - 1 + (num2 - 1) * stride;
byte b = *ptr;
if (ptr[1] < b)
{
b = ptr[1];
}
if (ptr[stride2] < b)
{
b = ptr[stride2];
}
if (ptr[stride2 + 1] < b)
{
b = ptr[stride2 + 1];
}
*ptr2 = b;
ptr++;
ptr2++;
int num7 = num;
while (num7 < num3)
{
b = *ptr;
if (ptr[-1] < b)
{
b = ptr[-1];
}
if (ptr[1] < b)
{
b = ptr[1];
}
if (ptr[stride2 - 1] < b)
{
b = ptr[stride2 - 1];
}
if (ptr[stride2] < b)
{
b = ptr[stride2];
}
if (ptr[stride2 + 1] < b)
{
b = ptr[stride2 + 1];
}
*ptr2 = b;
num7++;
ptr++;
ptr2++;
}
b = *ptr;
if (ptr[-1] < b)
{
b = ptr[-1];
}
if (ptr[stride2 - 1] < b)
{
b = ptr[stride2 - 1];
}
if (ptr[stride2] < b)
{
b = ptr[stride2];
}
*ptr2 = b;
ptr += num6;
ptr2 += num5;
for (int i = num2; i < num4; i++)
{
b = *ptr;
if (ptr[1] < b)
{
b = ptr[1];
}
if (ptr[-stride2] < b)
{
b = ptr[-stride2];
}
if (ptr[-stride2 + 1] < b)
{
b = ptr[-stride2 + 1];
}
if (ptr[stride2] < b)
{
b = ptr[stride2];
}
if (ptr[stride2 + 1] < b)
{
b = ptr[stride2 + 1];
}
*ptr2 = b;
ptr++;
ptr2++;
int num8 = num;
while (num8 < num3)
{
b = *ptr;
if (ptr[-1] < b)
{
b = ptr[-1];
}
if (ptr[1] < b)
{
b = ptr[1];
}
if (ptr[-stride2 - 1] < b)
{
b = ptr[-stride2 - 1];
}
if (ptr[-stride2] < b)
{
b = ptr[-stride2];
}
if (ptr[-stride2 + 1] < b)
{
b = ptr[-stride2 + 1];
}
if (ptr[stride2 - 1] < b)
{
b = ptr[stride2 - 1];
}
if (ptr[stride2] < b)
{
b = ptr[stride2];
}
if (ptr[stride2 + 1] < b)
{
b = ptr[stride2 + 1];
}
*ptr2 = b;
num8++;
ptr++;
ptr2++;
}
b = *ptr;
if (ptr[-1] < b)
{
b = ptr[-1];
}
if (ptr[-stride2 - 1] < b)
{
b = ptr[-stride2 - 1];
}
if (ptr[-stride2] < b)
{
b = ptr[-stride2];
}
if (ptr[stride2 - 1] < b)
{
b = ptr[stride2 - 1];
}
if (ptr[stride2] < b)
{
b = ptr[stride2];
}
*ptr2 = b;
ptr += num6;
ptr2 += num5;
}
*ptr2 = (byte)(*ptr | ptr[1] | ptr[-stride2] | ptr[-stride2 + 1]);
b = *ptr;
if (ptr[1] < b)
{
b = ptr[1];
}
if (ptr[-stride2] < b)
{
b = ptr[-stride2];
}
if (ptr[-stride2 + 1] < b)
{
b = ptr[-stride2 + 1];
}
*ptr2 = b;
ptr++;
ptr2++;
int num9 = num;
while (num9 < num3)
{
b = *ptr;
if (ptr[-1] < b)
{
b = ptr[-1];
}
if (ptr[1] < b)
{
b = ptr[1];
}
if (ptr[-stride2 - 1] < b)
{
b = ptr[-stride2 - 1];
}
if (ptr[-stride2] < b)
{
b = ptr[-stride2];
}
if (ptr[-stride2 + 1] < b)
{
b = ptr[-stride2 + 1];
}
*ptr2 = b;
num9++;
ptr++;
ptr2++;
}
b = *ptr;
if (ptr[-1] < b)
{
b = ptr[-1];
}
if (ptr[-stride2 - 1] < b)
{
b = ptr[-stride2 - 1];
}
if (ptr[-stride2] < b)
{
b = ptr[-stride2];
}
*ptr2 = b;
}
}

View File

@@ -0,0 +1,82 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public abstract class ErrorDiffusionDithering : BaseInPlacePartialFilter
{
private byte threshold = 128;
protected int x;
protected int y;
protected int startX;
protected int startY;
protected int stopX;
protected int stopY;
protected int stride;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public byte ThresholdValue
{
get
{
return threshold;
}
set
{
threshold = value;
}
}
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
protected ErrorDiffusionDithering()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
}
protected unsafe abstract void Diffuse(int error, byte* ptr);
protected unsafe override void ProcessFilter(UnmanagedImage image, Rectangle rect)
{
startX = rect.Left;
startY = rect.Top;
stopX = startX + rect.Width;
stopY = startY + rect.Height;
stride = image.Stride;
int num = stride - rect.Width;
byte* ptr = (byte*)image.ImageData.ToPointer();
ptr += startY * stride + startX;
for (y = startY; y < stopY; y++)
{
x = startX;
while (x < stopX)
{
int num2 = *ptr;
int error;
if (num2 >= threshold)
{
*ptr = byte.MaxValue;
error = num2 - 255;
}
else
{
*ptr = 0;
error = num2;
}
Diffuse(error, ptr);
x++;
ptr++;
}
ptr += num;
}
}
}

View File

@@ -0,0 +1,83 @@
namespace AForge.Imaging.Filters;
public class ErrorDiffusionToAdjacentNeighbors : ErrorDiffusionDithering
{
private int[][] coefficients;
private int coefficientsSum;
public int[][] Coefficients
{
get
{
return coefficients;
}
set
{
coefficients = value;
CalculateCoefficientsSum();
}
}
public ErrorDiffusionToAdjacentNeighbors(int[][] coefficients)
{
this.coefficients = coefficients;
CalculateCoefficientsSum();
}
protected unsafe override void Diffuse(int error, byte* ptr)
{
int[] array = coefficients[0];
int num = 1;
int i = 0;
for (int num2 = array.Length; i < num2; i++)
{
if (x + num >= stopX)
{
break;
}
int num3 = ptr[num] + error * array[i] / coefficientsSum;
num3 = ((num3 >= 0) ? ((num3 > 255) ? 255 : num3) : 0);
ptr[num] = (byte)num3;
num++;
}
int j = 1;
for (int num4 = coefficients.Length; j < num4 && y + j < stopY; j++)
{
ptr += stride;
array = coefficients[j];
int k = 0;
int num5 = array.Length;
int num6 = -(num5 >> 1);
for (; k < num5; k++)
{
if (x + num6 >= stopX)
{
break;
}
if (x + num6 >= startX)
{
int num3 = ptr[num6] + error * array[k] / coefficientsSum;
num3 = ((num3 >= 0) ? ((num3 > 255) ? 255 : num3) : 0);
ptr[num6] = (byte)num3;
}
num6++;
}
}
}
private void CalculateCoefficientsSum()
{
coefficientsSum = 0;
int i = 0;
for (int num = coefficients.Length; i < num; i++)
{
int[] array = coefficients[i];
int j = 0;
for (int num2 = array.Length; j < num2; j++)
{
coefficientsSum += array[j];
}
}
}
}

View File

@@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class EuclideanColorFiltering : BaseInPlacePartialFilter
{
private short radius = 100;
private RGB center = new RGB(byte.MaxValue, byte.MaxValue, byte.MaxValue);
private RGB fill = new RGB(0, 0, 0);
private bool fillOutside = true;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public short Radius
{
get
{
return radius;
}
set
{
radius = System.Math.Max((short)0, System.Math.Min((short)450, value));
}
}
public RGB CenterColor
{
get
{
return center;
}
set
{
center = value;
}
}
public RGB FillColor
{
get
{
return fill;
}
set
{
fill = value;
}
}
public bool FillOutside
{
get
{
return fillOutside;
}
set
{
fillOutside = value;
}
}
public EuclideanColorFiltering()
{
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
}
public EuclideanColorFiltering(RGB center, short radius)
: this()
{
this.center = center;
this.radius = radius;
}
protected unsafe override void ProcessFilter(UnmanagedImage image, Rectangle rect)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
int num = (((int)image.PixelFormat == 137224) ? 3 : 4);
int left = rect.Left;
int top = rect.Top;
int num2 = left + rect.Width;
int num3 = top + rect.Height;
int num4 = image.Stride - rect.Width * num;
int num5 = radius * radius;
int red = center.Red;
int green = center.Green;
int blue = center.Blue;
byte red2 = fill.Red;
byte green2 = fill.Green;
byte blue2 = fill.Blue;
byte* ptr = (byte*)image.ImageData.ToPointer();
ptr += top * image.Stride + left * num;
for (int i = top; i < num3; i++)
{
int num6 = left;
while (num6 < num2)
{
int num7 = red - ptr[2];
int num8 = green - ptr[1];
int num9 = blue - *ptr;
if (num7 * num7 + num8 * num8 + num9 * num9 <= num5)
{
if (!fillOutside)
{
ptr[2] = red2;
ptr[1] = green2;
*ptr = blue2;
}
}
else if (fillOutside)
{
ptr[2] = red2;
ptr[1] = green2;
*ptr = blue2;
}
num6++;
ptr += num;
}
ptr += num4;
}
}
}

View File

@@ -0,0 +1,139 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class ExtractBiggestBlob : IFilter, IFilterInformation
{
private Bitmap originalImage;
private IntPoint blobPosition;
public IntPoint BlobPosition => blobPosition;
public Dictionary<PixelFormat, PixelFormat> FormatTranslations
{
get
{
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
Dictionary<PixelFormat, PixelFormat> dictionary = new Dictionary<PixelFormat, PixelFormat>();
if (originalImage == null)
{
dictionary[(PixelFormat)198659] = (PixelFormat)198659;
dictionary[(PixelFormat)137224] = (PixelFormat)137224;
dictionary[(PixelFormat)2498570] = (PixelFormat)2498570;
dictionary[(PixelFormat)139273] = (PixelFormat)139273;
dictionary[(PixelFormat)925707] = (PixelFormat)925707;
}
else
{
dictionary[(PixelFormat)198659] = ((Image)originalImage).PixelFormat;
dictionary[(PixelFormat)137224] = ((Image)originalImage).PixelFormat;
dictionary[(PixelFormat)2498570] = ((Image)originalImage).PixelFormat;
dictionary[(PixelFormat)139273] = ((Image)originalImage).PixelFormat;
dictionary[(PixelFormat)925707] = ((Image)originalImage).PixelFormat;
}
return dictionary;
}
}
public Bitmap OriginalImage
{
get
{
return originalImage;
}
set
{
originalImage = value;
}
}
public Bitmap Apply(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);
Bitmap val2 = null;
try
{
return Apply(val);
}
finally
{
image.UnlockBits(val);
}
}
public Bitmap Apply(BitmapData imageData)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Invalid comparison between Unknown and I4
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Invalid comparison between Unknown and I4
//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Invalid comparison between Unknown and I4
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_0112: Invalid comparison between Unknown and I4
//IL_011a: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Invalid comparison between Unknown and I4
if (!FormatTranslations.ContainsKey(imageData.PixelFormat))
{
throw new UnsupportedImageFormatException("Source pixel format is not supported by the filter.");
}
BlobCounter blobCounter = new BlobCounter(imageData);
Blob[] objectsInformation = blobCounter.GetObjectsInformation();
int num = 0;
Blob blob = null;
int i = 0;
for (int num2 = objectsInformation.Length; i < num2; i++)
{
int num3 = objectsInformation[i].Rectangle.Width * objectsInformation[i].Rectangle.Height;
if (num3 > num)
{
num = num3;
blob = objectsInformation[i];
}
}
if (blob == null)
{
throw new ArgumentException("The source image does not contain any blobs.");
}
blobPosition = new IntPoint(blob.Rectangle.Left, blob.Rectangle.Top);
if (originalImage == null)
{
blobCounter.ExtractBlobsImage(new UnmanagedImage(imageData), blob, extractInOriginalSize: false);
}
else
{
if ((int)((Image)originalImage).PixelFormat != 137224 && (int)((Image)originalImage).PixelFormat != 2498570 && (int)((Image)originalImage).PixelFormat != 139273 && (int)((Image)originalImage).PixelFormat != 925707 && (int)((Image)originalImage).PixelFormat != 198659)
{
throw new UnsupportedImageFormatException("Original image may be grayscale (8bpp indexed) or color (24/32bpp) image only.");
}
if (((Image)originalImage).Width != imageData.Width || ((Image)originalImage).Height != imageData.Height)
{
throw new InvalidImagePropertiesException("Original image must have the same size as passed source image.");
}
blobCounter.ExtractBlobsImage(originalImage, blob, extractInOriginalSize: false);
}
Bitmap result = blob.Image.ToManagedImage();
blob.Image.Dispose();
return result;
}
public UnmanagedImage Apply(UnmanagedImage image)
{
throw new NotImplementedException("The method is not implemented for the filter.");
}
public void Apply(UnmanagedImage sourceImage, UnmanagedImage destinationImage)
{
throw new NotImplementedException("The method is not implemented filter.");
}
}

View File

@@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class ExtractChannel : BaseFilter
{
private short channel = 2;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public short Channel
{
get
{
return channel;
}
set
{
if (value != 2 && value != 1 && value != 0 && value != 3)
{
throw new ArgumentException("Invalid channel is specified.");
}
channel = value;
}
}
public ExtractChannel()
{
formatTranslations[(PixelFormat)137224] = (PixelFormat)198659;
formatTranslations[(PixelFormat)139273] = (PixelFormat)198659;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)198659;
formatTranslations[(PixelFormat)1060876] = (PixelFormat)1052676;
formatTranslations[(PixelFormat)3424269] = (PixelFormat)1052676;
}
public ExtractChannel(short channel)
: this()
{
Channel = channel;
}
protected unsafe override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
int width = sourceData.Width;
int height = sourceData.Height;
int num = Image.GetPixelFormatSize(sourceData.PixelFormat) / 8;
if (channel == 3 && num != 4 && num != 8)
{
throw new InvalidImagePropertiesException("Can not extract alpha channel from none ARGB image.");
}
if (num <= 4)
{
int num2 = sourceData.Stride - width * num;
int num3 = destinationData.Stride - width;
byte* ptr = (byte*)sourceData.ImageData.ToPointer();
byte* ptr2 = (byte*)destinationData.ImageData.ToPointer();
ptr += channel;
for (int i = 0; i < height; i++)
{
int num4 = 0;
while (num4 < width)
{
*ptr2 = *ptr;
num4++;
ptr += num;
ptr2++;
}
ptr += num2;
ptr2 += num3;
}
return;
}
num /= 2;
byte* ptr3 = (byte*)sourceData.ImageData.ToPointer();
byte* ptr4 = (byte*)destinationData.ImageData.ToPointer();
int stride = sourceData.Stride;
int stride2 = destinationData.Stride;
for (int j = 0; j < height; j++)
{
ushort* ptr5 = (ushort*)(ptr3 + (nint)j * (nint)stride);
ushort* ptr6 = (ushort*)(ptr4 + (nint)j * (nint)stride2);
ptr5 += channel;
int num5 = 0;
while (num5 < width)
{
*ptr6 = *ptr5;
num5++;
ptr5 += num;
ptr6++;
}
}
}
}

View File

@@ -0,0 +1,95 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class ExtractNormalizedRGBChannel : BaseFilter
{
private short channel = 2;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public short Channel
{
get
{
return channel;
}
set
{
if (value != 2 && value != 1 && value != 0)
{
throw new ArgumentException("Invalid channel is specified.");
}
channel = value;
}
}
public ExtractNormalizedRGBChannel()
{
formatTranslations[(PixelFormat)137224] = (PixelFormat)198659;
formatTranslations[(PixelFormat)139273] = (PixelFormat)198659;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)198659;
formatTranslations[(PixelFormat)1060876] = (PixelFormat)1052676;
formatTranslations[(PixelFormat)3424269] = (PixelFormat)1052676;
}
public ExtractNormalizedRGBChannel(short channel)
: this()
{
Channel = channel;
}
protected unsafe override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
int width = sourceData.Width;
int height = sourceData.Height;
int num = Image.GetPixelFormatSize(sourceData.PixelFormat) / 8;
if (num <= 4)
{
int num2 = sourceData.Stride - width * num;
int num3 = destinationData.Stride - width;
byte* ptr = (byte*)sourceData.ImageData.ToPointer();
byte* ptr2 = (byte*)destinationData.ImageData.ToPointer();
for (int i = 0; i < height; i++)
{
int num4 = 0;
while (num4 < width)
{
int num5 = ptr[2] + ptr[1] + *ptr;
*ptr2 = (byte)((num5 != 0) ? ((byte)(255 * ptr[channel] / num5)) : 0);
num4++;
ptr += num;
ptr2++;
}
ptr += num2;
ptr2 += num3;
}
return;
}
num /= 2;
byte* ptr3 = (byte*)sourceData.ImageData.ToPointer();
byte* ptr4 = (byte*)destinationData.ImageData.ToPointer();
int stride = sourceData.Stride;
int stride2 = destinationData.Stride;
for (int j = 0; j < height; j++)
{
ushort* ptr5 = (ushort*)(ptr3 + (nint)j * (nint)stride);
ushort* ptr6 = (ushort*)(ptr4 + (nint)j * (nint)stride2);
int num6 = 0;
while (num6 < width)
{
int num5 = ptr5[2] + ptr5[1] + *ptr5;
*ptr6 = (ushort)((num5 != 0) ? ((ushort)(65535 * ptr5[channel] / num5)) : 0);
num6++;
ptr5 += num;
ptr6++;
}
}
}
}

View File

@@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class FillHoles : BaseInPlaceFilter
{
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
private bool coupledSizeFiltering = true;
private int maxHoleWidth = int.MaxValue;
private int maxHoleHeight = int.MaxValue;
public bool CoupledSizeFiltering
{
get
{
return coupledSizeFiltering;
}
set
{
coupledSizeFiltering = value;
}
}
public int MaxHoleWidth
{
get
{
return maxHoleWidth;
}
set
{
maxHoleWidth = System.Math.Max(value, 0);
}
}
public int MaxHoleHeight
{
get
{
return maxHoleHeight;
}
set
{
maxHoleHeight = System.Math.Max(value, 0);
}
}
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public FillHoles()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
}
protected unsafe override void ProcessFilter(UnmanagedImage image)
{
int width = image.Width;
int height = image.Height;
Invert invert = new Invert();
UnmanagedImage image2 = invert.Apply(image);
BlobCounter blobCounter = new BlobCounter();
blobCounter.ProcessImage(image2);
Blob[] objectsInformation = blobCounter.GetObjectsInformation();
byte[] array = new byte[objectsInformation.Length + 1];
array[0] = byte.MaxValue;
int i = 0;
for (int num = objectsInformation.Length; i < num; i++)
{
Blob blob = objectsInformation[i];
if (blob.Rectangle.Left == 0 || blob.Rectangle.Top == 0 || blob.Rectangle.Right == width || blob.Rectangle.Bottom == height)
{
array[blob.ID] = 0;
}
else if ((coupledSizeFiltering && blob.Rectangle.Width <= maxHoleWidth && blob.Rectangle.Height <= maxHoleHeight) | (!coupledSizeFiltering && (blob.Rectangle.Width <= maxHoleWidth || blob.Rectangle.Height <= maxHoleHeight)))
{
array[blob.ID] = byte.MaxValue;
}
else
{
array[blob.ID] = 0;
}
}
byte* ptr = (byte*)image.ImageData.ToPointer();
int num2 = image.Stride - width;
int[] objectLabels = blobCounter.ObjectLabels;
int j = 0;
int num3 = 0;
for (; j < height; j++)
{
int num4 = 0;
while (num4 < width)
{
*ptr = array[objectLabels[num3]];
num4++;
num3++;
ptr++;
}
ptr += num2;
}
}
}

View File

@@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class FilterIterator : IFilter, IFilterInformation
{
private IFilter baseFilter;
private int iterations = 1;
public Dictionary<PixelFormat, PixelFormat> FormatTranslations => ((IFilterInformation)baseFilter).FormatTranslations;
public IFilter BaseFilter
{
get
{
return baseFilter;
}
set
{
baseFilter = value;
}
}
public int Iterations
{
get
{
return iterations;
}
set
{
iterations = System.Math.Max(1, System.Math.Min(255, value));
}
}
public FilterIterator(IFilter baseFilter)
{
this.baseFilter = baseFilter;
}
public FilterIterator(IFilter baseFilter, int iterations)
{
this.baseFilter = baseFilter;
this.iterations = iterations;
}
public Bitmap Apply(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);
Bitmap result = Apply(val);
image.UnlockBits(val);
return result;
}
public Bitmap Apply(BitmapData imageData)
{
Bitmap val = baseFilter.Apply(imageData);
for (int i = 1; i < iterations; i++)
{
Bitmap val2 = val;
val = baseFilter.Apply(val2);
((Image)val2).Dispose();
}
return val;
}
public UnmanagedImage Apply(UnmanagedImage image)
{
UnmanagedImage unmanagedImage = baseFilter.Apply(image);
for (int i = 1; i < iterations; i++)
{
UnmanagedImage unmanagedImage2 = unmanagedImage;
unmanagedImage = baseFilter.Apply(unmanagedImage2);
unmanagedImage2.Dispose();
}
return unmanagedImage;
}
public void Apply(UnmanagedImage sourceImage, UnmanagedImage destinationImage)
{
if (iterations == 1)
{
baseFilter.Apply(sourceImage, destinationImage);
return;
}
UnmanagedImage unmanagedImage = baseFilter.Apply(sourceImage);
iterations--;
for (int i = 1; i < iterations; i++)
{
UnmanagedImage unmanagedImage2 = unmanagedImage;
unmanagedImage = baseFilter.Apply(unmanagedImage2);
unmanagedImage2.Dispose();
}
baseFilter.Apply(unmanagedImage, destinationImage);
}
}

View File

@@ -0,0 +1,91 @@
using System;
using System.Collections;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class FiltersSequence : CollectionBase, IFilter
{
public IFilter this[int index] => (IFilter)base.InnerList[index];
public FiltersSequence()
{
}
public FiltersSequence(params IFilter[] filters)
{
base.InnerList.AddRange(filters);
}
public void Add(IFilter filter)
{
base.InnerList.Add(filter);
}
public Bitmap Apply(Bitmap image)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
Bitmap val = null;
BitmapData val2 = image.LockBits(new Rectangle(0, 0, ((Image)image).Width, ((Image)image).Height), (ImageLockMode)1, ((Image)image).PixelFormat);
try
{
return Apply(val2);
}
finally
{
image.UnlockBits(val2);
}
}
public Bitmap Apply(BitmapData imageData)
{
UnmanagedImage unmanagedImage = Apply(new UnmanagedImage(imageData));
Bitmap result = unmanagedImage.ToManagedImage();
unmanagedImage.Dispose();
return result;
}
public UnmanagedImage Apply(UnmanagedImage image)
{
int count = base.InnerList.Count;
if (count == 0)
{
throw new ApplicationException("No filters in the sequence.");
}
UnmanagedImage unmanagedImage = null;
UnmanagedImage unmanagedImage2 = null;
unmanagedImage = ((IFilter)base.InnerList[0]).Apply(image);
for (int i = 1; i < count; i++)
{
unmanagedImage2 = unmanagedImage;
unmanagedImage = ((IFilter)base.InnerList[i]).Apply(unmanagedImage2);
unmanagedImage2.Dispose();
}
return unmanagedImage;
}
public void Apply(UnmanagedImage sourceImage, UnmanagedImage destinationImage)
{
int count = base.InnerList.Count;
switch (count)
{
case 0:
throw new ApplicationException("No filters in the sequence.");
case 1:
((IFilter)base.InnerList[0]).Apply(sourceImage, destinationImage);
return;
}
UnmanagedImage unmanagedImage = null;
UnmanagedImage unmanagedImage2 = null;
unmanagedImage = ((IFilter)base.InnerList[0]).Apply(sourceImage);
count--;
for (int i = 1; i < count; i++)
{
unmanagedImage2 = unmanagedImage;
unmanagedImage = ((IFilter)base.InnerList[i]).Apply(unmanagedImage2);
unmanagedImage2.Dispose();
}
((IFilter)base.InnerList[count]).Apply(unmanagedImage, destinationImage);
}
}

View File

@@ -0,0 +1,166 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class FlatFieldCorrection : BaseInPlaceFilter
{
private Bitmap backgroundImage;
private UnmanagedImage unmanagedBackgroundImage;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public Bitmap BackgoundImage
{
get
{
return backgroundImage;
}
set
{
backgroundImage = value;
if (value != null)
{
unmanagedBackgroundImage = null;
}
}
}
public UnmanagedImage UnmanagedBackgoundImage
{
get
{
return unmanagedBackgroundImage;
}
set
{
unmanagedBackgroundImage = value;
if (value != null)
{
backgroundImage = null;
}
}
}
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public FlatFieldCorrection()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
}
public FlatFieldCorrection(Bitmap backgroundImage)
: this()
{
this.backgroundImage = backgroundImage;
}
protected unsafe override void ProcessFilter(UnmanagedImage image)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Invalid comparison between Unknown and I4
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_0162: Invalid comparison between Unknown and I4
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_0112: Unknown result type (might be due to invalid IL or missing references)
UnmanagedImage unmanagedImage = null;
BitmapData val = null;
int width = image.Width;
int height = image.Height;
int num = image.Stride - (((int)image.PixelFormat == 198659) ? width : (width * 3));
if (backgroundImage == null && unmanagedBackgroundImage == null)
{
ResizeBicubic resizeBicubic = new ResizeBicubic(width / 3, height / 3);
UnmanagedImage unmanagedImage2 = resizeBicubic.Apply(image);
GaussianBlur gaussianBlur = new GaussianBlur(5.0, 21);
gaussianBlur.ApplyInPlace(unmanagedImage2);
gaussianBlur.ApplyInPlace(unmanagedImage2);
gaussianBlur.ApplyInPlace(unmanagedImage2);
gaussianBlur.ApplyInPlace(unmanagedImage2);
gaussianBlur.ApplyInPlace(unmanagedImage2);
resizeBicubic.NewWidth = width;
resizeBicubic.NewHeight = height;
unmanagedImage = resizeBicubic.Apply(unmanagedImage2);
unmanagedImage2.Dispose();
}
else if (backgroundImage != null)
{
if (width != ((Image)backgroundImage).Width || height != ((Image)backgroundImage).Height || image.PixelFormat != ((Image)backgroundImage).PixelFormat)
{
throw new InvalidImagePropertiesException("Source image and background images must have the same size and pixel format");
}
val = backgroundImage.LockBits(new Rectangle(0, 0, width, height), (ImageLockMode)1, ((Image)backgroundImage).PixelFormat);
unmanagedImage = new UnmanagedImage(val);
}
else
{
unmanagedImage = unmanagedBackgroundImage;
}
ImageStatistics imageStatistics = new ImageStatistics(unmanagedImage);
byte* ptr = (byte*)image.ImageData.ToPointer();
byte* ptr2 = (byte*)unmanagedImage.ImageData.ToPointer();
if ((int)image.PixelFormat == 198659)
{
double mean = imageStatistics.Gray.Mean;
for (int i = 0; i < height; i++)
{
int num2 = 0;
while (num2 < width)
{
if (*ptr2 != 0)
{
*ptr = (byte)System.Math.Min(mean * (double)(int)(*ptr) / (double)(int)(*ptr2), 255.0);
}
num2++;
ptr++;
ptr2++;
}
ptr += num;
ptr2 += num;
}
}
else
{
double mean2 = imageStatistics.Red.Mean;
double mean3 = imageStatistics.Green.Mean;
double mean4 = imageStatistics.Blue.Mean;
for (int j = 0; j < height; j++)
{
int num3 = 0;
while (num3 < width)
{
if (ptr2[2] != 0)
{
ptr[2] = (byte)System.Math.Min(mean2 * (double)(int)ptr[2] / (double)(int)ptr2[2], 255.0);
}
if (ptr2[1] != 0)
{
ptr[1] = (byte)System.Math.Min(mean3 * (double)(int)ptr[1] / (double)(int)ptr2[1], 255.0);
}
if (*ptr2 != 0)
{
*ptr = (byte)System.Math.Min(mean4 * (double)(int)(*ptr) / (double)(int)(*ptr2), 255.0);
}
num3++;
ptr += 3;
ptr2 += 3;
}
ptr += num;
ptr2 += num;
}
}
if (backgroundImage != null)
{
backgroundImage.UnlockBits(val);
}
if (backgroundImage == null && unmanagedBackgroundImage == null)
{
unmanagedImage.Dispose();
}
}
}

View File

@@ -0,0 +1,13 @@
namespace AForge.Imaging.Filters;
public sealed class FloydSteinbergDithering : ErrorDiffusionToAdjacentNeighbors
{
public FloydSteinbergDithering()
: base(new int[2][]
{
new int[1] { 7 },
new int[3] { 3, 5, 1 }
})
{
}
}

View File

@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class GammaCorrection : BaseInPlacePartialFilter
{
private double gamma;
private byte[] table = new byte[256];
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public double Gamma
{
get
{
return gamma;
}
set
{
gamma = System.Math.Max(0.1, System.Math.Min(5.0, value));
double y = 1.0 / gamma;
for (int i = 0; i < 256; i++)
{
table[i] = (byte)System.Math.Min(255, (int)(System.Math.Pow((double)i / 255.0, y) * 255.0 + 0.5));
}
}
}
public GammaCorrection()
: this(2.2)
{
}
public GammaCorrection(double gamma)
{
Gamma = gamma;
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
}
protected unsafe override void ProcessFilter(UnmanagedImage image, Rectangle rect)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
int num = (((int)image.PixelFormat == 198659) ? 1 : 3);
int num2 = rect.Left * num;
int top = rect.Top;
int num3 = num2 + rect.Width * num;
int num4 = top + rect.Height;
int num5 = image.Stride - rect.Width * num;
byte* ptr = (byte*)image.ImageData.ToPointer();
ptr += top * image.Stride + num2;
for (int i = top; i < num4; i++)
{
int num6 = num2;
while (num6 < num3)
{
*ptr = table[*ptr];
num6++;
ptr++;
}
ptr += num5;
}
}
}

View File

@@ -0,0 +1,80 @@
using System;
using AForge.Math;
namespace AForge.Imaging.Filters;
public sealed class GaussianBlur : Convolution
{
private double sigma = 1.4;
private int size = 5;
public double Sigma
{
get
{
return sigma;
}
set
{
sigma = System.Math.Max(0.5, System.Math.Min(5.0, value));
CreateFilter();
}
}
public int Size
{
get
{
return size;
}
set
{
size = System.Math.Max(3, System.Math.Min(21, value | 1));
CreateFilter();
}
}
public GaussianBlur()
{
CreateFilter();
base.ProcessAlpha = true;
}
public GaussianBlur(double sigma)
{
Sigma = sigma;
base.ProcessAlpha = true;
}
public GaussianBlur(double sigma, int size)
{
Sigma = sigma;
Size = size;
base.ProcessAlpha = true;
}
private void CreateFilter()
{
Gaussian gaussian = new Gaussian(sigma);
double[,] array = gaussian.Kernel2D(size);
double num = array[0, 0];
int[,] array2 = new int[size, size];
int num2 = 0;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
double num3 = array[i, j] / num;
if (num3 > 65535.0)
{
num3 = 65535.0;
}
array2[i, j] = (int)num3;
num2 += array2[i, j];
}
}
base.Kernel = array2;
base.Divisor = num2;
}
}

View File

@@ -0,0 +1,94 @@
using System;
using AForge.Math;
namespace AForge.Imaging.Filters;
public class GaussianSharpen : Convolution
{
private double sigma = 1.4;
private int size = 5;
public double Sigma
{
get
{
return sigma;
}
set
{
sigma = System.Math.Max(0.5, System.Math.Min(5.0, value));
CreateFilter();
}
}
public int Size
{
get
{
return size;
}
set
{
size = System.Math.Max(3, System.Math.Min(21, value | 1));
CreateFilter();
}
}
public GaussianSharpen()
{
CreateFilter();
}
public GaussianSharpen(double sigma)
{
Sigma = sigma;
}
public GaussianSharpen(double sigma, int size)
{
Sigma = sigma;
Size = size;
}
private void CreateFilter()
{
Gaussian gaussian = new Gaussian(sigma);
double[,] array = gaussian.Kernel2D(size);
double num = array[0, 0];
int[,] array2 = new int[size, size];
int num2 = 0;
int num3 = 0;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
double num4 = array[i, j] / num;
if (num4 > 65535.0)
{
num4 = 65535.0;
}
array2[i, j] = (int)num4;
num2 += array2[i, j];
}
}
int num5 = size >> 1;
for (int k = 0; k < size; k++)
{
for (int l = 0; l < size; l++)
{
if (k == num5 && l == num5)
{
array2[k, l] = 2 * num2 - array2[k, l];
}
else
{
array2[k, l] = -array2[k, l];
}
num3 += array2[k, l];
}
}
base.Kernel = array2;
base.Divisor = num3;
}
}

View File

@@ -0,0 +1,100 @@
using System.Collections.Generic;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class Grayscale : BaseFilter
{
public static class CommonAlgorithms
{
public static readonly Grayscale BT709 = new Grayscale(0.2125, 0.7154, 0.0721);
public static readonly Grayscale RMY = new Grayscale(0.5, 0.419, 0.081);
public static readonly Grayscale Y = new Grayscale(0.299, 0.587, 0.114);
}
public readonly double RedCoefficient;
public readonly double GreenCoefficient;
public readonly double BlueCoefficient;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public Grayscale(double cr, double cg, double cb)
{
RedCoefficient = cr;
GreenCoefficient = cg;
BlueCoefficient = cb;
formatTranslations[(PixelFormat)137224] = (PixelFormat)198659;
formatTranslations[(PixelFormat)139273] = (PixelFormat)198659;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)198659;
formatTranslations[(PixelFormat)1060876] = (PixelFormat)1052676;
formatTranslations[(PixelFormat)3424269] = (PixelFormat)1052676;
}
protected unsafe override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData)
{
//IL_000f: 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_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Invalid comparison between Unknown and I4
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Invalid comparison between Unknown and I4
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Invalid comparison between Unknown and I4
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Invalid comparison between Unknown and I4
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Invalid comparison between Unknown and I4
int width = sourceData.Width;
int height = sourceData.Height;
PixelFormat pixelFormat = sourceData.PixelFormat;
if ((int)pixelFormat == 137224 || (int)pixelFormat == 139273 || (int)pixelFormat == 2498570)
{
int num = (((int)pixelFormat == 137224) ? 3 : 4);
int num2 = sourceData.Stride - width * num;
int num3 = destinationData.Stride - width;
int num4 = (int)(65536.0 * RedCoefficient);
int num5 = (int)(65536.0 * GreenCoefficient);
int num6 = (int)(65536.0 * BlueCoefficient);
byte* ptr = (byte*)sourceData.ImageData.ToPointer();
byte* ptr2 = (byte*)destinationData.ImageData.ToPointer();
for (int i = 0; i < height; i++)
{
int num7 = 0;
while (num7 < width)
{
*ptr2 = (byte)(num4 * ptr[2] + num5 * ptr[1] + num6 * *ptr >> 16);
num7++;
ptr += num;
ptr2++;
}
ptr += num2;
ptr2 += num3;
}
return;
}
int num8 = (((int)pixelFormat == 1060876) ? 3 : 4);
byte* ptr3 = (byte*)sourceData.ImageData.ToPointer();
byte* ptr4 = (byte*)destinationData.ImageData.ToPointer();
int stride = sourceData.Stride;
int stride2 = destinationData.Stride;
for (int j = 0; j < height; j++)
{
ushort* ptr5 = (ushort*)(ptr3 + (nint)j * (nint)stride);
ushort* ptr6 = (ushort*)(ptr4 + (nint)j * (nint)stride2);
int num9 = 0;
while (num9 < width)
{
*ptr6 = (ushort)(RedCoefficient * (double)(int)ptr5[2] + GreenCoefficient * (double)(int)ptr5[1] + BlueCoefficient * (double)(int)(*ptr5));
num9++;
ptr5 += num8;
ptr6++;
}
}
}
}

View File

@@ -0,0 +1,12 @@
using System;
namespace AForge.Imaging.Filters;
[Obsolete("Use Grayscale.CommonAlgorithms.BT709 object instead")]
public sealed class GrayscaleBT709 : Grayscale
{
public GrayscaleBT709()
: base(0.2125, 0.7154, 0.0721)
{
}
}

View File

@@ -0,0 +1,12 @@
using System;
namespace AForge.Imaging.Filters;
[Obsolete("Use Grayscale.CommonAlgorithms.RMY object instead")]
public sealed class GrayscaleRMY : Grayscale
{
public GrayscaleRMY()
: base(0.5, 0.419, 0.081)
{
}
}

View File

@@ -0,0 +1,39 @@
using System.Collections.Generic;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public sealed class GrayscaleToRGB : BaseFilter
{
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public GrayscaleToRGB()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)137224;
}
protected unsafe override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData)
{
int width = sourceData.Width;
int height = sourceData.Height;
int num = sourceData.Stride - width;
int num2 = destinationData.Stride - width * 3;
byte* ptr = (byte*)sourceData.ImageData.ToPointer();
byte* ptr2 = (byte*)destinationData.ImageData.ToPointer();
for (int i = 0; i < height; i++)
{
int num3 = 0;
while (num3 < width)
{
ptr2[2] = (ptr2[1] = (*ptr2 = *ptr));
num3++;
ptr++;
ptr2 += 3;
}
ptr += num;
ptr2 += num2;
}
}
}

View File

@@ -0,0 +1,12 @@
using System;
namespace AForge.Imaging.Filters;
[Obsolete("Use Grayscale.CommonAlgorithms.Y object instead")]
public sealed class GrayscaleY : Grayscale
{
public GrayscaleY()
: base(0.299, 0.587, 0.114)
{
}
}

View File

@@ -0,0 +1,218 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class HSLFiltering : BaseInPlacePartialFilter
{
private IntRange hue = new IntRange(0, 359);
private Range saturation = new Range(0f, 1f);
private Range luminance = new Range(0f, 1f);
private int fillH;
private float fillS;
private float fillL;
private bool fillOutsideRange = true;
private bool updateH = true;
private bool updateS = true;
private bool updateL = true;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public IntRange Hue
{
get
{
return hue;
}
set
{
hue = value;
}
}
public Range Saturation
{
get
{
return saturation;
}
set
{
saturation = value;
}
}
public Range Luminance
{
get
{
return luminance;
}
set
{
luminance = value;
}
}
public HSL FillColor
{
get
{
return new HSL(fillH, fillS, fillL);
}
set
{
fillH = value.Hue;
fillS = value.Saturation;
fillL = value.Luminance;
}
}
public bool FillOutsideRange
{
get
{
return fillOutsideRange;
}
set
{
fillOutsideRange = value;
}
}
public bool UpdateHue
{
get
{
return updateH;
}
set
{
updateH = value;
}
}
public bool UpdateSaturation
{
get
{
return updateS;
}
set
{
updateS = value;
}
}
public bool UpdateLuminance
{
get
{
return updateL;
}
set
{
updateL = value;
}
}
public HSLFiltering()
{
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
}
public HSLFiltering(IntRange hue, Range saturation, Range luminance)
: this()
{
this.hue = hue;
this.saturation = saturation;
this.luminance = luminance;
}
protected unsafe override void ProcessFilter(UnmanagedImage image, Rectangle rect)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
int num = (((int)image.PixelFormat == 137224) ? 3 : 4);
int left = rect.Left;
int top = rect.Top;
int num2 = left + rect.Width;
int num3 = top + rect.Height;
int num4 = image.Stride - rect.Width * num;
RGB rGB = new RGB();
HSL hSL = new HSL();
byte* ptr = (byte*)image.ImageData.ToPointer();
ptr += top * image.Stride + left * num;
for (int i = top; i < num3; i++)
{
int num5 = left;
while (num5 < num2)
{
bool flag = false;
rGB.Red = ptr[2];
rGB.Green = ptr[1];
rGB.Blue = *ptr;
HSL.FromRGB(rGB, hSL);
if (hSL.Saturation >= saturation.Min && hSL.Saturation <= saturation.Max && hSL.Luminance >= luminance.Min && hSL.Luminance <= luminance.Max && ((hue.Min < hue.Max && hSL.Hue >= hue.Min && hSL.Hue <= hue.Max) || (hue.Min > hue.Max && (hSL.Hue >= hue.Min || hSL.Hue <= hue.Max))))
{
if (!fillOutsideRange)
{
if (updateH)
{
hSL.Hue = fillH;
}
if (updateS)
{
hSL.Saturation = fillS;
}
if (updateL)
{
hSL.Luminance = fillL;
}
flag = true;
}
}
else if (fillOutsideRange)
{
if (updateH)
{
hSL.Hue = fillH;
}
if (updateS)
{
hSL.Saturation = fillS;
}
if (updateL)
{
hSL.Luminance = fillL;
}
flag = true;
}
if (flag)
{
HSL.ToRGB(hSL, rGB);
ptr[2] = rGB.Red;
ptr[1] = rGB.Green;
*ptr = rGB.Blue;
}
num5++;
ptr += num;
}
ptr += num4;
}
}
}

View File

@@ -0,0 +1,146 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class HSLLinear : BaseInPlacePartialFilter
{
private Range inLuminance = new Range(0f, 1f);
private Range inSaturation = new Range(0f, 1f);
private Range outLuminance = new Range(0f, 1f);
private Range outSaturation = new Range(0f, 1f);
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public Range InLuminance
{
get
{
return inLuminance;
}
set
{
inLuminance = value;
}
}
public Range OutLuminance
{
get
{
return outLuminance;
}
set
{
outLuminance = value;
}
}
public Range InSaturation
{
get
{
return inSaturation;
}
set
{
inSaturation = value;
}
}
public Range OutSaturation
{
get
{
return outSaturation;
}
set
{
outSaturation = value;
}
}
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public HSLLinear()
{
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
}
protected unsafe override void ProcessFilter(UnmanagedImage image, Rectangle rect)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
int num = Image.GetPixelFormatSize(image.PixelFormat) / 8;
int left = rect.Left;
int top = rect.Top;
int num2 = left + rect.Width;
int num3 = top + rect.Height;
int num4 = image.Stride - rect.Width * num;
RGB rGB = new RGB();
HSL hSL = new HSL();
float num5 = 0f;
float num6 = 0f;
float num7 = 0f;
float num8 = 0f;
if (inLuminance.Max != inLuminance.Min)
{
num5 = (outLuminance.Max - outLuminance.Min) / (inLuminance.Max - inLuminance.Min);
num6 = outLuminance.Min - num5 * inLuminance.Min;
}
if (inSaturation.Max != inSaturation.Min)
{
num7 = (outSaturation.Max - outSaturation.Min) / (inSaturation.Max - inSaturation.Min);
num8 = outSaturation.Min - num7 * inSaturation.Min;
}
byte* ptr = (byte*)image.ImageData.ToPointer();
ptr += top * image.Stride + left * num;
for (int i = top; i < num3; i++)
{
int num9 = left;
while (num9 < num2)
{
rGB.Red = ptr[2];
rGB.Green = ptr[1];
rGB.Blue = *ptr;
HSL.FromRGB(rGB, hSL);
if (hSL.Luminance >= inLuminance.Max)
{
hSL.Luminance = outLuminance.Max;
}
else if (hSL.Luminance <= inLuminance.Min)
{
hSL.Luminance = outLuminance.Min;
}
else
{
hSL.Luminance = num5 * hSL.Luminance + num6;
}
if (hSL.Saturation >= inSaturation.Max)
{
hSL.Saturation = outSaturation.Max;
}
else if (hSL.Saturation <= inSaturation.Min)
{
hSL.Saturation = outSaturation.Min;
}
else
{
hSL.Saturation = num7 * hSL.Saturation + num8;
}
HSL.ToRGB(hSL, rGB);
ptr[2] = rGB.Red;
ptr[1] = rGB.Green;
*ptr = rGB.Blue;
num9++;
ptr += num;
}
ptr += num4;
}
}
}

View File

@@ -0,0 +1,120 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class HistogramEqualization : BaseInPlacePartialFilter
{
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public HistogramEqualization()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
}
protected unsafe override void ProcessFilter(UnmanagedImage image, Rectangle rect)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Invalid comparison between Unknown and I4
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Invalid comparison between Unknown and I4
int num = (((int)image.PixelFormat == 198659) ? 1 : (((int)image.PixelFormat == 137224) ? 3 : 4));
int left = rect.Left;
int top = rect.Top;
int num2 = left + rect.Width;
int num3 = top + rect.Height;
int stride = image.Stride;
int num4 = stride - rect.Width * num;
int num5 = (num2 - left) * (num3 - top);
if ((int)image.PixelFormat == 198659)
{
byte* ptr = (byte*)image.ImageData.ToPointer();
ptr += top * stride + left;
int[] array = new int[256];
for (int i = top; i < num3; i++)
{
int num6 = left;
while (num6 < num2)
{
array[*ptr]++;
num6++;
ptr++;
}
ptr += num4;
}
byte[] array2 = Equalize(array, num5);
ptr = (byte*)image.ImageData.ToPointer();
ptr += top * stride + left;
for (int j = top; j < num3; j++)
{
int num7 = left;
while (num7 < num2)
{
*ptr = array2[*ptr];
num7++;
ptr++;
}
ptr += num4;
}
return;
}
byte* ptr2 = (byte*)image.ImageData.ToPointer();
ptr2 += top * stride + left * num;
int[] array3 = new int[256];
int[] array4 = new int[256];
int[] array5 = new int[256];
for (int k = top; k < num3; k++)
{
int num8 = left;
while (num8 < num2)
{
array3[ptr2[2]]++;
array4[ptr2[1]]++;
array5[*ptr2]++;
num8++;
ptr2 += num;
}
ptr2 += num4;
}
byte[] array6 = Equalize(array3, num5);
byte[] array7 = Equalize(array4, num5);
byte[] array8 = Equalize(array5, num5);
ptr2 = (byte*)image.ImageData.ToPointer();
ptr2 += top * stride + left * num;
for (int l = top; l < num3; l++)
{
int num9 = left;
while (num9 < num2)
{
ptr2[2] = array6[ptr2[2]];
ptr2[1] = array7[ptr2[1]];
*ptr2 = array8[*ptr2];
num9++;
ptr2 += num;
}
ptr2 += num4;
}
}
private byte[] Equalize(int[] histogram, long numPixel)
{
byte[] array = new byte[256];
float num = 255f / (float)numPixel;
float num2 = (float)histogram[0] * num;
array[0] = (byte)num2;
for (int i = 1; i < 256; i++)
{
num2 += (float)histogram[i] * num;
array[i] = (byte)num2;
}
return array;
}
}

View File

@@ -0,0 +1,119 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class HitAndMiss : BaseUsingCopyPartialFilter
{
public enum Modes
{
HitAndMiss,
Thinning,
Thickening
}
private short[,] se;
private int size;
private Modes mode;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public Modes Mode
{
get
{
return mode;
}
set
{
mode = value;
}
}
public HitAndMiss(short[,] se)
{
int length = se.GetLength(0);
if (length != se.GetLength(1) || length < 3 || length > 99 || length % 2 == 0)
{
throw new ArgumentException();
}
this.se = se;
size = length;
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
}
public HitAndMiss(short[,] se, Modes mode)
: this(se)
{
this.mode = mode;
}
protected unsafe override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData, Rectangle rect)
{
int left = rect.Left;
int top = rect.Top;
int num = left + rect.Width;
int num2 = top + rect.Height;
int stride = sourceData.Stride;
int stride2 = destinationData.Stride;
int num3 = stride - rect.Width;
int num4 = stride2 - rect.Width;
int num5 = size >> 1;
byte[] array = new byte[3] { 255, 0, 255 };
byte[] array2 = new byte[3];
byte[] array3 = array2;
int num6 = (int)mode;
byte* ptr = (byte*)sourceData.ImageData.ToPointer();
byte* ptr2 = (byte*)destinationData.ImageData.ToPointer();
ptr += top * stride + left;
ptr2 += top * stride2 + left;
for (int i = top; i < num2; i++)
{
int num7 = left;
while (num7 < num)
{
array3[1] = (array3[2] = *ptr);
byte b = byte.MaxValue;
for (int j = 0; j < size; j++)
{
int num8 = j - num5;
for (int k = 0; k < size; k++)
{
int num9 = k - num5;
short num10 = se[j, k];
if (num10 != -1)
{
if (i + num8 < top || i + num8 >= num2 || num7 + num9 < left || num7 + num9 >= num)
{
b = 0;
break;
}
byte b2 = ptr[num8 * stride + num9];
if ((num10 != 0 || b2 != 0) && (num10 != 1 || b2 != byte.MaxValue))
{
b = 0;
break;
}
}
}
if (b == 0)
{
break;
}
}
*ptr2 = ((b == byte.MaxValue) ? array[num6] : array3[num6]);
num7++;
ptr++;
ptr2++;
}
ptr += num3;
ptr2 += num4;
}
}
}

View File

@@ -0,0 +1,121 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class HomogenityEdgeDetector : BaseUsingCopyPartialFilter
{
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public HomogenityEdgeDetector()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
}
protected unsafe override void ProcessFilter(UnmanagedImage source, UnmanagedImage destination, Rectangle rect)
{
int num = rect.Left + 1;
int num2 = rect.Top + 1;
int num3 = num + rect.Width - 2;
int num4 = num2 + rect.Height - 2;
int stride = destination.Stride;
int stride2 = source.Stride;
int num5 = stride - rect.Width + 2;
int num6 = stride2 - rect.Width + 2;
byte* ptr = (byte*)source.ImageData.ToPointer();
byte* ptr2 = (byte*)destination.ImageData.ToPointer();
ptr += stride2 * num2 + num;
ptr2 += stride * num2 + num;
for (int i = num2; i < num4; i++)
{
int num7 = num;
while (num7 < num3)
{
int num8 = 0;
int num9 = *ptr;
int num10 = num9 - ptr[-stride2 - 1];
if (num10 < 0)
{
num10 = -num10;
}
if (num10 > num8)
{
num8 = num10;
}
num10 = num9 - ptr[-stride2];
if (num10 < 0)
{
num10 = -num10;
}
if (num10 > num8)
{
num8 = num10;
}
num10 = num9 - ptr[-stride2 + 1];
if (num10 < 0)
{
num10 = -num10;
}
if (num10 > num8)
{
num8 = num10;
}
num10 = num9 - ptr[-1];
if (num10 < 0)
{
num10 = -num10;
}
if (num10 > num8)
{
num8 = num10;
}
num10 = num9 - ptr[1];
if (num10 < 0)
{
num10 = -num10;
}
if (num10 > num8)
{
num8 = num10;
}
num10 = num9 - ptr[stride2 - 1];
if (num10 < 0)
{
num10 = -num10;
}
if (num10 > num8)
{
num8 = num10;
}
num10 = num9 - ptr[stride2];
if (num10 < 0)
{
num10 = -num10;
}
if (num10 > num8)
{
num8 = num10;
}
num10 = num9 - ptr[stride2 + 1];
if (num10 < 0)
{
num10 = -num10;
}
if (num10 > num8)
{
num8 = num10;
}
*ptr2 = (byte)num8;
num7++;
ptr++;
ptr2++;
}
ptr += num6;
ptr2 += num5;
}
Drawing.Rectangle(destination, rect, Color.Black);
}
}

View File

@@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class HorizontalRunLengthSmoothing : BaseInPlacePartialFilter
{
private int maxGapSize = 10;
private bool processGapsWithImageBorders;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public int MaxGapSize
{
get
{
return maxGapSize;
}
set
{
maxGapSize = System.Math.Max(1, System.Math.Min(1000, value));
}
}
public bool ProcessGapsWithImageBorders
{
get
{
return processGapsWithImageBorders;
}
set
{
processGapsWithImageBorders = value;
}
}
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public HorizontalRunLengthSmoothing()
{
formatTranslations[(PixelFormat)198659] = (PixelFormat)198659;
}
public HorizontalRunLengthSmoothing(int maxGapSize)
: this()
{
MaxGapSize = maxGapSize;
}
protected unsafe override void ProcessFilter(UnmanagedImage image, Rectangle rect)
{
int top = rect.Top;
int num = top + rect.Height;
int width = rect.Width;
int num2 = image.Stride - rect.Width;
byte* ptr = (byte*)image.ImageData.ToPointer() + (nint)top * (nint)image.Stride + rect.Left;
for (int i = top; i < num; i++)
{
byte* ptr2 = ptr;
byte* ptr3 = ptr + width;
while (ptr < ptr3)
{
byte* ptr4 = ptr;
for (; ptr < ptr3 && *ptr == 0; ptr++)
{
}
if (ptr - ptr4 <= maxGapSize && (processGapsWithImageBorders || (ptr4 != ptr2 && ptr != ptr3)))
{
for (; ptr4 < ptr; ptr4++)
{
*ptr4 = byte.MaxValue;
}
}
for (; ptr < ptr3 && *ptr != 0; ptr++)
{
}
}
ptr += num2;
}
}
}

View File

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace AForge.Imaging.Filters;
public class HueModifier : BaseInPlacePartialFilter
{
private int hue;
private Dictionary<PixelFormat, PixelFormat> formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations => formatTranslations;
public int Hue
{
get
{
return hue;
}
set
{
hue = System.Math.Max(0, System.Math.Min(359, value));
}
}
public HueModifier()
{
formatTranslations[(PixelFormat)137224] = (PixelFormat)137224;
formatTranslations[(PixelFormat)139273] = (PixelFormat)139273;
formatTranslations[(PixelFormat)2498570] = (PixelFormat)2498570;
formatTranslations[(PixelFormat)925707] = (PixelFormat)925707;
}
public HueModifier(int hue)
: this()
{
this.hue = hue;
}
protected unsafe override void ProcessFilter(UnmanagedImage image, Rectangle rect)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
int num = Image.GetPixelFormatSize(image.PixelFormat) / 8;
int left = rect.Left;
int top = rect.Top;
int num2 = left + rect.Width;
int num3 = top + rect.Height;
int num4 = image.Stride - rect.Width * num;
RGB rGB = new RGB();
HSL hSL = new HSL();
byte* ptr = (byte*)image.ImageData.ToPointer();
ptr += top * image.Stride + left * num;
for (int i = top; i < num3; i++)
{
int num5 = left;
while (num5 < num2)
{
rGB.Red = ptr[2];
rGB.Green = ptr[1];
rGB.Blue = *ptr;
HSL.FromRGB(rGB, hSL);
hSL.Hue = hue;
HSL.ToRGB(hSL, rGB);
ptr[2] = rGB.Red;
ptr[1] = rGB.Green;
*ptr = rGB.Blue;
num5++;
ptr += num;
}
ptr += num4;
}
}
}

Some files were not shown because too many files have changed in this diff Show More