OutputBitmap.SetPixel(object_point_x、object_point_y、InputBitmap0.GetPixel(x、y)は)
それは時間がかかりましたが、最終的には、私は、私のケースを割りました。
我々は、2つのBitmap
を有する:入力InputBitmap0
ための出力OutputBitmap
用と別の部品にこのタスクを分割します:
- は、その後のため
OutputBitmap.SetPixel()
を
- 座標
y
、x
ためInputBitmap0.GetPixel()
を行います異なる座標object_point_x, object_point_y
CudafyはまたはColor
タイプのデータをサポートしていません。そこでビットマップをbyte
タイプに変換しました。
BitmapData InputBitmapData0 = InputBitmap0.LockBits(new Rectangle(0, 0, InputBitmap0.Width, InputBitmap0.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
IntPtr ptr0 = InputBitmapData0.Scan0;//pointer for color
int stride0 = InputBitmapData0.Stride;
byte[] input_ragba_color = new byte[InputBitmapData0.Stride * InputBitmap0.Height];
Marshal.Copy(ptr0, input_ragba_color, 0, bytes0);// Copy the RGB values of color value into the array.
我々はrgbValues
配列にInputBitmap0
の内容をコピーしています。今我々はGetPixel()
の仕事をする必要がある(R、G、B、Aの値を得る)。
GPUでSetPixel()
を実行しているため、上記の作業(make array)をOutputBitmap
に対して実行する必要がありますが、後でその配列をビットマップにコピーして戻します。
BitmapData OutputBitmapData = OutputBitmap.LockBits(new Rectangle(0, 0, OutputBitmap.Width, OutputBitmap.Height), ImageLockMode.WriteOnly, OutputBitmap.PixelFormat);
IntPtr ptr_output = OutputBitmapData.Scan0;
byte[] output_ragba = new byte[OutputBitmapData.Stride * OutputBitmap.Height];
GPUの計算時間。 gpuを初期化します。私たちは、配列を反復処理し、任意の計算を行うことができますので、
CudafyModule km = new CudafyTranslator.Cudafy();
GPGPU gpu = new CudafyHost.getDevice(CudafyModes.Target, CudafyModes.DeviceId);
gpu.LoadModule(km);
今GPUに
input_ragba_color
と
output_ragba
を送信します。第一タスク (
InputBitmap0.GetPixel()
)を解くれ
input_ragba_color[(y * stride0) + (x * 4) + 1]
:今すぐGPU(カーネル)
[Cudafy]
public static void update_bitmap(GThread thread, int x,int y,int object_point_x,int object_point_y,int stride0, int OutputBitmapData_Stride,byte [] dev_input_ragba_color,byte [] dev_output_rgba_color)
{
dev_output_rgba_color[(object_point_y * OutputBitmapData_Stride) + (object_point_x * 4)] = input_ragba_color[(y * stride0) + (x * 4)];
dev_output_rgba_color[(object_point_y * OutputBitmapData_Stride) + (object_point_x * 4) + 1] = input_ragba_color[(y * stride0) + (x * 4) + 1];
dev_output_rgba_color[(object_point_y * OutputBitmapData_Stride) + (object_point_x * 4) + 2] = input_ragba_color[(y * stride0) + (x * 4) + 2];
dev_output_rgba_color[(object_point_y * OutputBitmapData_Stride) + (object_point_x * 4) + 3] = input_ragba_color[(y * stride0) + (x * 4) + 3];
}
の内側に、私はそれぞれR、G、B、A、元の値を取ってい
byte[] dev_output_rgba_color = gpu.Allocate<byte>(output_ragba.Length);
byte[] dev_input_ragba_color = gpu.CopyToDevice(input_ragba_color);
gpu.Launch(N, 1).update_bitmap(x, y, object_point_x, object_point_y,int stride0, int OutputBitmapData.Stride,dev_input_ragba_color,dev_output_rgba_color);
dev_output_rgba_color
は、input_ragba_color
の値をとっています。例:
我々は今、GPUが私たちのOutputBitmap
のための配列(dev_output_rgba_color
)を埋めたことを知っている私たちの第二のタスク(OutputBitmap.SetPixel()
)
を解決している
dev_output_rgba_color[(object_point_y * OutputBitmapData_Stride) + (object_point_x * 4)] = input_ragba_color[(y * stride0) + (x * 4)];
。
gpu.CopyFromDevice(dev_output_rgba_color, output_ragba); //dev_output_rgba_color values will be assigned to output_ragba
gpu.FreeAll();
メモリポインタを使用してバックOutputBitmap
に結果をコピーして、メモリからそれをアンロック。
Marshal.Copy(output_ragba, 0, ptr_output, output_bytes);// Copy the RGB values of color value into the array.
OutputBitmap.UnlockBits(OutputBitmapData);
ここで、OutputBitmap
には更新された値が含まれています。
この質問は書かれた通り広すぎると私はそのように閉じるように投票しました – talonmies
@talonmies投稿者が簡単に理解できるように詳細にしようとしました!それを閉じるのではなく、解決の可能な方法を学ぶことができますか? –
あなたはここで深刻な質問をしていません。 *あなたは何を知っていますか? CUDAにはネイティブのC#バインディングがなく、使用しているフレームワークについても言及していません。あなたはビットマップデータ形式を理解していますか?カーネルを実際に作成しようとしましたか?あなたが持っている場合、問題は何ですか?これが広すぎる理由です。あなたはあなたの応答のために[SO]の質問 – talonmies