在 C 中使用 CUDA.NET 进行 GPU 加速图像处理的问题#

Trouble with GPU-Accelerated Image Processing using CUDA.NET in C#

提问人:tomato bar 提问时间:11/18/2023 更新时间:11/18/2023 访问量:20

问:

我正在尝试在 C# 应用程序中使用 CUDA.NET 执行 GPU 加速的图像处理。目标是根据亮度交换图像中的像素。但是,我遇到了问题,并且代码有以下错误:

Severity    Code    Description Project File    Line    Suppression State
Error   CS1503  Argument 1: cannot convert from 'long' to 'uint'    Image   F:\projects\programming\C#\clauth app 4\Image\Image\Form1.cs    464 Active
Severity    Code    Description Project File    Line    Suppression State
Error   CS0019  Operator '>>>' cannot be applied to operands of type 'dim3' and '(ManagedCuda.BasicTypes.CUdeviceptr, int, int, int)'   Image   F:\projects\programming\C#\clauth app 4\Image\Image\Form1.cs    467 Active

Severity    Code    Description Project File    Line    Suppression State
Error   CS1061  'CudaDeviceVariable<byte>' does not contain a definition for 'ToHost' and no accessible extension method 'ToHost' accepting a first argument of type 'CudaDeviceVariable<byte>' could be found (are you missing a using directive or an assembly reference?)    Image   F:\projects\programming\C#\clauth app 4\Image\Image\Form1.cs    470 Active
Severity    Code    Description Project File    Line    Suppression State
Error   CS0214  Pointers and fixed size buffers may only be used in an unsafe context   Image   F:\projects\programming\C#\clauth app 4\Image\Image\Form1.cs    504 Active
Severity    Code    Description Project File    Line    Suppression State
Error   CS0103  The name 'blockDim' does not exist in the current context   Image   F:\projects\programming\C#\clauth app 4\Image\Image\Form1.cs    489 Active

下面是代码的简化版本:

using System;
using System.Drawing;
using ManagedCuda;

class Program
{
    static void Main()
    {
        // Load your image using Bitmap
        Bitmap inputImage = new Bitmap("input.jpg");

        // Initialize CUDA
        CudaContext ctx = new CudaContext();

        // Allocate GPU memory for image data
        CudaDeviceVariable<byte> gpuImage = new CudaDeviceVariable<byte>(inputImage.Width * inputImage.Height * 3);

        // Copy image data to GPU
        gpuImage.CopyToDevice(ImageToByteArray(inputImage));

        // Define grid and block dimensions
        dim3 blockDim = new dim3(16, 16);
        dim3 gridDim = new dim3((inputImage.Width + blockDim.x - 1) / blockDim.x, (inputImage.Height + blockDim.y - 1) / blockDim.y);

        // Launch the CUDA kernel for image processing
        ImageProcessingKernel<<<gridDim, blockDim>>>(gpuImage.DevicePointer, inputImage.Width, inputImage.Height, 10);

        // Copy results back to CPU
        byte[] result = gpuImage.ToHost();

        // Clean up resources
        gpuImage.Dispose();
        ctx.Dispose();

        // Display or save the processed image
        Bitmap outputImage = ByteArrayToImage(result, inputImage.Width, inputImage.Height);
        outputImage.Save("output.jpg");
    }

    static void ImageProcessingKernel(byte* image, int width, int height, int value10)
    {
        // CUDA kernel code for image processing
        // Each thread handles a portion of the image data
        int x = blockIdx.x * blockDim.x + threadIdx.x;
        int y = blockIdx.y * blockDim.y + threadIdx.y;

        if (x < width - value10 && y < height)
        {
            int index1 = (y * width + x) * 3;
            int index2 = (y * width + (x + value10)) * 3;

            // Perform the pixel swap based on brightness (simplified logic)
            if ((int)(image[index2] + image[index2 + 1] + image[index2 + 2]) <
                (int)(image[index1] + image[index1 + 1] + image[index1 + 2]))
            {
                // Swap pixels
                for (int i = 0; i < 3; i++)
                {
                    byte temp = image[index1 + i];
                    image[index1 + i] = image[index2 + i];
                    image[index2 + i] = temp;
                }
            }
        }
    }

    static byte[] ImageToByteArray(Bitmap image)
    {
        // Convert a Bitmap to a byte array
        // Note: This is a simplistic conversion and might not cover all cases
        var converter = new ImageConverter();
        return (byte[])converter.ConvertTo(image, typeof(byte[]));
    }

    static Bitmap ByteArrayToImage(byte[] byteArray, int width, int height)
    {
        // Convert a byte array to a Bitmap
        // Note: This is a simplistic conversion and might not cover all cases
        var converter = new ImageConverter();
        return (Bitmap)converter.ConvertFrom(byteArray);
    }
}

任何指导或建议将不胜感激!谢谢。

C# WinForms CUDA

评论


答: 暂无答案