В настоящее время я участвую в проекте, где у меня очень большие объемы изображений. Эти объемы должны обрабатываться очень быстро (добавление, вычитание, пороговое значение и т. Д.). Кроме того, большая часть тома настолько велика, что они не помещаются в память системы. По этой причине я создал абстрактный класс томов (VoxelVolume), который размещает данные тома и изображения и перегружает операторов, чтобы можно было выполнять обычные математические операции над томами. Тем самым открылось еще два вопроса, которые я буду помещать в stackoverflow в два дополнительных потока.C# Общие массивы и математические операции на нем
Вот мой первый вопрос. Мой том реализован таким образом, что он может содержать только данные массива float, но большинство содержащихся данных - из источника изображения 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 (мне понравилось, если я ошибаюсь), что я привязан к определенной платформе (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# редактора. Является ли такое решение показанным выше понятным? Пожалуйста, не стесняйтесь спрашивать, допустил ли я ошибку или описал некоторые вещи не полностью.
Спасибо за вашу помощь
Martin
Вы должны удалить этот вопрос и запросить его как не-Community Wiki. (Сначала нажмите «править» и скопируйте источник) – SLaks
Это не должно быть CW, но нет необходимости повторно его просить. –