C#+Helcon的HObject图像,OpenCV的Mat图像(代替IplImage类型图像),Bitmap图像三者之间的相互转化方法;HObject=>HImage(灰度/彩色);C#MAT图像与C++MAT图像的相互传输

全网图像转化源码C#版独一,为了弄清不同类型储存结构,我太难了!

一,认识HObject类型,HImage类型,Mat类型,Bitmap类型;(。。。没整理呢)

1. HObject类型

2. HImage类型

3. opencv之Mat数据类型Mat类的定义学习OpenCV2——Mat之通道的理解Mat基本操作以及灰度图转化

  data:Mat对象中的一个指针,指向内存中存放矩阵数据的一块内存 (uchar* data)

  dims:Mat所代表的矩阵的维度,如 3 * 4 的矩阵为 2 维, 3 * 4 * 5 的为3维

  channels:通道,矩阵中的每一个矩阵元素拥有的值的个数,比如说 3 * 4 矩阵中一共 12 个元素,如果每个元素有三个值,那么就说这个矩阵是 3 通道的,即 channels = 3。常见的是一张彩色图片有红、绿、蓝三个通道。

  depth:深度,即每一个像素的位数(bits),在opencv的Mat.depth()中得到的是一个 0 – 6 的数字,分别代表不同的位数:enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 }; 可见 0和1都代表8位, 2和3都代表16位,4和5代表32位,6代表64位;

  step:是一个数组,定义了矩阵的布局,具体见下面图片分析,另外注意 step1 (step / elemSize1),M.step[m-1] 总是等于 elemSize,M.step1(m-1)总是等于 channels;

  elemSize : 矩阵中每一个元素的数据大小,如果Mat中的数据的数据类型是 CV_8U 那么 elemSize = 1,CV_8UC3 那么 elemSize = 3,CV_16UC2 那么 elemSize = 4;记住另外有个 elemSize1 表示的是矩阵中数据类型的大小,即 elemSize / channels 的大小

4. Bitmap类型

二,不一定要转化(直接读文件的情况) 很简单,有点乱,整理出来再传

三,转化方法(避免 “存” “读”文件)

1.HObject<=>Bitmap(还未验证,会验证的)

(1)把Halcon的“HObject图像”转换到Bitmap图像 

 1         /// <summary> 
 2         /// 把halcon图像转换到bitmap图像 
 3         /// </summary> 
 4         /// <param name="image">HObject对象</param> 
 5         /// <param name="res">Bitmap对象</param> 
 6         private Bitmap HObjectToBitmap(HObject hImage)
 7         {
 8             HTuple hpoint, type, width, height;
 9             Bitmap res;
10             const int Alpha = 255;
11             HOperatorSet.GetImagePointer1(hImage, out hpoint, out type, out width, out height);
12 
13 
14             res = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
15             ColorPalette pal = res.Palette;
16             for (int i = 0; i <= 255; i++)
17             {
18                 string insds = Color.FromArgb(Alpha, i, i, i).ToString();
19             }
20             res.Palette = pal;
21             Rectangle rect = new Rectangle(0, 0, width, height);
22             BitmapData bitmapData = res.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
23             int PixelSize = Bitmap.GetPixelFormatSize(bitmapData.PixelFormat) / 8;
24 
25             if (width % 4 == 0)//4的倍数的时候,直接复制 
26                 CopyMemory(bitmapData.Scan0, hpoint, width * height * PixelSize);
27             else//根据高循环 
28             {
29                 for (int i = 0; i < height - 1; i++)
30                 {
31                     CopyMemory(bitmapData.Scan0, hpoint, width * PixelSize);
32                     hpoint.I += width;
33                     bitmapData.Scan0 += bitmapData.Stride;
34                 }
35             }
36             res.UnlockBits(bitmapData);
37             return res;
38         }
View Code

(2)把Bitmap图像转换到Halcon的“HObject图像”

 1         /// <summary>
 2         /// 把bitmap图像转换到halcon图像
 3         /// </summary>
 4         /// <param name="bmp"></param>
 5         /// <returns></returns>
 6         public HObject BitmapToHObject(Bitmap bmp)
 7         {
 8             try
 9             {
10 
11                 Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
12 
13                 System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
14                 IntPtr pointer = bmpData.Scan0;
15 
16                 byte[] dataBlue = new byte[bmp.Width * bmp.Height];
17                 unsafe
18                 {
19                     fixed (byte* ptrdata = dataBlue)
20                     {
21                         for (int i = 0; i < bmp.Height; i++)
22                         {
23                             CopyMemory((IntPtr)(ptrdata + bmp.Width * i), pointer + bmpData.Stride * i, bmp.Width);
24                         }
25                         HObject ho;
26                         HOperatorSet.GenImage1(out ho, "byte", bmp.Width, bmp.Height, (int)ptrdata);
27                         HImage himg = new HImage("byte", bmp.Width, bmp.Height, (IntPtr)ptrdata);
28 
29                         //HOperatorSet.DispImage(ho, hWindowControl1.HalconWindow);
30 
31                         bmp.UnlockBits(bmpData);
32                         return ho;
33                     }
34                 }
35             }
36             catch (Exception exc)
37             {
38                 return null;
39             }
40 
41         }
View Code

2.Mat<=>Bitmap(还未写,会写的)

(1)把OpenCV的“Mat图像”转换到Bitmap图像 

(2)把Bitmap图像转换到OpenCV的“Mat图像”

3.HObject<=>Mat

