2017-02-04 16 views
8

में सेटपिक्सेल() मैं क्यूडाफी का उपयोग कर रहा हूं क्योंकि सी # रैपर मुझे बिटमैप की रंग जानकारी InputBitmap0.GetPixel(x, y) प्राप्त करने और आउटपुट के लिए एक नया बिटमैप बनाने की आवश्यकता है।सी # बिटमैप गेट पिक्सेल(), जीपीयू

मुझे GPU में निम्नलिखित कार्य करने की आवश्यकता है।

सीपीयू

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

में

संक्षेप में:

() में outputbitmap बिटमैप के प्रत्येक पिक्सेल बिंदु के लिए इनपुट बिटमैप के प्रत्येक पिक्सेल बिंदु, SetPixel() के लिए GetPixel कैसे GPU।

+0

यह प्रश्न लिखित रूप में बहुत व्यापक है और मैंने इसे – talonmies

+0

@talonmies के रूप में बंद करने के लिए वोट दिया है, इसलिए मैंने विस्तृत होने की कोशिश की है ताकि योगदानकर्ता इसे आसानी से समझ सकें! इसे बंद करने के बजाय क्या मैं इसे हल करने का एक संभावित तरीका सीख सकता हूं? –

+0

आपने यहां एक गंभीर सवाल नहीं पूछा है। क्या * आपको * क्या पता है? CUDA में मूल सी # बाइंडिंग नहीं है और आपने यह भी नहीं कहा है कि आप किस फ्रेमवर्क का उपयोग कर रहे हैं। क्या आप बिट मैप डेटा प्रारूप को समझते हैं? क्या आपने वास्तव में कर्नेल लिखने की कोशिश की है? यदि आपके पास समस्या है तो क्या समस्या है? यही कारण है कि यह बहुत व्यापक है। आपने अपनी प्रतिक्रिया के लिए एक इच्छा सूची पोस्ट की है, [SO] प्रश्न – talonmies

उत्तर

5

OutputBitmap.SetPixel (object_point_x, object_point_y, InputBitmap0.GetPixel (एक्स, वाई))

यह समय लिया, लेकिन अंत में, मैं, मेरे मामले फटा।

हम दो Bitmap हैं: एक उत्पादन OutputBitmap के लिए और इनपुट InputBitmap0

के लिए एक और भागों में इस कार्य को विभाजित करने देता है:

  1. x लिए क्या InputBitmap0.GetPixel(), y समन्वय
  2. तो, OutputBitmap.SetPixel() एक के लिए विभिन्न समन्वय object_point_x, object_point_y

कुडाफी Bitmap या 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() का काम करने की आवश्यकता है (आर, जी, बी, ए के मान प्राप्त करें)।

क्योंकि हम GPU में SetPixel() कर रही होगी ऊपर काम (सरणी बनाने) 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 समय। चलिए जीपीयू शुरू करते हैं।

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

अब GPU के लिए input_ragba_color और output_ragba भेज क्योंकि हम सरणी पुनरावृति और किसी भी गणना कर सकते हैं।

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

} 

मैं प्रत्येक आर, जी, बी, ए, पूर्व के मूल्यों ले रहा हूँ: input_ragba_color[(y * stride0) + (x * 4) + 1] 1 कार्य (InputBitmap0.GetPixel()) को सुलझाने है जो

dev_output_rgba_colorinput_ragba_color के मान ले रहा है उदाहरण:

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

है जो हमारे OutputBitmap के लिए हमारे 2 कार्य (OutputBitmap.SetPixel())

अब हम जानते हैं कि GPU एक सरणी (dev_output_rgba_color) आबादी है हल करती है।

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; 

} 
संबंधित मुद्दे