私は現在、非常に大量の画像を扱うプロジェクトに携わっています。このボリュームは非常に高速に処理する必要があります (加算、減算、しきい値処理など)。さらに、ほとんどのボリュームは非常に大きいため、システムのメモリに収まりません。そのため、ボリュームとイメージ データをホストし、オペレータをオーバーロードする抽象ボリューム クラス (VoxelVolume) を作成して、ボリュームに対して通常の数学演算を実行できるようにしました。これにより、さらに 2 つの質問が開かれ、stackoverflow に追加の 2 つのスレッドに入れます。
これが私の最初の質問です。私のボリュームは、float 配列データのみを含むことができるように実装されていますが、含まれているデータのほとんどは UInt16 イメージ ソースからのものです。float 配列イメージを作成できるのは、ボリュームに対する操作のみです。
このようなボリュームの実装を開始したとき、クラスは次のようになりました。
public abstract class VoxelVolume<T>
{
...
}
しかしその後、演算子や戻り値をオーバーロードするとさらに複雑になることに気付きました。例は次のとおりです。
public abstract class VoxelVolume<T>
{
...
public static VoxelVolume<T> Import<T>(param string[] files)
{
}
}
また、2 つのオーバーロード演算子を追加すると、より複雑になります。
...
public static VoxelVolume<T> operator+(VoxelVolume<T> A, VoxelVolume<T> B)
{
...
}
上記の問題を克服できると仮定しましょう。ただし、画像データを含むさまざまなタイプの配列があります。ボリュームのタイプを float に修正したので問題ありません。2 つのイメージ ボリューム配列の内容を追加するときに安全でない操作を行うことができます。ここでいくつかのスレッドを読み、Web を見回しましたが、異なるタイプの 2 つの配列をすばやく追加したい場合に何をすべきかについての適切な説明が見つかりませんでした。残念ながら、C# は基礎となるデータ型のサイズを計算できないため、ジェネリックに対するすべての数学演算は不可能です。もちろん、C++/CLR を使用してこの問題を回避することもできますが、現在のところ、これまでに行ったことはすべて、何もしなくても 32 ビットと 64 ビットで実行できます。C++/CLR への切り替えは、私には次のように思えました (間違っていたら訂正してください)。m は特定のプラットフォーム (32 ビット) にバインドされており、アプリケーションを別のプラットフォーム (64 ビット) で実行するには、2 つのアセンブリをコンパイルする必要があります。これは本当ですか?
簡単に尋ねたところ、2 つの異なるタイプの 2 つの配列をすばやく追加するにはどうすればよいでしょうか。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# エディターを使用せずに記述しました。上記のような解決策は考えられますか?間違いや不完全な説明がありましたら、お気軽にお問い合わせください。
助けてくれてありがとう
マーティン