(1)把Halcon的“HObject图像”转换到OpenCV的“Mat图像”

 1 /// <summary>
 2         /// 把Halcon图像转换到OpenCV图像
 3         /// </summary>
 4         /// <param name="hImage">Halcon图像_HObject</param>
 5         /// <returns>OpenCV图像_Mat</returns>
 6         public Mat HImageToMat(HObject hImage)
 7         {
 8             try
 9             {
10                 Mat mImage;      // 返回值
11                 HTuple htChannels;       // 通道
12                 HTuple cType = null;     // 类型
13                 HTuple width, height;    // 宽,高
14                 width = height = 0;      
15 
16                 htChannels = null;
17                 HOperatorSet.CountChannels(hImage, out htChannels);  // 获取通道
18 
19                 // 通道存在值
20                 if (htChannels.Length == 0)
21                 {
22                     return null;
23                 }
24                 if (htChannels[0].I == 1)           // 单通道
25                 {
26                     HTuple ptr;                     // HTuple_单通道值指针
27                     HOperatorSet.GetImagePointer1(hImage, out ptr, out cType, out width, out height);       // 单通道取值方法(图片,输出“单通道值指针”,输出“类型”,输出“宽”,输出“高”)  // (ptr=2157902018096    cType=byte    width=830    height=822)         
28                     mImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1, new Scalar(0));  // 实例化mImage(大小,MatType.CV_8UC1,new Scalar(0))
29                     int Width = width;
30 
31                     unsafe
32                     {
33                         //for (int i = 0; i < height; i++)  // 循环赋值
34                         //{
35                         //    IntPtr start = IntPtr.Add(mImage.Data, i * width);                              // Mat的单通道_Data地址+偏移(start=0x000001f66d4df300     Data=0x000001f66d4df300     i * 830)
36                         //    CopyMemory(start, new IntPtr((byte*)ptr.IP + width * i), width);                // CopyMemory(要复制到的地址,复制源的地址,复制的长度)
37                         //}
38                         CopyMemory(mImage.Data, new IntPtr((byte*)ptr.IP), width*height);// CopyMemory(要复制到的地址,复制源的地址,复制的长度)
39                     }
40                     return mImage;
41                 }
42                 else if (htChannels[0].I == 3)      // 三通道
43                 {
44                     HTuple ptrRed;                  // HTuple_R通道值指针
45                     HTuple ptrGreen;                // HTuple_G通道值指针
46                     HTuple ptrBlue;                 // HTuple_B通道值指针
47 
48                     HOperatorSet.GetImagePointer3(hImage, out ptrRed, out ptrGreen, out ptrBlue, out cType, out width, out height);  // 三通道取值方法(图片,输出“R通道值指针”,输出“G通道值指针”,输出“B通道值指针”,输出“类型”,输出“宽”,输出“高”)
49                     Mat pImageRed = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);                                   // Mat_R通道值指针(大小,MatType.CV_8UC1)
50                     Mat pImageGreen = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);                                 // Mat_G通道值指针(大小,MatType.CV_8UC1)
51                     Mat pImageBlue = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);                                  // Mat_B通道值指针(大小,MatType.CV_8UC1)
52                     mImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC3, new Scalar(0, 0, 0));                     // Mat_图片(大小,MatType.CV_8UC1,new Scalar(0, 0, 0))
53                     unsafe
54                     {
55                         //for (int i = 0; i < height; i++)
56                         //{
57                         //    //long step = mImage.Step();
58                         //    IntPtr startRed = IntPtr.Add(pImageRed.Data, i * width);                    // Mat的Red_Data地址+偏移(start=0x000001f66d4df300     Data=0x000001f66d4df300     i * 830)
59                         //    IntPtr startGreen = IntPtr.Add(pImageGreen.Data, i * width);                // Mat的Green_Data地址+偏移(start=0x000001f66d4df300     Data=0x000001f66d4df300     i * 830)
60                         //    IntPtr startBlue = IntPtr.Add(pImageBlue.Data, i * width);                  // Mat的Blue_Data地址+偏移(start=0x000001f66d4df300     Data=0x000001f66d4df300     i * 830)
61                         //    CopyMemory(startRed, new IntPtr((byte*)ptrRed.IP + width * i), width);      // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Red
62                         //    CopyMemory(startGreen, new IntPtr((byte*)ptrGreen.IP + width * i), width);  // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Green
63                         //    CopyMemory(startBlue, new IntPtr((byte*)ptrBlue.IP + width * i), width);    // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Blue
64                         //}
65                         CopyMemory(pImageRed.Data, new IntPtr((byte*)ptrRed.IP), width*height);        // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Red
66                         CopyMemory(pImageGreen.Data, new IntPtr((byte*)ptrGreen.IP), width * height);  // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Green
67                         CopyMemory(pImageBlue.Data, new IntPtr((byte*)ptrBlue.IP), width * height);    // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Blue
68                     }
69                     Mat[] multi = new Mat[] { pImageBlue, pImageGreen, pImageRed };   // 存储rgb三通道
70                     Cv2.Merge(multi, mImage);                                         // rgb三通道合成一张图
71                     pImageRed.Dispose();                                              // Mat_R通道值指针销毁
72                     pImageGreen.Dispose();                                            // Mat_G通道值指针销毁
73                     pImageBlue.Dispose();                                             // Mat_B通道值指针销毁
74                     return mImage;                                                       
75                 }
76                 else
77                 {
78                     return null;
79                 }
80             }
81             catch (Exception ex)
82             {
83                 throw ex;
84             }
85         }
View Code

