我从Kinect V2相机中取出红外帧。这些框架以WritableBitmap的形式出现,所以我尝试使用我制作的代码进行转换:
public Mat WritableBitmapToMat(WriteableBitmap writeBmp)
{
Bitmap bmp;
using (MemoryStream outStream = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create((BitmapSource)writeBmp));
enc.Save(outStream);
bmp = new Bitmap(outStream);
}
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
IntPtr data = bmpData.Scan0;
int step = bmpData.Stride;
Mat mat = new Mat(bmp.Height, bmp.Width, Emgu.CV.CvEnum.DepthType.Cv32F, 4, data, step);
bmp.UnlockBits(bmpData);
return mat;
}
我不知道转换是否有问题,但是当我尝试使用此代码在窗口中显示图像时:
CvInvoke.Imshow("window showing a picture", infraredMat);
我最终得到一个如下所示的异常:
异常:抛出异常:Emgu.CV.World.dll中的“System.AccessViolationException”(“试图读取或写入受保护的内存。这通常表示其他内存已损坏。”)。
我还想提一下我使用的是EmguCV 3.1和Kinect SDK 2.0
提前感谢我获得的任何帮助。
答案 0 :(得分:1)
如果您查看Kinect 2.0 SDK中的InfraredBasics-WPF示例,则会将IR图像从ushort
方法提取到FrameReference.AcquireFrame()
向量中。然后,您可以使用IntPtr infraredBuffer.UnderlyingBuffer
访问帧数据(以不安全的方法)来获取1-D向量。如果需要,您可以稍后使用标准2xfor循环将1-D转换为2-D矩阵。
这样您就不必访问`BitmapEncoder中的数据了。另外,因为它是SDK中的标准示例,所以我认为这是获取IR帧的推荐方法。此外,该示例还包含用于显示IR图像的方法;除非你有特定的方法/理由使用你的方式。
答案 1 :(得分:0)
使用以下代码可以很容易地将C#中的位图转换为EMGUCV的Mat:
Bitmap bmp = new Bitmap("FilePath");//Declare a Bitmap Object
Image<Bgr, Byte> bmp_I = new Image<Bgr, byte>(bmp);//Creating an Image object in EMGUCV which can read Bitmap object.
Mat converted_mat = bmp_I.Mat;//Convert Image object into Mat
答案 2 :(得分:0)
我使用这种方法取得了很大的成功:
public static Mat ToMat(BitmapSource source)
{
if (source.Format == PixelFormats.Bgra32)
{
Mat result = new Mat();
result.Create(source.PixelHeight, source.PixelWidth, DepthType.Cv8U, 4);
source.CopyPixels(Int32Rect.Empty, result.DataPointer, result.Step * result.Rows, result.Step);
return result;
}
else if (source.Format == PixelFormats.Bgr24)
{
Mat result = new Mat();
result.Create(source.PixelHeight, source.PixelWidth, DepthType.Cv8U, 3);
source.CopyPixels(Int32Rect.Empty, result.DataPointer, result.Step * result.Rows, result.Step);
return result;
}
else if (source.Format == PixelFormats.Pbgra32)
{
Mat result = new Mat();
result.Create(source.PixelHeight, source.PixelWidth, DepthType.Cv8U, 4);
source.CopyPixels(Int32Rect.Empty, result.DataPointer, result.Step * result.Rows, result.Step);
return result;
}
else
{
throw new Exception(String.Format("Conversion from BitmapSource of format {0} is not supported.", source.Format));
}
}
您可以根据需要调整此项。我不确定ImShow是否会处理32位浮点数的BitMap。通常,位图充满了字节。我可能是错的,但我从来没有试图得到任何东西,以显示浮动。
道格