Files
SuperVPN/output/Libraries/AForge.Imaging/AForge/Imaging/ExhaustiveBlockMatching.cs
2025-10-09 09:57:24 +09:00

199 lines
5.4 KiB
C#

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;
}
}