(2)把OpenCV的”Mat图像“转换到Halcon的“HObject图像”

  1         /// <summary>
  2         /// 把OpenCV图像转换到Halcon图像
  3         /// </summary>
  4         /// <param name="mImage">OpenCV图像_Mat</param>
  5         /// <returns>Halcon图像_HObject</returns>
  6         public HObject MatToHImage(Mat mImage)
  7         {
  8             try
  9             {
 10                 HObject hImage;
 11                 int matChannels = 0;   // 通道数
 12                 Type matType = null;
 13                 int width, height;   // 宽,高
 14                 width = height = 0;  // 宽,高初始化
 15 
 16                 // 获取通道数
 17                 matChannels = mImage.Channels();
 18                 if (matChannels == 0)
 19                 {
 20                     return null;
 21                 }
 22                 if (matChannels == 1)        // 单通道
 23                 {
 24                     IntPtr ptr;      // 灰度图通道
 25                     Mat[] mats = mImage.Split();
 26 
 27                     // 改自:Mat.GetImagePointer1(mImage, out ptr, out matType, out width, out height);     // ptr=2157902018096    cType=byte    width=830    height=822
 28                     ptr = mats[0].Data;          // 取灰度图值
 29                     matType = mImage.GetType();  // byte
 30                     height = mImage.Rows;        //
 31                     width = mImage.Cols;         // 32 
 33                     // 改自:hImage = new HObject(new OpenCvSharp.Size(width, height), MatType.CV_8UC1, new Scalar(0));
 34                     byte[] dataGrayScaleImage = new byte[width * height];      //Mat dataGrayScaleImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);
 35 
 36                     unsafe
 37                     {
 38                         fixed (byte* ptrdata = dataGrayScaleImage)
 39                         {
 40                             #region 按行复制
 41                             //for (int i = 0; i < height; i++)
 42                             //{
 43                             //    CopyMemory((IntPtr)(ptrdata + width * i), new IntPtr((long)ptr + width * i), width);
 44                             //}
 45                             #endregion
 46 
 47                             CopyMemory((IntPtr)ptrdata, new IntPtr((long)ptr), width * height);
 48                             HOperatorSet.GenImage1(out hImage, "byte", width, height, (IntPtr)ptrdata);
 49 
 50                         }
 51                     }
 52                     return hImage;
 53                 }
 54                 else if (matChannels == 3)   // 三通道
 55                 {
 56                     IntPtr ptrRed;    // R通道图
 57                     IntPtr ptrGreen;  // G通道图
 58                     IntPtr ptrBlue;   // B通道图
 59                     Mat[] mats =mImage.Split();
 60 
 61                     ptrRed = mats[0].Data;    // 取R通道值
 62                     ptrGreen = mats[1].Data;  // 取G通道值
 63                     ptrBlue = mats[2].Data;   // 取B通道值
 64                     matType = mImage.GetType();  // 类型
 65                     height = mImage.Rows;        //
 66                     width = mImage.Cols;         // 67 
 68                     // 改自:hImage = new HObject(new OpenCvSharp.Size(width, height), MatType.CV_8UC1, new Scalar(0));
 69                     byte[] dataRed = new byte[width * height];      //Mat dataGrayScaleImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);
 70                     byte[] dataGreen = new byte[width * height];
 71                     byte[] dataBlue = new byte[width * height];
 72 
 73                     unsafe
 74                     {
 75                         fixed (byte* ptrdataRed = dataRed , ptrdataGreen = dataGreen, ptrdataBlue = dataBlue)
 76                         {
 77                             #region 按行复制
 78                             //HImage himg = new HImage("byte", width, height, (IntPtr)ptrdataRed);
 79                             //for (int i = 0; i < height; i++)
 80                             //{
 81                             //     CopyMemory((IntPtr)(ptrdataRed + width * i), new IntPtr((long)ptrRed + width * i), width);
 82                             //     CopyMemory((IntPtr)(ptrdataGreen + width * i), new IntPtr((long)ptrGreen + width * i), width);
 83                             //     CopyMemory((IntPtr)(ptrdataBlue + width * i), new IntPtr((long)ptrBlue + width * i), width);
 84                             //}
 85                             #endregion
 86 
 87                             CopyMemory((IntPtr)ptrdataRed , new IntPtr((long)ptrRed ), width* height);        // 复制R通道
 88                             CopyMemory((IntPtr)ptrdataGreen , new IntPtr((long)ptrGreen ), width* height);    // 复制G通道
 89                             CopyMemory((IntPtr)ptrdataBlue , new IntPtr((long)ptrBlue ), width* height);      // 复制B通道
 90                             HOperatorSet.GenImage3(out hImage, "byte", width, height, (IntPtr)ptrdataRed, (IntPtr)ptrdataGreen, (IntPtr)ptrdataBlue);   // 合成
 91                         }                         
 92                     }
 93                     return hImage;
 94                 }
 95                 else
 96                 {
 97                     return null;
 98                 }
 99             }
100             catch (Exception ex)
101             {
102                 throw ex;
103             }
104 
105         }
View Code

4.HObject=>HImage(灰度/彩色)

(1)灰度图像 HObject -> HImage

 1 /// <summary>
 2 /// 灰度图像 HObject -> HImage
 3 /// </summary>
 4 public HImage HObjectToHImage1(HObject hObj)
 5 {
 6 HImage image = new HImage();
 7 HTuple type, width, height, pointer;
 8 HOperatorSet.GetImagePointer1(hObj, out pointer, out type, out width, out height);
 9 image.GenImage1(type, width, height, pointer);
10 return image;
11 }
View Code

(2)彩色图像 HObject -> HImage

 1 /// <summary>
 2 /// 彩色图像 HObject -> HImage
 3 /// </summary>
 4 public HImage HObjectToHImage3(HObject hObj)
 5 {
 6 HImage image = new HImage();
 7 HTuple type, width, height, pointerRed, pointerGreen, pointerBlue;
 8 HOperatorSet.GetImagePointer3(hObj, out pointerRed, out pointerGreen, out pointerBlue,
 9 out type, out width, out height);
10 image.GenImage3(type, width, height, pointerRed, pointerGreen, pointerBlue);
11 return image;
12 }
View Code

 5.灰度图HObject->彩图HObject

 1 /// <summary>
 2         /// 灰度图像 HObject -> 三通道HObject
 3         /// </summary>
 4         public HObject HObject1ToHObject3(HObject hObj)
 5         {
 6             HObject image = new HObject();
 7             HTuple type, width, height, pointer;
 8             HOperatorSet.GetImagePointer1(hObj, out pointer, out type, out width, out height);
 9             HOperatorSet.GenImage3(out image, "byte", width, height, (IntPtr)pointer, (IntPtr)pointer, (IntPtr)pointer);   // 合成
10             return image;
11         }
View Code

5.附录_全部代码:

(1)用到的NuGet包:OpenCvSharp3-AnyCPU 4.0.0.20181129

