通过导出 dll 从 CUDA 中的指针加载图像
Load Image from pointer in CUDA with export of dll
我对这种东西很陌生。我正在尝试创建一个等同于图像直方图函数的函数。我正在使用 windows 表单应用程序来显示直方图(并加载图像)和 CUDA/c++ 来制作直方图。我从一开始就提到我没有使用 openCV、glut、OpenGL 或任何其他第三方库。继续...我正在尝试将位图传递给非托管 C++ DLL。这里的问题是我现在不知道如何在 C++ 代码中引用该位图。 (甚至如何从中获取 RGB)。
代码片段:
c#:
private void calculateHistogram(object sender, EventArgs e)
{
Bitmap bmp = (Bitmap)pictureBox1.Image;
unsafe {
int** matrixAcumulated;
var date = bmp.LockBits(new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
matrixAcumulated=NativeMethods.GenerateHistogram(date.Scan0, pictureBox1.Width);
bmp.UnlockBits(date);
// Write the string to a file.
System.Console.WriteLine(matrixAcumulated[0][0]);
}
}
Dll 导入:
using System;
using System.Runtime.InteropServices;
namespace HistogramProcessingCs
{
class NativeMethods
{
[DllImport("HistogramProcessingCpp.dll", CallingConvention = CallingConvention.StdCall)]
public static extern unsafe int** GenerateHistogram(IntPtr bmp, int dimensionImage);
}
}
c++:
extern "C" __declspec(dllexport) int** __stdcall GenerateHistogram(unsigned char *bmp, int dimensionImage)
{
//How to refere the bitmap from the bmp pointer?
//dimensionImage is Width = Height
}
好的,经过 2 小时的谷歌搜索、Whosebuging 和 Microsoft 文档编制,我得出了一些结论!
因为您使用的是 CUDA,所以我认为您只需要快速和好的解决方案,这就是为什么我试图找到一种方法,您可以通过它修改数据而无需多次复制数据,仅因为 C# 和 C++ 连接。
这就是我到目前为止所做的。
有些事情很重要。
我使用了一个整数指针,这对当前代码来说有点混乱。
您当然可以使用更有意义的 char 指针(尚未测试)。
另一件事是System.Drawing.Imaging.PixelFormat
。
知道您选择了哪个非常重要。在我的示例中,我选择了 PixelFormat.Format32bppRgb
。
字节顺序是(到目前为止我了解到的)名字是怎样的。
示例:
32bppRgb代表红绿蓝每8位。
然而,因为它是这种格式而不是 24bppRgb 它会消耗一个完整的整数(不使用 8 位)。在这种情况下,前 8 位没有被使用(从左到右的思考)所以要将一个像素设置为红色它是这样工作的。 (抱歉格式化没有按预期工作...)
| 8 | 8 | 8 | 8 |消耗比特
|空|红色 |绿色 |蓝色 |颜色
| 00 | FF | 00 | 00 |红色的颜色代码
所以红色的代码是这样的
=> 0x00 FF 00 00
十进制为 16711680。这就是 C++ 中数字的来源。
C++代码:
头文件"NativeLibrary.h":
namespace NativeLibrary
{
extern "C" __declspec(dllexport) void __stdcall PassBitmap(int* number, int size);
}
Cpp 文件"NativeLibrary.cpp":
#include <NativeLibrary.h>
void NativeLibrary::PassBitmap(int* number, int size) {
for (int i = 0; i < size; i++) {
number[i] = 16711680;
}
}
C#代码:
using System.Drawing;
using System.Runtime.InteropServices;
[DllImport("NativeLibrary.dll", CallingConvention = CallingConvention.StdCall)]
public static extern void PassBitmap(IntPtr bmp, int size);
public System.Drawing.Bitmap bitmap = null;
public void GenerateAndModifyBitmap()
{
//The pixel format is essential!
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(100, 100, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
//Just which region we want to lock of the bitmap
System.Drawing.Rectangle rect = new System.Drawing.Rectangle(new System.Drawing.Point(), bmp.Size);
//We want to read and write to the data, pixel format stays the same (anything else wouldn't make much sense)
System.Drawing.Imaging.BitmapData data = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
//This is a pointer to the data in memory. Can be manipulated directly!
IntPtr ptr = data.Scan0;
// This code is specific to a bitmap with 32 bits per pixels.
// Ignore current calculations. They are still work in progress xD
int size = bmp.Height;
size *= Math.Abs(data.Stride);
size /= 4;
//Call native function with our pointer to the data and of course how many ints we have
PassBitmap(ptr, size);
//Work is finished. Give our data back to the manager
bmp.UnlockBits(data);
bitmap = bmp;
}
此代码将生成一个完全红色的位图。
我对这种东西很陌生。我正在尝试创建一个等同于图像直方图函数的函数。我正在使用 windows 表单应用程序来显示直方图(并加载图像)和 CUDA/c++ 来制作直方图。我从一开始就提到我没有使用 openCV、glut、OpenGL 或任何其他第三方库。继续...我正在尝试将位图传递给非托管 C++ DLL。这里的问题是我现在不知道如何在 C++ 代码中引用该位图。 (甚至如何从中获取 RGB)。 代码片段:
c#:
private void calculateHistogram(object sender, EventArgs e)
{
Bitmap bmp = (Bitmap)pictureBox1.Image;
unsafe {
int** matrixAcumulated;
var date = bmp.LockBits(new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
matrixAcumulated=NativeMethods.GenerateHistogram(date.Scan0, pictureBox1.Width);
bmp.UnlockBits(date);
// Write the string to a file.
System.Console.WriteLine(matrixAcumulated[0][0]);
}
}
Dll 导入:
using System;
using System.Runtime.InteropServices;
namespace HistogramProcessingCs
{
class NativeMethods
{
[DllImport("HistogramProcessingCpp.dll", CallingConvention = CallingConvention.StdCall)]
public static extern unsafe int** GenerateHistogram(IntPtr bmp, int dimensionImage);
}
}
c++:
extern "C" __declspec(dllexport) int** __stdcall GenerateHistogram(unsigned char *bmp, int dimensionImage)
{
//How to refere the bitmap from the bmp pointer?
//dimensionImage is Width = Height
}
好的,经过 2 小时的谷歌搜索、Whosebuging 和 Microsoft 文档编制,我得出了一些结论!
因为您使用的是 CUDA,所以我认为您只需要快速和好的解决方案,这就是为什么我试图找到一种方法,您可以通过它修改数据而无需多次复制数据,仅因为 C# 和 C++ 连接。
这就是我到目前为止所做的。
有些事情很重要。
我使用了一个整数指针,这对当前代码来说有点混乱。
您当然可以使用更有意义的 char 指针(尚未测试)。
另一件事是System.Drawing.Imaging.PixelFormat
。
知道您选择了哪个非常重要。在我的示例中,我选择了 PixelFormat.Format32bppRgb
。
字节顺序是(到目前为止我了解到的)名字是怎样的。
示例:
32bppRgb代表红绿蓝每8位。 然而,因为它是这种格式而不是 24bppRgb 它会消耗一个完整的整数(不使用 8 位)。在这种情况下,前 8 位没有被使用(从左到右的思考)所以要将一个像素设置为红色它是这样工作的。 (抱歉格式化没有按预期工作...)
| 8 | 8 | 8 | 8 |消耗比特
|空|红色 |绿色 |蓝色 |颜色
| 00 | FF | 00 | 00 |红色的颜色代码
所以红色的代码是这样的 => 0x00 FF 00 00 十进制为 16711680。这就是 C++ 中数字的来源。
C++代码:
头文件"NativeLibrary.h":
namespace NativeLibrary
{
extern "C" __declspec(dllexport) void __stdcall PassBitmap(int* number, int size);
}
Cpp 文件"NativeLibrary.cpp":
#include <NativeLibrary.h>
void NativeLibrary::PassBitmap(int* number, int size) {
for (int i = 0; i < size; i++) {
number[i] = 16711680;
}
}
C#代码:
using System.Drawing;
using System.Runtime.InteropServices;
[DllImport("NativeLibrary.dll", CallingConvention = CallingConvention.StdCall)]
public static extern void PassBitmap(IntPtr bmp, int size);
public System.Drawing.Bitmap bitmap = null;
public void GenerateAndModifyBitmap()
{
//The pixel format is essential!
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(100, 100, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
//Just which region we want to lock of the bitmap
System.Drawing.Rectangle rect = new System.Drawing.Rectangle(new System.Drawing.Point(), bmp.Size);
//We want to read and write to the data, pixel format stays the same (anything else wouldn't make much sense)
System.Drawing.Imaging.BitmapData data = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
//This is a pointer to the data in memory. Can be manipulated directly!
IntPtr ptr = data.Scan0;
// This code is specific to a bitmap with 32 bits per pixels.
// Ignore current calculations. They are still work in progress xD
int size = bmp.Height;
size *= Math.Abs(data.Stride);
size /= 4;
//Call native function with our pointer to the data and of course how many ints we have
PassBitmap(ptr, size);
//Work is finished. Give our data back to the manager
bmp.UnlockBits(data);
bitmap = bmp;
}
此代码将生成一个完全红色的位图。