如何将Emgu mat传递给需要IntPtr的Emgu函数?

时间:2016-09-11 18:35:44

标签: vb.net opencv emgucv

我正在尝试使用CvInvoke.cvConvertScale将字节深度mat转换为Int32深度mat,以准备与CvInvoke.Add一起汇总多个帧。 convert函数需要几个IntPtr个参数。

我的第一个图像是字节深度mat,我初始化了一个Int32深度mat,准备接受转换函数的结果。

但我根本无法弄清楚如何将这些mat作为参数传递给函数。 cvarrToMat始终抛出Unknown Array Type。我尝试了以下方法:

'm is a mat with a Cv8U frame from a single channel video in it

Dim dataC(m.Cols * m.Rows) As Byte
Dim dataD(m.Cols * m.Rows) As Int32
Dim handleC As GCHandle = GCHandle.Alloc(dataC, GCHandleType.Pinned)
Dim handleD As GCHandle = GCHandle.Alloc(dataD, GCHandleType.Pinned)
Dim frametoaddC_Byte As New Mat(sizes:=New Integer() {m.Cols, m.Rows, m.NumberOfChannels}, type:=CvEnum.DepthType.Cv8U, data:=handleC.AddrOfPinnedObject)
Dim frametoaddD_Int32 As New Mat(sizes:=New Integer() {m.Cols, m.Rows, m.NumberOfChannels}, type:=CvEnum.DepthType.Cv32S, data:=handleD.AddrOfPinnedObject)

frametoaddC_Byte = vid.frame(i) 'Returns a mat of depth Cv8U from a video, same size as m, one channel.

'This doesn't work
CvInvoke.cvConvertScale(Marshal.GetIUnknownForObject(frametoaddC_Byte), Marshal.GetIUnknownForObject(frametoaddD_Int32), 1, 0)
'This doesn't work either
CvInvoke.cvConvertScale(handleC.AddrOfPinnedObject, handleD.AddrOfPinnedObject, 1, 0)
'And neither does this
CvInvoke.cvConvertScale(frametoaddC_Byte.Ptr, frametoaddD_Int32.Ptr, 1, 0)
'And finally, just in case, neither does this
CvInvoke.cvConvertScale(frametoaddC_Byte, frametoaddD_Int32, 1, 0)

(令我惊讶的是,这三个IntPtr都有不同的价值 - 实际上差别很大。你会认为他们都会在记忆中接近,但事实并非如此。无论如何,别担心。)

我也尝试用这个替换两个frametoadds的Dims:

Dim frametoaddC_Byte As New Mat(m.Rows, m.Cols, CvEnum.DepthType.Cv8U, 1)
Dim frametoaddD_Int32 As New Mat(m.Rows, m.Cols, CvEnum.DepthType.Cv32S, 1)

这将是通常的语法,而不是困扰GCHandle.Alloc,实际上是我开始的地方。我只尝试了Alloc,所以我可以选择在尝试获取有效的IntPtr时使用AddrOfPinnedObject。但无济于事。

我的所有尝试都会导致同样的错误:Unknown Array Type中的cvarrToMat。样品看起来很薄。我正在使用Emgu 3.有什么想法吗?

0 个答案:

没有答案