(2)全部代码:

  1 using System.Runtime.InteropServices;
  2 using System.Drawing.Imaging;
  3 using HalconDotNet;
  4 using System.Drawing;
  5 using OpenCvSharp;
  6 using System;
  7 
  8 namespace Bll.SaveImage
  9 {
 10     public class HObjectBitmap
 11     {
 12         /// <summary> 
 13         /// 把source指针长度为size的数据复制到指针dest 
 14         /// </summary> 
 15         /// <param name="dest">要复制到的地址</param> 
 16         /// <param name="source">复制源的地址</param> 
 17         /// <param name="size">复制的长度</param> 
 18         /// <returns></returns> 
 19         [DllImport("kernel32.dll")]
 20         public extern static long CopyMemory(IntPtr dest, IntPtr source, int size);
 21 
 22         /// <summary> 
 23         /// 把halcon图像转换到bitmap图像 
 24         /// </summary> 
 25         /// <param name="image">HObject对象</param> 
 26         /// <param name="res">Bitmap对象</param> 
 27         private Bitmap HObjectToBitmap(HObject hImage)
 28         {
 29             HTuple hpoint, type, width, height;
 30             Bitmap res;
 31             const int Alpha = 255;
 32             HOperatorSet.GetImagePointer1(hImage, out hpoint, out type, out width, out height);
 33 
 34 
 35             res = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
 36             ColorPalette pal = res.Palette;
 37             for (int i = 0; i <= 255; i++)
 38             {
 39                 string insds = Color.FromArgb(Alpha, i, i, i).ToString();
 40             }
 41             res.Palette = pal;
 42             Rectangle rect = new Rectangle(0, 0, width, height);
 43             BitmapData bitmapData = res.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
 44             int PixelSize = Bitmap.GetPixelFormatSize(bitmapData.PixelFormat) / 8;
 45 
 46             if (width % 4 == 0)//4的倍数的时候,直接复制 
 47                 CopyMemory(bitmapData.Scan0, hpoint, width * height * PixelSize);
 48             else//根据高循环 
 49             {
 50                 for (int i = 0; i < height - 1; i++)
 51                 {
 52                     CopyMemory(bitmapData.Scan0, hpoint, width * PixelSize);
 53                     hpoint.I += width;
 54                     bitmapData.Scan0 += bitmapData.Stride;
 55                 }
 56             }
 57             res.UnlockBits(bitmapData);
 58             return res;
 59         }
 60 
 61         /// <summary>
 62         /// 把bitmap图像转换到halcon图像
 63         /// </summary>
 64         /// <param name="bmp"></param>
 65         /// <returns></returns>
 66         public HObject BitmapToHObject(Bitmap bmp)
 67         {
 68             try
 69             {
 70 
 71                 Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
 72 
 73                 System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
 74                 IntPtr pointer = bmpData.Scan0;
 75 
 76                 byte[] dataBlue = new byte[bmp.Width * bmp.Height];
 77                 unsafe
 78                 {
 79                     fixed (byte* ptrdata = dataBlue)
 80                     {
 81                         for (int i = 0; i < bmp.Height; i++)
 82                         {
 83                             CopyMemory((IntPtr)(ptrdata + bmp.Width * i), pointer + bmpData.Stride * i, bmp.Width);
 84                         }
 85                         HObject ho;
 86                         HOperatorSet.GenImage1(out ho, "byte", bmp.Width, bmp.Height, (int)ptrdata);
 87                         HImage himg = new HImage("byte", bmp.Width, bmp.Height, (IntPtr)ptrdata);
 88 
 89                         //HOperatorSet.DispImage(ho, hWindowControl1.HalconWindow);
 90 
 91                         bmp.UnlockBits(bmpData);
 92                         return ho;
 93                     }
 94                 }
 95             }
 96             catch (Exception exc)
 97             {
 98                 return null;
 99             }
100 
101         }
102 
103         /// <summary>
104         /// 把Halcon图像转换到OpenCV图像
105         /// </summary>
106         /// <param name="hImage">Halcon图像_HObject</param>
107         /// <returns>OpenCV图像_Mat</returns>
108         public Mat HImageToMat(HObject hImage)
109         {
110             try
111             {
112                 Mat mImage;      // 返回值
113                 HTuple htChannels;       // 通道
114                 HTuple cType = null;     // 类型
115                 HTuple width, height;    // 宽,高
116                 width = height = 0;      
117 
118                 htChannels = null;
119                 HOperatorSet.CountChannels(hImage, out htChannels);  // 获取通道
120 
121                 // 通道存在值
122                 if (htChannels.Length == 0)
123                 {
124                     return null;
125                 }
126                 if (htChannels[0].I == 1)           // 单通道
127                 {
128                     HTuple ptr;                     // HTuple_单通道值指针
129                     HOperatorSet.GetImagePointer1(hImage, out ptr, out cType, out width, out height);       // 单通道取值方法(图片,输出“单通道值指针”,输出“类型”,输出“宽”,输出“高”)  // (ptr=2157902018096    cType=byte    width=830    height=822)         
130                     mImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1, new Scalar(0));  // 实例化mImage(大小,MatType.CV_8UC1,new Scalar(0))
131                     int Width = width;
132 
133                     unsafe
134                     {
135                         //for (int i = 0; i < height; i++)  // 循环赋值
136                         //{
137                         //    IntPtr start = IntPtr.Add(mImage.Data, i * width);                              // Mat的单通道_Data地址+偏移(start=0x000001f66d4df300     Data=0x000001f66d4df300     i * 830)
138                         //    CopyMemory(start, new IntPtr((byte*)ptr.IP + width * i), width);                // CopyMemory(要复制到的地址,复制源的地址,复制的长度)
139                         //}
140                         CopyMemory(mImage.Data, new IntPtr((byte*)ptr.IP), width*height);// CopyMemory(要复制到的地址,复制源的地址,复制的长度)
141                     }
142                     return mImage;
143                 }
144                 else if (htChannels[0].I == 3)      // 三通道
145                 {
146                     HTuple ptrRed;                  // HTuple_R通道值指针
147                     HTuple ptrGreen;                // HTuple_G通道值指针
148                     HTuple ptrBlue;                 // HTuple_B通道值指针
149 
150                     HOperatorSet.GetImagePointer3(hImage, out ptrRed, out ptrGreen, out ptrBlue, out cType, out width, out height);  // 三通道取值方法(图片,输出“R通道值指针”,输出“G通道值指针”,输出“B通道值指针”,输出“类型”,输出“宽”,输出“高”)
151                     Mat pImageRed = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);                                   // Mat_R通道值指针(大小,MatType.CV_8UC1)
152                     Mat pImageGreen = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);                                 // Mat_G通道值指针(大小,MatType.CV_8UC1)
153                     Mat pImageBlue = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);                                  // Mat_B通道值指针(大小,MatType.CV_8UC1)
154                     mImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC3, new Scalar(0, 0, 0));                     // Mat_图片(大小,MatType.CV_8UC1,new Scalar(0, 0, 0))
155                     unsafe
156                     {
157                         //for (int i = 0; i < height; i++)
158                         //{
159                         //    //long step = mImage.Step();
160                         //    IntPtr startRed = IntPtr.Add(pImageRed.Data, i * width);                    // Mat的Red_Data地址+偏移(start=0x000001f66d4df300     Data=0x000001f66d4df300     i * 830)
161                         //    IntPtr startGreen = IntPtr.Add(pImageGreen.Data, i * width);                // Mat的Green_Data地址+偏移(start=0x000001f66d4df300     Data=0x000001f66d4df300     i * 830)
162                         //    IntPtr startBlue = IntPtr.Add(pImageBlue.Data, i * width);                  // Mat的Blue_Data地址+偏移(start=0x000001f66d4df300     Data=0x000001f66d4df300     i * 830)
163                         //    CopyMemory(startRed, new IntPtr((byte*)ptrRed.IP + width * i), width);      // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Red
164                         //    CopyMemory(startGreen, new IntPtr((byte*)ptrGreen.IP + width * i), width);  // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Green
165                         //    CopyMemory(startBlue, new IntPtr((byte*)ptrBlue.IP + width * i), width);    // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Blue
166                         //}
167                         CopyMemory(pImageRed.Data, new IntPtr((byte*)ptrRed.IP), width*height);        // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Red
168                         CopyMemory(pImageGreen.Data, new IntPtr((byte*)ptrGreen.IP), width * height);  // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Green
169                         CopyMemory(pImageBlue.Data, new IntPtr((byte*)ptrBlue.IP), width * height);    // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Blue
170                     }
171                     Mat[] multi = new Mat[] { pImageBlue, pImageGreen, pImageRed };   // 存储rgb三通道
172                     Cv2.Merge(multi, mImage);                                         // rgb三通道合成一张图
173                     pImageRed.Dispose();                                              // Mat_R通道值指针销毁
174                     pImageGreen.Dispose();                                            // Mat_G通道值指针销毁
175                     pImageBlue.Dispose();                                             // Mat_B通道值指针销毁
176                     return mImage;                                                       
177                 }
178                 else
179                 {
180                     return null;
181                 }
182             }
183             catch (Exception ex)
184             {
185                 throw ex;
186             }
187         }
188 
189         /// <summary>
190         /// 把OpenCV图像转换到Halcon图像
191         /// </summary>
192         /// <param name="mImage">OpenCV图像_Mat</param>
193         /// <returns>Halcon图像_HObject</returns>
194         public HObject MatToHImage(Mat mImage)
195         {
196             try
197             {
198                 HObject hImage;
199                 int matChannels = 0;   // 通道数
200                 Type matType = null;
201                 int width, height;   // 宽,高
202                 width = height = 0;  // 宽,高初始化
203 
204                 // 获取通道数
205                 matChannels = mImage.Channels();
206                 if (matChannels == 0)
207                 {
208                     return null;
209                 }
210                 if (matChannels == 1)        // 单通道
211                 {
212                     IntPtr ptr;      // 灰度图通道
213                     Mat[] mats = mImage.Split();
214 
215                     // 改自:Mat.GetImagePointer1(mImage, out ptr, out matType, out width, out height);     // ptr=2157902018096    cType=byte    width=830    height=822
216                     ptr = mats[0].Data;          // 取灰度图值
217                     matType = mImage.GetType();  // byte
218                     height = mImage.Rows;        //
219                     width = mImage.Cols;         //220 
221                     // 改自:hImage = new HObject(new OpenCvSharp.Size(width, height), MatType.CV_8UC1, new Scalar(0));
222                     byte[] dataGrayScaleImage = new byte[width * height];      //Mat dataGrayScaleImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);
223 
224                     unsafe
225                     {
226                         fixed (byte* ptrdata = dataGrayScaleImage)
227                         {
228                             #region 按行复制
229                             //for (int i = 0; i < height; i++)
230                             //{
231                             //    CopyMemory((IntPtr)(ptrdata + width * i), new IntPtr((long)ptr + width * i), width);
232                             //}
233                             #endregion
234 
235                             CopyMemory((IntPtr)ptrdata, new IntPtr((long)ptr), width * height);
236                             HOperatorSet.GenImage1(out hImage, "byte", width, height, (IntPtr)ptrdata);
237 
238                         }
239                     }
240                     return hImage;
241                 }
242                 else if (matChannels == 3)   // 三通道
243                 {
244                     IntPtr ptrRed;    // R通道图
245                     IntPtr ptrGreen;  // G通道图
246                     IntPtr ptrBlue;   // B通道图
247                     Mat[] mats =mImage.Split();
248 
249                     ptrRed = mats[0].Data;    // 取R通道值
250                     ptrGreen = mats[1].Data;  // 取G通道值
251                     ptrBlue = mats[2].Data;   // 取B通道值
252                     matType = mImage.GetType();  // 类型
253                     height = mImage.Rows;        //
254                     width = mImage.Cols;         //255 
256                     // 改自:hImage = new HObject(new OpenCvSharp.Size(width, height), MatType.CV_8UC1, new Scalar(0));
257                     byte[] dataRed = new byte[width * height];      //Mat dataGrayScaleImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);
258                     byte[] dataGreen = new byte[width * height];
259                     byte[] dataBlue = new byte[width * height];
260 
261                     unsafe
262                     {
263                         fixed (byte* ptrdataRed = dataRed , ptrdataGreen = dataGreen, ptrdataBlue = dataBlue)
264                         {
265                             #region 按行复制
266                             //HImage himg = new HImage("byte", width, height, (IntPtr)ptrdataRed);
267                             //for (int i = 0; i < height; i++)
268                             //{
269                             //     CopyMemory((IntPtr)(ptrdataRed + width * i), new IntPtr((long)ptrRed + width * i), width);
270                             //     CopyMemory((IntPtr)(ptrdataGreen + width * i), new IntPtr((long)ptrGreen + width * i), width);
271                             //     CopyMemory((IntPtr)(ptrdataBlue + width * i), new IntPtr((long)ptrBlue + width * i), width);
272                             //}
273                             #endregion
274 
275                             CopyMemory((IntPtr)ptrdataRed , new IntPtr((long)ptrRed ), width* height);        // 复制R通道
276                             CopyMemory((IntPtr)ptrdataGreen , new IntPtr((long)ptrGreen ), width* height);    // 复制G通道
277                             CopyMemory((IntPtr)ptrdataBlue , new IntPtr((long)ptrBlue ), width* height);      // 复制B通道
278                             HOperatorSet.GenImage3(out hImage, "byte", width, height, (IntPtr)ptrdataRed, (IntPtr)ptrdataGreen, (IntPtr)ptrdataBlue);   // 合成
279                         }                         
280                     }
281                     return hImage;
282                 }
283                 else
284                 {
285                     return null;
286                 }
287             }
288             catch (Exception ex)
289             {
290                 throw ex;
291             }
292 
293         }
294 
295         /// <summary>
296         /// 灰度图像 HObject -> HImage
297         /// </summary>
298         public HImage HObjectToHImage1(HObject hObj)
299         {
300             HImage image = new HImage();
301             HTuple type, width, height, pointer;
302             HOperatorSet.GetImagePointer1(hObj, out pointer, out type, out width, out height);
303             image.GenImage1(type, width, height, pointer);
304             return image;
305         }
306 
307         /// <summary>
308         /// 彩色图像 HObject -> HImage
309         /// </summary>
310         public HImage HObjectToHImage3(HObject hObj)
311         {
312             HImage image = new HImage();
313             HTuple type, width, height, pointerRed, pointerGreen, pointerBlue;
314             HOperatorSet.GetImagePointer3(hObj, out pointerRed, out pointerGreen, out pointerBlue,
315                                           out type, out width, out height);
316             image.GenImage3(type, width, height, pointerRed, pointerGreen, pointerBlue);
317             return image;
318         }
319     }
320 }
View Code

 四,C#MAT图像与C++MAT图像的相互传输

