我目前正在参与一个图像量非常大的项目。这些卷必须非常快速地处理(加法、减法、阈值处理等)。此外,大多数卷都非常大,以至于它们无法放入系统的内存中。出于这个原因,我创建了一个抽象体积类 (VoxelVolume),它承载体积和图像数据并重载运算符,以便可以对体积执行常规数学运算。因此,另外两个问题打开了,我将把它们放入 stackoverflow 到另外两个线程中。
这是我的第一个问题。我的卷以只能包含浮点数组数据的方式实现,但大部分包含的数据来自 UInt16 图像源。只有对卷的操作才能创建浮点数组图像。
当我开始实现这样一个卷时,该类如下所示:
public abstract class VoxelVolume<T>
{
...
}
但后来我意识到重载运算符或返回值会变得更加复杂。一个例子是:
public abstract class VoxelVolume<T>
{
...
public static VoxelVolume<T> Import<T>(param string[] files)
{
}
}
还添加两个重载运算符会更复杂:
...
public static VoxelVolume<T> operator+(VoxelVolume<T> A, VoxelVolume<T> B)
{
...
}
假设我可以克服上述问题,但我有不同类型的包含图像数据的数组。由于我已将卷中的类型固定为浮动,所以没有问题,并且在添加两个图像卷数组的内容时可以执行不安全的操作。我在这里阅读了一些主题并浏览了网络,但没有找到真正好的解释当我想快速添加两个不同类型的数组时该怎么做。不幸的是,不可能对泛型进行所有数学运算,因为 C# 无法计算基础数据类型的大小。当然,可以通过使用 C++/CLR 来解决这个问题,但目前我所做的一切都是在 32 位和 64 位下运行而无需做任何事情。切换到 C++/CLR 在我看来(如果我错了,请纠正我)我' m 绑定到某个平台(32 位),当我让应用程序在另一个平台(64 位)上运行时,我必须编译两个程序集。这是真的?
所以很快问:如何快速添加两个不同类型的两个数组。是不是C#的开发者没有想到这一点。切换到另一种语言(C# -> C++)似乎不是一种选择。
我意识到只需执行此操作
float []A = new float[]{1,2,3};
byte []B = new byte[]{1,2,3};
float []C = A+B;
是不可能的和不必要的,尽管如果它可以工作会很好。我正在尝试的解决方案如下:
public static class ArrayExt
{
public static unsafe TResult[] Add<T1, T2, TResult>(T1 []A, T2 []B)
{
// Assume the length of both arrays is equal
TResult[] result = new TResult[A.Length];
GCHandle h1 = GCHandle.Alloc (A, Pinned);
GCHandle h2 = GCHandle.Alloc (B, Pinned);
GCHandle hR = GCHandle.Alloc (C, Pinned);
void *ptrA = h1.ToPointer();
void *ptrB = h2.ToPointer();
void *ptrR = hR.ToPointer();
for (int i=0; i<A.Length; i++)
{
*((TResult *)ptrR) = (TResult *)((T1)*ptrA + (T2)*ptrB));
}
h1.Free();
h2.Free();
hR.Free();
return result;
}
}
如果上面的代码不是很正确,请原谅,我没有使用 C# 编辑器编写它。上面显示的这种解决方案是否可行?请随时询问我是否犯了错误或描述了一些不完整的内容。
谢谢你的帮助
马丁