我想将一张图像的 Alpha 通道与其他约 1000 张图像进行比较。我的比较方法如下所示:
public static unsafe double Similiarity (Bitmap a, Bitmap b)
{
BitmapData aData = a.LockBits (
new Rectangle (0, 0, a.Width, a.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly, a.PixelFormat);
BitmapData bData = b.LockBits (
new Rectangle (0, 0, b.Width, b.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly, b.PixelFormat);
int PixelSize = 4;
double sum = 0;
for (int y=0; y<aData.Height; y++) {
byte* aRow = (byte *)aData.Scan0 + (y * aData.Stride);
byte* bRow = (byte *)bData.Scan0 + (y * bData.Stride);
for (int x=0; x<aData.Width; x++) {
byte aWeight = aRow [x * PixelSize + 3];
byte bWeight = bRow [x * PixelSize + 3];
sum += Math.Abs (aWeight - bWeight);
}
}
a.UnlockBits (aData);
b.UnlockBits (bData);
return 1 - ((sum / 255) / (a.Width * a.Height));
}
我认为加快计算速度的最简单方法是使用 PLINQ:
var list = from Bitmap img in imageList.AsParallel where (Similiarity (referenceImage, img) > 0.5) select img;
但是在执行时 gdiplus 中有一个异常:
System.InvalidOperationException: The operation is invalid [GDI+ status: Win32Error]
at System.Drawing.GDIPlus.CheckStatus (Status status) [0x00000] in <filename unknown>:0
at System.Drawing.Bitmap.LockBits (Rectangle rect, ImageLockMode flags, PixelFormat format, System.Drawing.Imaging.BitmapData bitmapData) [0x00000] in <filename unknown>:0
我知道 gdiplus 必须在不同的进程中执行,但我认为 PLINQ 正在这样做。我的假设有什么问题?