C++:

dlltest.h

 1 #pragma once
 2 // dlltest.h   头文件,使用动态链接库时需要包含头文件
 3 
 4 #ifdef __DLLEXPORT
 5 #define __DLL_EXP _declspec(dllexport)    // 导出函数 - 生成dll文件时使用
 6 #else
 7 #define __DLL_EXP _declspec(dllimport)    // 导入函数 -使用dll是使用
 8 #endif // __DLLEXPORT
 9 
10 // 判断是否是c++
11 #if defined(__cplusplus)||defined(c_plusplus)
12 extern "C"
13 {
14 #endif
15     __DLL_EXP int add(int a, int b);
16     __DLL_EXP int sub(int a, int b);
17 
18 #if defined(__cplusplus)||defined(c_plusplus)
19 }
20 #endif
View Code

dlltest.cpp

 1 #include "pch.h"
 2 #include "dlltest.h"
 3 #include<stdio.h>
 4 
 5 int add(int a, int b)
 6 {
 7     return a + b;
 8 }
 9 
10 int sub(int a, int b)
11 {
12     return a - b;
13 }
View Code

CppMatToCsMat.h

 1 #pragma once
 2 #include "pch.h"
 3 #include<vector>
 4 #include <opencv2/opencv.hpp>  //头文件
 5 using namespace cv;            //包含cv命名空间
 6 using namespace std;
 7 // 头文件,使用动态链接库时需要包含头文件
 8 
 9 #ifdef __DLLEXPORT
