C# VB NIVision Halcon混合编程——NIVision图像与Halcon图像互转:.Net指针操作

编程入门 行业动态 更新时间:2024-10-07 14:26:28

C# VB NIVision Halcon混合编程——NIVision<a href=https://www.elefans.com/category/jswz/34/1771430.html style=图像与Halcon图像互转:.Net指针操作"/>

C# VB NIVision Halcon混合编程——NIVision图像与Halcon图像互转:.Net指针操作

NIVision图像VisionImage转Halcon图像HObject:C#版

//NationalInstruments.Vision.dll
//NationalInstruments.Vision.Common.dll
//NationalInstruments.Vision.Acquisition.Imaqdx.dllusing NationalInstruments.Vision
using NationalInstruments.Vision.AnalysisPrivate void VisionImage2HObject()
{try{if (Getimage_Busy(0)){//For I = 0 To DT(142).U//Cam(0).GetImage(1).WriteBmpFile(Application.StartupPath + "\\AOI Image\\" + //PT_AB(3) + "_" + I + ".bmp") '飞拍图片写入硬盘//NextVisionImage Image = new VisionImage();PixelValue2D p2D;//Cam(0).TriggerSource = NiCamera.TriggerSourceType.Software;for(int I = 0; I< DT(142).U; I++){Algorithms.Rotate(Cam(0).GetImage(1), Image, A_To_R(DT(244).S / 100));Image.WriteBmpFile(Application.StartupPath + "\\AOI Image\\" + "_" + I + ".bmp"); //飞拍图片写入硬盘p2D = Image.ImageToArray();                Byte[] imagedata=null;/byte二维数组转一维数组imagedata = ByteArrToByte(p2D.U8, Image.Height, Image.Width); //p2D.U8按行列排序的HalconDotNet.HObject hImage=new HalconDotNet.HObject();                IntPtr jj= new IntPtr();/byte()转IntPrt  CSDN关键字“在VB.Net中使用指针”//以下语句告诉net垃圾回收进程不对imagedata进行处理,也就是说imagedata占用的内存区域固定不变。System.Runtime.InteropServices.GCHandle thObject = System.Runtime.InteropServices.GCHandle.Alloc(imagedata, System.Runtime.InteropServices.GCHandleType.Pinned);IntPtr tpObject = thObject.AddrOfPinnedObject(); //取得指向字节数组的指针HalconDotNet.HOperatorSet.GenImage1(out hImage, "byte", Image.Width, Image.Height, tpObject);HalconDotNet.HOperatorSet.WriteImage(hImage, "bmp", 0, Application.StartupPath + "\\AOI Image\\" + "_H" + I + ".bmp");//在使用完毕后一定要释放指针指向的内存块,让垃圾回收器可对这个内存块回收处理if (thObject.IsAllocated)thObject.Free();}Image.Dispose();Cam(0).TriggerSource = NiCamera.TriggerSourceType.Software;Getimage_Busy(0) = False;}elseThreading.Thread.Sleep(10);        }catch(Exception ex){MsgBox(ex.ToString);}
}//bytebyte二维数组转一维数组
public static byte[] ByteArrToByte(Byte[,] b, int nNum1, int nNum2)
{List<byte> list = new List<byte>();for (int i = 0; i < nNum1; i++){for (int j = 0; j < nNum2; j++)list.Add(b[i, j]);}byte[] newB = list.ToArray();return newB;
}

 

 

 

 

NIVision图像VisionImage转Halcon图像HObject:VB.Net版

'NationalInstruments.Vision.dll
'NationalInstruments.Vision.Common.dll
'NationalInstruments.Vision.Acquisition.Imaqdx.dllImports NationalInstruments.Vision
Imports NationalInstruments.Vision.AnalysisPrivate Sub VisionImage2HObject()TryIf Getimage_Busy(0) Then'For I = 0 To DT(142).U'    Cam(0).GetImage(1).WriteBmpFile(Application.StartupPath & "\AOI Image\" & PT_AB(3) & "_" & I & ".bmp") '飞拍图片写入硬盘'NextDim Image As New VisionImageDim p2D As PixelValue2D'Cam(0).TriggerSource = NiCamera.TriggerSourceType.SoftwareFor I = 0 To DT(142).U - 1Algorithms.Rotate(Cam(0).GetImage(1), Image, A_To_R(DT(244).S / 100))Image.WriteBmpFile(Application.StartupPath & "\AOI Image\" & "_" & I & ".bmp") '飞拍图片写入硬盘p2D = Image.ImageToArray()Dim imagedata As Byte() = Nothing'''''byte二维数组转一维数组imagedata = ByteArrToByte(p2D.U8, Image.Height, Image.Width) 'p2D.U8按行列排序的Dim hImage As New HalconDotNet.HObjectDim jj As New IntPtr'''''byte()转IntPrt  CSDN关键字“在VB.Net中使用指针”'以下语句告诉net垃圾回收进程不对imagedata进行处理,也就是说imagedata占用的内存区域固定不变。Dim thObject As System.Runtime.InteropServices.GCHandle = System.Runtime.InteropServices.GCHandle.Alloc(imagedata, System.Runtime.InteropServices.GCHandleType.Pinned)Dim tpObject As IntPtr = thObject.AddrOfPinnedObject() '取得指向字节数组的指针HalconDotNet.HOperatorSet.GenImage1(hImage, "byte", Image.Width, Image.Height, tpObject)HalconDotNet.HOperatorSet.WriteImage(hImage, "bmp", 0, Application.StartupPath & "\AOI Image\" & "_H" & I & ".bmp")'在使用完毕后一定要释放指针指向的内存块,让垃圾回收器可对这个内存块回收处理If thObject.IsAllocated ThenthObject.Free()End IfNextImage.Dispose()Cam(0).TriggerSource = NiCamera.TriggerSourceType.SoftwareGetimage_Busy(0) = FalseElseThreading.Thread.Sleep(10)End IfCatch ex As ExceptionMsgBox(ex.ToString)End TryEnd Sub'bytebyte二维数组转一维数组
Private Function ByteArrToByte(ByVal b As Byte(,), ByVal nNum1 As Int16, ByVal nNum2 As Int16) As Byte()Dim lstByte As New List(Of Byte)For i = 0 To nNum1 - 1For j = 0 To nNum2 - 1lstByte.Add(b(i, j))NextNextDim newB As Byte()newB = lstByte.ToArrayReturn newB
End Function

 

Halcon图像HObject转NIVision图像VisionImage,步骤倒过来就好了:

HalconDotNet.HOperatorSet.GetImagePointer1(hImage, out Pointer, "byte", out Width, out Height);

将Pointer转byte[]

            //将内存中的buffer保存到byte[]中,IntPtr转byte[]
            IntPtr buffer = Pointer;
            int size = Width * Height;            
            byte[] imagedata = new byte[size];
            System.Runtime.InteropServices.Marshal.Copy(buffer, imagedata, 0, size); 
            if (buffer != IntPtr.Zero)  //记得要释放buffer
            {
                //camera.MKL_ReleaseBuffer(buffer);
                buffer = IntPtr.Zero;
            }

将byte[]转byte[,]

PixelValue2D p2D.U8=ByteArrToByte(Byte[] b, Height[0].I(), Width[0].I()); //byte一维数组转二维数组

ArrayToImage(p2D);

 


 

 

Byte 一维数组 和 二维数组 互转

public static byte[] ByteArrToByte(Byte[,] b, int nNum1, int nNum2){List<byte> list = new List<byte>();for (int i = 0; i < nNum1; i++){for (int j = 0; j < nNum2; j++)list.Add(b[i, j]);}byte[] newB = list.ToArray();return newB;}public static byte[,] ByteArrToByte(Byte[] b, int nNum1, int nNum2){byte[,] newB = new byte[nNum1, nNum2];for (int i = 0; i < nNum1; i++){for (int j = 0; j < nNum2; j++){newB[i, j] = b[j + nNum2 * i];}}return newB;}

 

在VB.Net中使用指针

例1:以下程序我们申请几个指向不同类型的指针:

’使用<StructLayout(LayoutKind.Sequential)>属性告诉net编译器:结构的元素在内存中按其出现的顺序排列
<StructLayout(LayoutKind.Sequential)> _
Public Structure DEFUDT_Test
 Public bytb As Byte
 Public i32a As Int32
End Structure

Public Function fnGetIntptr1() As IntPtr
 ’取得一个4字节数组指针
 Dim tabytTest(3) As Byte
 ’以下语句告诉net垃圾回收进程不对tabytTest进行处理,也就是说tabytTest占用的内存区域固定不变。
 Dim thObject As GCHandle = GCHandle.Alloc(tabytTest, GCHandleType.Pinned)
 Dim tpObject As IntPtr = thObject.AddrOfPinnedObject() ’取得指向字节数组的指针

 ’取得一个指向32位内存数据的指针,
 ’由于使用gchandle取指针的方法只能对引用的对象有效,
 ’所以对如int32等值类型必须使用将其封装成为一个对象的方法以变为引用类型
 Dim ti32Test As Object = Convert.ToInt32(0)
 ’以下语句告诉net垃圾回收进程不对ti32test进行处理,也就是说ti32Test的内存位置固定不变。
 Dim thObject1 As GCHandle = GCHandle.Alloc(ti32Test, GCHandleType.Pinned)
 Dim tpObject1 As IntPtr = thObject1.AddrOfPinnedObject() ’取得ti32Test的首地址

 Dim tudtTest1 As DEFUDT_Test
 ’由于结构是一种值类型变量,为保证指针申请方便,我们申请
 ’取得一个和结构tudtTest1大小一致的字节数组指针,只要空间占用长度和结构一样就可以了
 ’由于net在结构封装中会插入额外的数据位,所以一定要用sizeof方法得到结构在非托管使用时的实际大小
 Dim tudtTest(Marshal.SizeOf(tudtTest1)) As Byte
 Dim thObject2 As GCHandle = GCHandle.Alloc(tudtTest, GCHandleType.Pinned)
 Dim tpObject2 As IntPtr = thObject2.AddrOfPinnedObject() ’取得指向结构的指针

 ’在这儿你可以写对指针处理的任意代码(在例2中会给予补充)……

 ’在使用完毕后一定要释放指针指向的内存块,让垃圾回收器可对这个内存块回收处理
 If thObject.IsAllocated Then
  thObject.Free()
 End If
 If thObject1.IsAllocated Then
  thObject1.Free()
 End If
 If thObject2.IsAllocated Then
  thObject2.Free()
 End If
End Function

  上例中指针流程处理可以归纳为:

  1、 定义一个具有合适内存长度的引用变量(关于引用变量和值变量的差异可以参观vb的书籍)

  2、使用GCHandle.Alloc方法将变量的内存区域固定下来。

  3、使用GCHandle对象的AddrOfPinnedObject取得该内存区域的首地址并赋值给指针变量.

  4、对指针进行操作

  5、使用GCHandle对象的free方法释放指针指向的内存区域以便net垃圾回收器可以回收这个内存空间

  2、指针所指向数据的存取

  在中,对指针指向数据的存储函数都封装在marshal类中,主要的函数包括:Copy、PtrToStringUni 、PtrToStructure 、OffsetOf、WriteXXX,RreadXXX等,其中WriteXXX的表示向指针所表示的地址中写入XXX类型的数据,而ReadXXX中作用就是将指针所在地址的数据以XXX类型方式读出。看例程2,我们使用这些方法演示对例1那几个指向不同类型数据的指针作数据存/取操作。

  例2:演示向例1申请得到的几个指针执行写入及读取数据的操作.

Marshal.WriteInt32(tpObject1, 0, Convert.ToInt32(77)) ’向ti32Test变量指向的地址写入32位整数77
MsgBox("现在ti32Test的值为:" & ti32Test) ’因为变量存储地址的数据已改为77,所以显示为77
’以下这句之所以可行,因为ti32Test是32位整数,而tpObject指向的tabytTest数组刚好有4个元素
’而每一个byte元素都占用8位,合起来就是32位,和ti32Test占用的空间一样。这就印证了前面提’
’到的net中指针没有指向类型的说明。
Marshal.WriteInt32(tpObject, 0, ti32Test)

’以下代码再将tabytTest字节数组的内容理解为一个int32整数,
’并将值赋值给tudtTest结构中的int32元素

’我们使用Marshal.OffsetOf(GetType(DEFUDT_Test), "i32a").ToInt32以取得i32a元素在结构中的内存偏移位置
’所以New IntPtr(tpObject2.ToInt32 + Marshal.OffsetOf(GetType(DEFUDT_Test), "i32a").ToInt32)就临时产生了
’一个指针并指向i32a所在的内存地址(, 这个方法也说明了指针可以以字节为单位进行加减计算以指向合适的变量。
’Marshal.ReadInt32的作用是从指针中读取一个32整数。
Marshal.WriteInt32(New IntPtr(tpObject2.ToInt32 + Marshal.OffsetOf(GetType(DEFUDT_Test), "i32a").ToInt32), _
0, Marshal.ReadInt32(tpObject))
’这儿可以将字节数组的内容复制到真正的结构中
MsgBox(Marshal.OffsetOf(tudtTest1.GetType, "i32a").ToInt32)
tudtTest1 = CType(Marshal.PtrToStructure(tpObject2, GetType(DEFUDT_Test)), DEFUDT_Test)

MsgBox("结构tidtTest1中i32a元素的值为:" & tudtTest1.i32a) ’此处将显示刚赋的值77

 

C# byte[]与byte*(IntPtr)内存copy

1.byte* 转 byte[]

public int (byte* write_data, int data_len)
{
    byte[] write = new byte[data_len];
    Marshal.Copy((IntPtr)write_data, write, 0, write.Length);
}

2.byte[] 转 byte*

public void (byte[] write)
{
    IntPtr write_data = Marshal.AllocHGlobal(write.Length);    
    Marshal.Copy(write, 0, write_data, write.Length);
    Marshal.FreeHGlobal(write_data );
}

3.byte* 复制到 byte*

[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);

CopyMemory((IntPtr)(m_buffer_in + m_buffer_in_pos), (IntPtr)out_data, (uint)out_len);

 

 

 

更多推荐

C# VB NIVision Halcon混合编程——NIVision图像与Halcon图像互转:.Net指针操作

本文发布于:2024-02-06 12:14:51,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1748847.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:图像   指针   操作   NIVision   VB

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!