我正在尝试使用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.有什么想法吗?