10 #define __DLL_EXP _declspec(dllexport)    // 导出函数 - 生成dll文件时使用
11 #else
12 #define __DLL_EXP _declspec(dllimport)    // 导入函数 -使用dll是使用
13 #endif // __DLLEXPORT
14 
15 // 判断是否是c++
16 #if defined(__cplusplus)||defined(c_plusplus)
17 extern "C"
18 {
19 #endif
20     //__DLL_EXP void Getmat(uchar *data, size_t &size);
21     __DLL_EXP extern "C" _declspec(dllexport) void Getmat(uchar *data, size_t &size);
22 #if defined(__cplusplus)||defined(c_plusplus)
23 }
24 #endif
View Code

CppMatToCsMat.cpp

 1 #include "pch.h"
 2 #include "CppMatToCsMat.h"
 3 #include<vector>
 4 #include <opencv2/opencv.hpp>  //头文件
 5 using namespace cv;            //包含cv命名空间
 6 using namespace std;
 7 
 8 //void Getmat(uchar *data, size_t &size)
 9 extern "C" _declspec(dllexport) void Getmat(uchar *data, size_t &size)
10 {
11     vector<uchar>buf;               // uchar数组
12     Mat img = imread("C:\2.jpg");  // 读入图片
13     imencode(".bmp", img, buf);     // 将Mat以BMP格式存入uchar的buf数组中
14     size = buf.size();
15     for (auto it = buf.begin(); it != buf.end(); it++)  // 将buf拷贝到C#的byte[]中
16     {
17         *data = *it;
18         data++;
19     }
20 }
View Code

CsMatToCppMat.h

 1 #pragma once
 2 #include "pch.h"
 3 #include<vector>
 4 #include <opencv2/opencv.hpp>  //头文件
 5 using namespace cv;            //包含cv命名空间
 6 using namespace std;
 7 // 头文件,使用动态链接库时需要包含头文件
 8 
 9 #ifdef __DLLEXPORT
10 #define __DLL_EXP _declspec(dllexport)    // 导出函数 - 生成dll文件时使用
11 #else
12 #define __DLL_EXP _declspec(dllimport)    // 导入函数 -使用dll是使用
13 #endif // __DLLEXPORT
14 
15 // 判断是否是c++
16 #if defined(__cplusplus)||defined(c_plusplus)
17 extern "C"
18 {
19 #endif
20     __DLL_EXP extern "C" _declspec(dllexport) const void Setmat(long* ImageBuffer, int imageWedth, int imageHeigth);
21 #if defined(__cplusplus)||defined(c_plusplus)
22 }
23 #endif
View Code

CsMatToCppMat.cpp

 1 #include "pch.h"
 2 #include "CsMatToCppMat.h"
 3 #include<vector>
 4 #include <opencv2/opencv.hpp>  //头文件
 5 using namespace cv;            //包含cv命名空间
 6 using namespace std;
 7 
 8 // CsMat->CppMat
 9 extern "C" _declspec(dllexport) const void Setmat(long* ImageBuffer, int imageWedth, int imageHeigth)
