Je suis actuellement impliqué dans un projet où j'ai de très grands volumes d'images. Ces volumes doivent être traités très rapidement (ajout, soustraction, seuillage, etc.). De plus, la plus grande partie du volume est si grande que les événements ne rentrent pas dans la mémoire du système. Pour cette raison, j'ai créé une classe de volume abstrait (VoxelVolume) qui héberge les données de volume et d'image et surcharge les opérateurs de sorte qu'il est possible d'effectuer les opérations mathématiques normales sur les volumes. Par la suite, deux autres questions s'ouvriront que je mettrai dans stackoverflow dans deux threads supplémentaires.C# Generic Arrays et opérations mathématiques
Voici ma première question. Mon volume est implémenté d'une manière qui ne peut contenir que des données de type float, mais la plupart des données contenues proviennent d'une source d'image UInt16. Seules les opérations sur le volume peuvent créer des images flottantes.
Lorsque j'ai commencé à mettre en œuvre un tel volume de la classe ressemblait à ce qui suit:
public abstract class VoxelVolume<T>
{
...
}
mais je réalise que la surcharge des opérateurs ou de retour des valeurs obtiendraient plus compliquées. Un exemple serait:
public abstract class VoxelVolume<T>
{
...
public static VoxelVolume<T> Import<T>(param string[] files)
{
}
}
également l'ajout de deux opérateurs surcharge seraient plus compliquées:
...
public static VoxelVolume<T> operator+(VoxelVolume<T> A, VoxelVolume<T> B)
{
...
}
Supposons que je peux surmonter les problèmes décrits ci-dessus, néanmoins, j'ai différents types de tableaux qui contiennent l'image Les données. Depuis que j'ai fixé mon type dans les volumes pour flotter le n'est pas un problème et je peux faire une opération dangereuse lors de l'ajout du contenu de deux tableaux de volume d'image. J'ai lu quelques fils ici et ai jeté un coup d'oeil autour du Web, mais n'ai trouvé aucune vraie bonne explication de ce que faire quand je veux ajouter deux rangées de types différents d'une manière rapide. Malheureusement, chaque opération mathématique sur les génériques n'est pas possible, car C# n'est pas capable de calculer la taille du type de données sous-jacent. Bien sûr, il pourrait contourner ce problème en utilisant C++/CLR, mais actuellement tout ce que j'ai fait jusqu'à présent, fonctionne en 32 bits et 64 bits sans avoir à faire une chose. Passer en C++/CLR m'a semblé (content de me corriger si je me trompe) que je suis lié à une certaine plate-forme (32bits) et je dois compiler deux assemblées quand je laisse l'application tourner sur une autre plateforme (64bits). Est-ce vrai?
Donc demandé brièvement: Comment est-il possible d'ajouter deux tableaux de deux types différents d'une manière rapide. Est-il vrai que les développeurs de C# n'y ont pas pensé. Passer à une autre langue (C# -> C++) ne semble pas être une option.
Je me rends compte que la réalisation de cette opération simplement
float []A = new float[]{1,2,3};
byte []B = new byte[]{1,2,3};
float []C = A+B;
est impossible et inutile, bien que ce serait bien si cela fonctionnerait. Ma solution que je tentais suivais:
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;
}
}
S'il vous plaît excuser si le code ci-dessus est pas tout à fait correct, je l'ai écrit sans utiliser un éditeur C#. Est-ce qu'une telle solution est montrée ci-dessus pensable? N'hésitez pas à demander si j'ai fait une erreur ou décrit certaines choses de manière incomplète.
Merci pour votre aide
Martin
Vous devriez supprimer cette question et la redemander comme wiki non communautaire. (D'abord, cliquez sur 'edit' et copiez la source) – SLaks
Il n'a pas eu à être CW mais il n'y a pas besoin de re-demander. –