c#和c++的opencv位图数据参数互换问题解决方法

51 篇文章 3 订阅
36 篇文章 29 订阅

1.******************************

C#调用vc++ dll 传递参数的问题(Bitmap 转换为 opencv mat ),保存后图片不一样。

vc++ 代码

bool Recognize(Point_2F *arr,uchar* b)
{

Mat src=cv::Mat(415,770,CV_8UC3,b);

/*for (int i=0;i<src.rows;i++) 
{
memcpy(src.ptr(i),b+i*src.cols,src.cols);
}*/
cv::imwrite("D:\\my_2_testfiles\\111_before.png",src);

// 保存的照片和原来的照片不一样而且大小也不一样?

}

C#代码

 [DllImport("rectanglepoints.dll", EntryPoint = "Recognize", CallingConvention = CallingConvention.Cdecl)]
        static extern byte Recognize(IntPtr arr, IntPtr b);

复制代码

{ 
 // Create a new bitmap.
            Bitmap bmp = new Bitmap("D:\\my_2_testfiles\\111.png");

            // Lock the bitmap's bits.  
            Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
            System.Drawing.Imaging.BitmapData bmpData =
                bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
                bmp.PixelFormat);
            // Get the address of the first line.
            IntPtr ptrImg = bmpData.Scan0;
bool ret;
    ret = Convert.ToBoolean(Recognize(IntPtr.Zero, ptrImg));   

 // Unlock the bits.
            bmp.UnlockBits(bmpData);

            Console.Read();

        } 

复制代码

照片附加

原图:

 

调用vc++ dll后保存的图片

2.******************************************************************

C#Bitmap和C++ opencv Mat相互转换  C#调用C++编译成的dll,这个dll中包含Opencv个的Mat到c#的Bitmap转换,具体代码如下:  C++部分:  首先创建win32应用程序,选择类库模板    DLL_APIuchar * _stdcall run1(char* filename, int&width, int&height, int&step) {   IplImage* uu = cvLoadImage(filename);   IplImage * dst1 = cvCreateImage(cvSize(uu->width, uu->height), 8, 1); cvCvtColor(uu, dst1, CV_RGB2GRAY); Matss = cvarrToMat(uu);   uchar * data = new uchar[uu->width*uu->height * 3]; data = ss.data;   width = ss.size().width; height = ss.size().height; step = ss.step;  return data; }  C#中调用这个dll  [DllImport(@"E:\Files\BarcodeProject\Code\testCode\OpenCvAssemblies\Debug\OpenCvAssemblies.dll" )]  publicstaticexternIntPtr run1(string a, outint width, outint height, outint step);  至此完成C++ Mat到Bitmap的转换  下面是Bitmap 到 Mat的转换 C# 部分  publicstaticBitmapInfoGetImagePixel(Bitmap Source) { byte[] result; int step;  intiWidth = Source.Width; intiHeight = Source.Height;  Rectanglerect = newRectangle(0, 0, iWidth, iHeight);  System.Drawing.Imaging.BitmapDatabmpData = Source.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, Source.PixelFormat); IntPtriPtr = bmpData.Scan0;  intiBytes = iWidth * iHeight * 3; //根据通道数进行设置 byte[] PixelValues = newbyte[iBytes];    //int time = Environment.TickCount;  System.Runtime.InteropServices.Marshal .Copy(iPtr, PixelValues, 0, iBytes); //time = Environment.TickCount - time; //Console.WriteLine(time.ToString() + "ms"); Source.UnlockBits(bmpData); step = bmpData.Stride; result = PixelValues; // return result; // step = 0;  BitmapInfo bi = newBitmapInfo{ Result=result, Step=step }; return bi; } }  ///<summary> /// Bitmap信息类 ///</summary>  publicclassBitmapInfo {  publicbyte[] Result { get;  set; } publicint Step { get; set; }  }  Step 是扫描的步长,这个很重要,如果这个步长不是原来的值,就会造成图像偏移,从而造成失真。    C++部分  DLL_APIvoid_stdcallshow(uchar* data,intwidth,intheight,intstep) { Matimage(height,width, CV_8UC3,data,step); //image.data = data; imshow("Image",image);    //Mat(int rows, int cols, int type, void* data, size_t step = AUTO_STEP); }  C# 中调用方式  BitmapInfo bi = GetImagePixel(bitmap);  show(bi.Result,bitmap.Width,bitmap.Height,bi.Step);  至此完成他们的相互转换

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在C#中调用C++编写的OpenCV dll,可以使用Platform Invoke(P/Invoke)技术。下面是一个简单的示例,演示如何在C#中调用C++编写的OpenCV dll: 1. 创建一个新的C#控制台应用程序。 2. 在项目文件夹中创建一个名为“opencv”的子文件夹。 3. 将OpenCV dll文件复制到该子文件夹中。 4. 在Visual Studio中打开项目,并添加以下代码: ```C# using System; using System.Runtime.InteropServices; class Program { [DllImport("opencv\\opencv_core320.dll", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr cvCreateImage( [MarshalAs(UnmanagedType.Struct)] CvSize size, int depth, int channels); static void Main(string[] args) { // 创建一个256x256的8位单通道图像 var size = new CvSize(256, 256); var image = cvCreateImage(size, 8, 1); // 在控制台中输出图像信息 Console.WriteLine("Image created: {0}x{1}, depth={2}, channels={3}", size.Width, size.Height, 8, 1); Console.ReadKey(); } } [StructLayout(LayoutKind.Sequential)] public struct CvSize { public int Width; public int Height; public CvSize(int width, int height) { Width = width; Height = height; } } ``` 上面的代码创建了一个256x256的8位单通道图像,并在控制台中输出了图像信息。 在上面的代码中,我们使用DllImport属性来指定要导入的OpenCV dll的名称和调用约定。在本例中,我们使用Cdecl调用约定。 我们还定义了一个结构体CvSize,用于传递图像大小参数。在C++中,CvSize结构体定义在opencv_core.hpp头文件中。我们在C#中重新定义了这个结构体,以便我们可以在C#中使用它来传递参数。 需要注意的是,由于C++C#使用不同的内存管理机制,因此您需要确保在C#中正确处理从C++返回的指针。在本例中,我们使用IntPtr类型来表示从C++返回的指针,并使用Marshal类中的相关方法来管理它们。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值