10 {
11     Mat compMat = Mat(imageHeigth, imageWedth,  CV_8UC3, ImageBuffer);
12     // 在窗口中显示载入的图片
13     imshow("[载入的图片]", compMat);
14     // 等待6000 ms后窗口自动关闭
15     //waitKey(6000);
16 
17 }
View Code

CsMatToCppMatToCsMat.h

 1 #pragma once
 2 #include "pch.h"
 3 #include<vector>
 4 #include <opencv2/opencv.hpp>  //头文件
 5 using namespace cv;            //包含cv命名空间
 6 using namespace std;
 7 // 头文件,使用动态链接库时需要包含头文件
 8 
 9 #ifdef __DLLEXPORT
10 #define __DLL_EXP _declspec(dllexport)    // 导出函数 - 生成dll文件时使用
11 #else
12 #define __DLL_EXP _declspec(dllimport)    // 导入函数 -使用dll是使用
13 #endif // __DLLEXPORT
14 
15 // 判断是否是c++
16 #if defined(__cplusplus)||defined(c_plusplus)
17 extern "C"
18 {
19 #endif
20     __DLL_EXP extern "C" _declspec(dllexport) const void SetmatRuselt(long* ImageBuffer, int imageHeigth, int imageWidth, long* &imgdata, int &imgHeigth, int &imgWidth);
21 #if defined(__cplusplus)||defined(c_plusplus)
22 }
23 #endif
View Code

CsMatToCppMatToCsMat.cpp

 1 #include "pch.h"
 2 #include "CsMatToCppMatToCsMat.h"
 3 #include<vector>
 4 #include <opencv2/opencv.hpp>  //头文件
 5 using namespace cv;            //包含cv命名空间
 6 using namespace std;
 7 
 8 // CsMat->CppMat->CsMat
 9 extern "C" _declspec(dllexport) const void SetmatRuselt(long* ImageBuffer, int imageHeigth, int imageWidth, long* &imgdata,int &imgHeigth,int &imgWidth)
10 {
11     Mat compMat = Mat(imageHeigth, imageWidth, CV_8UC3, ImageBuffer);
12     //// 在窗口中显示载入的图片
13     //imshow("[载入的图片1]", compMat);
14     //// 等待6000 ms后窗口自动关闭
15     //waitKey(6000);
16 
17     //返回值
18     imgdata = (long*)compMat.data;
19     imgHeigth = compMat.rows;
20     imgWidth = compMat.cols;
21 
22     //Mat compMat2 = Mat(imageHeigth, imageWidth, CV_8UC3, imgdata);
23     //// 在窗口中显示载入的图片
24     //imshow("[载入的图片2]", compMat2);
25     //// 等待6000 ms后窗口自动关闭
26     //waitKey(6000);
27 }
View Code

CsMatToCppMatToCsMat新,解决“指向内存不对“的问题

//long* ImageBuffer, int imageWedth, int imageHeigth
extern "C" _declspec(dllexport) const char* ocrmain(long* ImageBuffer, int imageHeigth, int imageWidth) {

    //获取mat
    cv::Mat  srcimg = cv::Mat(imageHeigth, imageWidth, CV_8UC3, ImageBuffer);    
//返回值
       ....// img.data是处理完的新图片通道数据
    memcpy(ImageBuffer, img.data, sizeof(unsigned char)*img.rows*img.cols*img.channels());

    const char* test;
    test = "1";

    return test;
}
View Code

//返回值
memcpy(ImageBuffer, img.data, sizeof(unsigned char)*img.rows*img.cols*img.channels());

const char* test;
test = ocrstring.c_str();

return test;

