麻烦使用Kinect ColorImageFrame和Emgu CV

时间:2013-02-15 03:44:00

标签: c# kinect emgucv computer-vision

我正在研究一个涉及C#,Kinect和Emgu CV的学校项目。我对C#和Emgu CV都很陌生,所以我可能会遗漏一些简单的东西。我想要做的是使用Kinect中的图像作为Emgu CV图像进行处理,但我一直收到错误。出现的错误是“TypeInitializationException未处理”和“'Emgu.Cv.CVInvoke'的类型初始化程序引发了异常。”

我用来从Kinect获取图像的代码是:

using (ColorImageFrame colorFrame = e.OpenColorImageFrame()) 
{
    if (colorFrame != null)
    {           
        byte[] pixels = new byte[colorFrame.PixelDataLength];
        colorFrame.CopyPixelDataTo(pixels);

        int stride = colorFrame.Width * 4;
        BitmapSource color = BitmapImage.Create(colorFrame.Width, colorFrame.Height,96, 96, PixelFormats.Bgr32, null, pixels, stride);
        liveFeed.Source = color;

        EmguCVProcessing(color); 
    }
    else
    {
        return;
    }
}

我还发现了一些代码,用于将BitmapSource转换为位图:Is there a good way to convert between BitmapSource and Bitmap?

无效的代码如下:

void EmguCVProcessing(BitmapSource bitmap)
{
    Bitmap bmp = GetBitmap(bitmap);

    Image<Bgr, Byte> imgLiveFeed = new Image<Bgr, Byte>(bmp);
}

从我能找到的,这应该将Bitmap转换为Emgu CV图像但由于某种原因它不是。

更多信息:

InnerException:确保文件图像是有效的托管程序集。

InnerException:确保为程序集提供了正确的文件路径。

我最好的猜测是该程序使用的是不同版本的.NET Framework,但我不确定如何解决这个问题。

2 个答案:

答案 0 :(得分:0)

我遇到了同样的问题和一个半合适的解决方案。所以我也希望有人有个好主意。

我目前所做的是逐个像素地转换图像:

private KinectSensor sensor;
private byte[] colorPixels;
private Image<Gray, UInt16> grayImage;
// during init:
this.colorPixels = new byte[this.sensor.ColorStream.FramePixelDataLength];
grayImage = new Emgu.CV.Image<Gray, UInt16>(this.sensor.ColorStream.FrameWidth, this.sensor.ColorStream.FrameHeight, new Gray(0));

// the callback for the Kinect SDK
private void SensorColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
{
    using (ColorImageFrame colorFrame = e.OpenColorImageFrame())
    {
        if (colorFrame != null)
        {
            // Copy the pixel data from the image to a temporary array
            colorFrame.CopyPixelDataTo(this.colorPixels);

            int width = 640;
            int height = 480;
            int bytesPerPx = 2;
            if (nthShot == 0)
            {
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        grayImage[height - y -1, x] = new Gray(((this.colorPixels[(y * width + x) * bytesPerPx + 1])));
                    }
                }
                // *** processing of the image comes here ***
            }
            nthShot++;
            if (nthShot == 4)
                nthShot = 0;
        }
    }
}

然而,这种方法非常慢,所以我只处理每个第n个样本。

如果某人有更好/更快的解决方案,那将是非常棒的:)

谢谢,

弗洛

答案 1 :(得分:0)

TypeInitializationException可能与二进制文件无关,无法找到Emgu CV所需的DLL。

此问题可以解决您的问题: EmguCV TypeInitializationException

此外,如果您想将Kinect v2中的ColorFrame转换为Emgu CV可处理图像(Image<Bgra,byte>),您可以使用此功能:

/**
 * Converts the ColorFrame of the Kinect v2 to an image applicable for Emgu CV
 */
    public static Image<Bgra, byte> ToImage(this ColorFrame frame)
    {
        int width = frame.FrameDescription.Width;
        int height = frame.FrameDescription.Height;
        PixelFormat format = PixelFormats.Bgr32;

        byte[] pixels = new byte[width * height * ((format.BitsPerPixel + 7) / 8)];

        if (frame.RawColorImageFormat == ColorImageFormat.Bgra)
        {
            frame.CopyRawFrameDataToArray(pixels);
        }
        else
        {
            frame.CopyConvertedFrameDataToArray(pixels, ColorImageFormat.Bgra);
        }

        Image<Bgra, byte> img = new Image<Bgra, byte>(width, height);
        img.Bytes = pixels;

        return img;
    }