2017-02-04 65 views
8

我使用Cudafy作爲c#封裝器 我需要獲取位圖的顏色信息InputBitmap0.GetPixel(x, y)併爲輸出創建一個新的位圖。C#位圖GPU中的GetPixel(),SetPixel()

我需要在GPU中完成以下工作。

IN CPU

OutputBitmap.SetPixel(object_point_x, object_point_y, InputBitmap0.GetPixel(x, y)); 

簡而言之:

如何GetPixel()進行,SetPixel()在outputbitmap位圖的每個像素點的輸入位圖的每個像素點GPU。

+0

這個問題過於寬泛,我已經投票將其關閉,因爲這樣 – talonmies

+0

@talonmies我試圖詳細說明,以便貢獻者能夠輕鬆理解它!我可以學習解決它的一種可能方式,而不是關閉它? –

+0

你還沒有在這裏問過一個嚴肅的問題。什麼*確切*你知道什麼? CUDA沒有原生的C#綁定,你甚至沒有說你使用的是什麼框架。你瞭解位圖數據格式嗎?你有沒有試過寫一個內核?如果你有什麼問題?這就是爲什麼這太寬泛。你已經發布了一個願望清單,而不是[SO]問題 – talonmies

回答

5

OutputBitmap.SetPixel(object_point_x,object_point_y,InputBitmap0.GetPixel(X,Y))

,經過一段時間,但最後我,打斷了我的情況。

我們有兩個Bitmap:一個用於輸出OutputBitmap,另一個用於輸入InputBitmap0

讓我們分這任務分成部分:

  1. xInputBitmap0.GetPixel()y協調
  2. 然後,OutputBitmap.SetPixel()了不同座標object_point_x, object_point_y

Cudafy不支持BitmapColor類型的數據。所以我將位圖轉換爲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. 

我們已經複製InputBitmap0rgbValues陣列的內容。現在我們需要做GetPixel()的工作(得到R,G,B,A的值)。

我們還需要爲OutputBitmap做上述工作(製作數組),因爲我們將在GPU中執行SetPixel(),但我們稍後會將該數組複製回位圖。

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); 

立即發送input_ragba_coloroutput_ragba到GPU,因爲我們可以遍歷數組和做任何計算。

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); 

現在內部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,前的值:input_ragba_color[(y * stride0) + (x * 4) + 1],其解決第一任務 (InputBitmap0.GetPixel()

dev_output_rgba_color取值input_ragba_color 例如:

dev_output_rgba_color[(object_point_y * OutputBitmapData_Stride) + (object_point_x * 4)] = input_ragba_color[(y * stride0) + (x * 4)]; 

這是解決我們的第二個任務(OutputBitmap.SetPixel()

我們現在知道,GPU已經填充的數組(dev_output_rgba_color)我們OutputBitmap

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包含更新的值。

1

我認爲你需要使用byte[]並在GPU上分配它。 I've seen you asking around這個答案是一項正在進行中的工作,隨着時間的推移,我會在未來幾天繼續更新它。

CudafyModule km = new CudafyTranslator.Cudafy(); 
GPGPU gpu = new CudafyHost.getDevice(CudafyModes.Target, CudafyModes.DeviceId); 
gpu.LoadModule(km); 

var image = new Bitmap(width, height); 
image = (Bitmap)Image.FromFile(@"C:\temp\a.bmp", true); 
byte[] imageBytes = new byte[width * height * 4]; 
using(MemoryStream ms = new MemoryStream()) 
{ 
    image.Save(ms, format); 
    imageBytes = ms.ToArray(); 
} 
byte[] device_imageBytes = _gpu.CopyToDevice(imageBytes); 

byte r = 0; 
byte g = 0; 
byte b = 0; 

byte device_r = _gpu.Allocate<byte>(r); 
byte device_g = _gpu.Allocate<byte>(g); 
byte device_b = _gpu.Allocate<byte>(b); 

//Call this in a loop 
gpu.Launch(N, 1).GetPixel(x, y, device_imageBytes, device_r, device_g, device_b); 

... 

[Cudafy] 
public static void GetPixel(GThread thread, int x, int y, byte[] imageBytes, byte blue, byte green, byte red) 
{ 
    int offset = x * BPP + y * stride; 
    blue = imageBytes[offset++]; 
    green = imageBytes[offset++]; 
    red = imageBytes[offset]; 

    double R = red; 
    double G = green * 255; 
    double B = blue * 255 * 255; 

} 
相關問題