C#:

  1 using Bll.SaveImage;
  2 using OpenCvSharp;
  3 using System;
  4 using System.Collections.Generic;
  5 using System.ComponentModel;
  6 using System.Data;
  7 using System.Drawing;
  8 using System.IO;
  9 using System.Linq;
 10 using System.Runtime.InteropServices;
 11 using System.Text;
 12 using System.Threading.Tasks;
 13 using System.Windows.Forms;
 14 
 15 namespace repo.素材
 16 {
 17     public partial class 调用dll : Form
 18     {
 19         /// <summary> 
 20         /// 把source指针长度为size的数据复制到指针dest 
 21         /// </summary> 
 22         /// <param name="dest">要复制到的地址</param> 
 23         /// <param name="source">复制源的地址</param> 
 24         /// <param name="size">复制的长度</param> 
 25         /// <returns></returns> 
 26         [DllImport("kernel32.dll")]
 27         public extern static long CopyMemory(IntPtr dest, IntPtr source, int size);
 28 
 29         HObjectMatBitmap hObjectMatBitmap21 = new HObjectMatBitmap();
 30 
 31         // OpencvSharp的图片显示类
 32         SharpWindows Imgwindow;
 33         // 全局图片Mat类型
 34         Mat rawimg;
 35         public 调用dll()
 36         {
 37             InitializeComponent();
 38             // 委托
 39             Imgwindow = new SharpWindows(this.pic_ShowPic, "MainUIwindow");
 40         }
 41 
 42         // OCR接口
 43         [DllImport("main.dll")]
 44         //public extern static void ocrmainone();
 45         public extern static IntPtr ocrmain(IntPtr ImageBuffer, int imageHeigth, int imageWidth);
 46         private void button1_Click(object sender, EventArgs e)
 47         {
 48             //try
 49             //{
 50             var filename = OpenfileDlg();
 51             if (filename != null && filename != "")
 52             {
 53                 Mat img = Cv2.ImRead(filename);
 54                 // 图像数据,高度,宽度
 55                 IntPtr ptr1 = img.Data;
 56                 int imageHeigth = img.Height;
 57                 int imageWidth = img.Width;
 58 
 59                 IntPtr ocrStr =ocrmain(new IntPtr((long)ptr1), imageHeigth, imageWidth);
 60                 Mat lam = new Mat(imageHeigth, imageWidth, MatType.CV_8UC3, ptr1);
 61                 Cv2.ImShow("[载入的图片3]", lam);
 62                 Imgwindow.Showimg(lam);
 63                 string myString = Marshal.PtrToStringAnsi(ocrStr);
 64 
 65                 #region 转换为utf-8编码
 66                 byte[] bytes = Encoding.Default.GetBytes(myString);
 67                 string myStringr = Encoding.UTF8.GetString(bytes);
 68                 #endregion
 69 
 70                 textBox2.Text = myStringr;
 71             }
 72             //}
 73             //catch (Exception ex)
 74             //{
 75             //    throw (ex);
 76             //}
 77         }
 78 
 79         #region 通过路径取文件方法
 80         /// <summary>
 81         /// 通过路径取文件方法
 82         /// </summary>
 83         /// <param name="Defaultpath"></param>
 84         /// <returns></returns>
 85         private static string OpenfileDlg(string Defaultpath = null)
 86         {
 87             OpenFileDialog ofd = new OpenFileDialog();
 88             ofd.Title = "请选择要打开的文件";
 89             //多选
 90             ofd.Multiselect = true;
 91             //初始目录
 92             ofd.InitialDirectory = Defaultpath;
 93             //设定文件类型
 94             //   ofd.Filter = "*.bmp | *.jpg";
 95 
 96             ofd.ShowDialog();
 97 
 98             //获得在打开文件对话框中选择的文件的路径
 99             string path = ofd.FileName;
100             return path;
101         }
102         #endregion
103 
104         // 求和
105         [DllImport("main.dll")]
106         public extern static int sum(int a, int b);
107         private void button3_Click(object sender, EventArgs e)
108         {
109             int i1 = 10, i2 = 5;
110             int sumruselt = sum(i1, i2);
111             txt1.Text = sumruselt.ToString();
112         }
113 
114         [DllImport("Dlltext.dll")]
115         /// <summary>
116         /// Dlltext
117         /// </summary>
118         /// <param name="data"></param>
119         /// <param name=""> </param>
120         /// <param name=""> </param>
121         /// <returns></returns>
122         public extern static int add(int a, int b);
123         private void button4_Click(object sender, EventArgs e)
124         {
125             int iruselt = add(3, 5);
126             textBox1.Text = iruselt.ToString();
127         }
128 
129         // CppMat->CsMat
130         [DllImport("Dlltext.dll")]
131         public static extern void Getmat(ref byte data, out ulong size);
132         private void button5_Click(object sender, EventArgs e)
133         {
134             //Mat Csmat;
135             //byte[] imgdata = new byte[width * height * 3];  // 存储图片的数组,必须大于等于图片分辨率
136             byte[] imgdata = new byte[3200 * 2400 * 3];  // 存储图片的数组,必须大于等于图片分辨率
137             ulong size = new ulong();
138             Getmat(ref imgdata[0], out size);
139             textBox1.Text = size.ToString();
140             pictureBox1.Image = Image.FromStream(new MemoryStream(imgdata, 0, (int)size));
141         }
142 
143         // CsMat->CppMat
144         [DllImport("Dlltext.dll")]
145         public static extern void Setmat(IntPtr bytedata, int width, int height);
146         private void button6_Click(object sender, EventArgs e)
147         {
148             // 图像实际宽度,高度
149             int imgWidth, imgHeigth;
150             //try
151             //{
152             var filename = OpenfileDlg();
153             if (filename != null && filename != "")
154             {
155                 // 读取Mat图像
156                 Mat img = Cv2.ImRead(filename);
157 
158                 // 取高宽
159                 imgWidth = img.Width;
160                 imgHeigth = img.Height;
161                 IntPtr ptr1 = img.Data;
162 
163                 //Mat lacalMat = new Mat(imgHeigth, imgWidth, MatType.CV_8UC3, ptr1);
164                 //Cv2.ImShow("[载入的图片]", lacalMat);
165                 Setmat(new IntPtr((long)ptr1), imgWidth, imgHeigth);
166             }
167             //}
168             //catch (Exception ex)
169             //{
170             //    throw (ex);
171             //}
172         }
173 
174         // CsMat->CppMat->CsMat
175         [DllImport("Dlltext.dll")]
176         public static extern void SetmatRuselt(IntPtr ImageBuffer, int imageHeigth, int imageWidth, out IntPtr imgdata, out int imgHeigth, out int imgWidth);
177         private void button7_Click(object sender, EventArgs e)
178         {
179             try
180             {
181                 var filename = OpenfileDlg();
182                 if (filename != null && filename != "")
183                 {
184                     // 读取Mat图像
185                     Mat img = Cv2.ImRead(filename);
186 
187                     // 图像数据,高度,宽度
188                     IntPtr ptr1 = img.Data;
189                     int imageHeigth = img.Height;
190                     int imageWidth = img.Width;
191 
192                     SetmatRuselt(new IntPtr((long)ptr1), imageHeigth, imageWidth, out IntPtr imgdata, out int imgHeigth, out int imgWidth);
193 
194                     Mat lacalMatr = new Mat(imgHeigth, imgWidth, MatType.CV_8UC3, imgdata);
195                     Cv2.ImShow("[载入的图片3]", lacalMatr);
196                 }
197             }
198             catch (Exception ex)
199             {
200                 throw (ex);
201             }
202         }
203 
204         private void button2_Click(object sender, EventArgs e)
205         {
206 
207         }
208         // CsMat->CppMat->CsMat
209         [DllImport("main.dll")]
210         public static extern void SetmatRuselt1(IntPtr ImageBuffer, int imageHeigth, int imageWidth, out IntPtr imgdata, out int imgHeigth, out int imgWidth);
211         private void button8_Click(object sender, EventArgs e)
212         {
213             var filename = OpenfileDlg();
214             if (filename != null && filename != "")
215             {
216                 // 读取Mat图像
217                 Mat img = Cv2.ImRead(filename);
218 
219                 // 图像数据,高度,宽度
220                 IntPtr ptr1 = img.Data;
221                 int imageHeigth = img.Height;
222                 int imageWidth = img.Width;
223 
224                 SetmatRuselt1(new IntPtr((long)ptr1), imageHeigth, imageWidth, out IntPtr imgdata, out int imgHeigth, out int imgWidth);
225 
226                 Mat lacalMatr = new Mat(imgHeigth, imgWidth, MatType.CV_8UC3, imgdata);
227                 Cv2.ImShow("[载入的图片3]", lacalMatr);
228             }
229         }
230     }
231 }
View Code
365个夜晚,我希望做到两天更一篇博客。加油,小白!
原文地址:https://www.cnblogs.com/qq2806933146xiaobai/p/13299193.html