OpenCV 将位图转换为 Mat

问题描述 投票:0回答:2

我正在使用 c# 和 OpenCV。我有一个位图,我想使用 OpenCV 提供的 VideoWriter 将其写入视频帧。我已经用 Python 完成了这个,所以知道它会起作用。我只需要从 Bitmap 到 Mat 的转换步骤。

我的(部分)代码看起来大致是这样的......

VideoWriter video = new VideoWriter(filename, fps, frameSize, false);
Bitmap image = SomethingReturningABitmap();
// NEED CONVERT FROM Bitmap to Mat
Mat frame = new Mat();
video.Write(frame);
c# opencv bitmap mat
2个回答
4
投票

我正在使用 Bitmap Converter OpenCV Extensions 将我的位图转换为内存中的 Mat 对象。

PSTK ps = new PSTK();
Image img = ps.CaptureScreen();    
Bitmap bmpScreenshot = new Bitmap(img);
image = BitmapConverter.ToMat(bmpScreenshot);

也可以执行以下操作,但这样您将在从磁盘写入和读取数据时产生大量开销。

myBitmap.Save("TempFile.PNG");
Mat myMatImage = CvInvoke.Imread("TempFile.PNG");

我想大致看看有什么区别。我使用每种方法处理 500 帧的 1920x1080 桌面屏幕投射,这就是我的发现。

平均而言,对于

Bitmap.Save/Cv2.ImRead
方法,需要
0.1403 seconds per frame
。 平均而言,对于
Bitmap Converter
方法,需要
0.09604 seconds per frame
。使用我的家用台式机保存和重新读取文件大约需要 50% 的时间。第二代酷睿 I7,16GB 内存。


0
投票

你可以简单地使用这个方法来为你转换它, 这个方法对我来说非常有效。

方法:

static void BitmapToMat(Bitmap bitmap, Mat mat)
{
    BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
    Mat tempMat = new Mat(bmpData.Height, bmpData.Width, DepthType.Cv8U, 3, bmpData.Scan0, bmpData.Stride);
    CvInvoke.Transpose(tempMat, mat);
    CvInvoke.Flip(mat, mat, FlipType.Horizontal);
    bitmap.UnlockBits(bmpData);
}

附注 起初,垫子逆时针旋转了 90 度,所以我添加了一个旋转计数器,所以请注意一些奇怪的旋转。

反转前:

static void BitmapToMat(Bitmap bitmap, Mat mat)
{
    BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
    CvInvoke.CvtColor(new Mat(bmpData.Height, bmpData.Width, DepthType.Cv8U, 3, bmpData.Scan0, bmpData.Stride), mat, ColorConversion.Bgr2Bgra);
    bitmap.UnlockBits(bmpData);
}
© www.soinside.com 2019 - 2024. All rights reserved.