如何在 EmguCV 中将图像转换为矩阵,然后将矩阵转换为位图?

Posted

技术标签:

【中文标题】如何在 EmguCV 中将图像转换为矩阵,然后将矩阵转换为位图?【英文标题】:How can I convert Image to Matrix and then Matrix to Bitmap in EmguCV? 【发布时间】:2022-01-03 10:04:18 【问题描述】:

我正在尝试执行以下操作:

public partial class Form1 : Form

const string path = @"lena.png";

public Form1()

    InitializeComponent();

    Image<Bgr, byte> color = new Image<Bgr, byte>(path);

    Matrix<byte> matrix = new Matrix<byte>(color.Rows, color.Cols);

    matrix.Data = color.ToMatrix();// just an analogy

    pictureBox1.Image = col.Bitmap;
    pictureBox2.Image = gray.Bitmap;


如何在 EmguCV 中将 Image 转换为 Matrix

如何将Matrix 转换为Bitmap

【问题讨论】:

如果我没看错文档,它们都继承自CvArray,所以可能是CopyTo 成员?顺便说一句,由于图像是 3 通道 (BGR),因此矩阵应该也可以正常工作。 好的,那是哪一个——ImageMatrixMatrixBitmap? ;) 我刚刚设置了我的 C# + EmguCV env(因为我从早期就没有真正接触过 C#)能够给你一个正确的答案,而且转移目标老实说有点令人沮丧(我记得读过你的元帖子也有人指出了这一点)。 @DanMašek,您的第一条评论解决了我的第一个问题。现在,我被第二个卡住了。 @DanMašek,我将问题回滚到上一个问题。 @DanMašek,顺便说一句,我正在删除我的个人资料。所以,不要对 meta 这么紧张。 【参考方案1】:

Image 转换为Matrix

这里要注意的重要一点是ImageMatrix 都继承自CvArray。这意味着可以使用(继承的)方法CopyTo 将数据从Image 实例复制到具有相同深度和尺寸的Matrix 实例。

注意:相关性有 3 个维度——宽度、高度和频道数。

Image<Bgr, byte> color = ... ; // Initialized in some manner

Matrix<byte> matrix = new Matrix<byte>(color.Rows, color.Cols, color.NumberOfChannels);

color.CopyTo(matrix);

注意:由于需要复制整个数据数组,因此这种方法会产生成本。

Matrix 转换为Bitmap

这个其实很简单。 Matrix 继承属性Mat,它为数组数据返回一个Mat 标头(表示现有数据数组周围的薄包装器)。由于这只是创建一个标题,因此非常快(不涉及副本)。

注意:由于是标头,我假设根据我对 C++ API 的经验(尽管这似乎没有记录),只要 Mat 对象有效底层 Matrix 对象保持在范围内。

Mat 提供了一个Bitmap 属性,其行为与Image.Bitmap 相同。

Bitmap b = matrix.Mat.Bitmap;

另一种选择是使用与以前相同的方法将数据复制回Image 实例。

matrix.CopyTo(color);

然后您可以使用Bitmap 属性(速度很快,但只要您使用Bitmap,就需要Image 实例存在)。

Bitmap b = color.Bitmap;

另一种选择是使用ToBitmap 方法,该方法复制数据,因此不携带对源Image 实例的依赖。

Bitmap b = color.ToBitmap();

用于测试的来源:

using System;
using System.Drawing;
using Emgu.CV;
using Emgu.CV.Structure;
// ============================================================================
namespace CS1 
// ============================================================================
class Test

    static void Main()
    
        Image<Bgr, byte> color = new Image<Bgr, byte>(2, 2);
        for (int r = 0; r < color.Rows; r++) 
            for (int c = 0; c < color.Cols; c++) 
                int n = (c + r * color.Cols) * 3;
                color[r, c] = new Bgr(n, n+1, n+2);
            
        

        Matrix<byte> matrix = new Matrix<byte>(color.Rows, color.Cols, color.NumberOfChannels);

        color.CopyTo(matrix);

        Bitmap b = matrix.Mat.Bitmap;

        matrix.CopyTo(color);

        b = color.Bitmap;

        b = color.ToBitmap();
    

// ============================================================================
 // namespace CS1
// ============================================================================

我用来生成解决方案来编译它的 CMake 文件:

cmake_minimum_required(VERSION 3.11)
project(CS1 VERSION 0.1.0 LANGUAGES CSharp)

add_executable(cs1
    src/test.cs
)

set_property(TARGET cs1
    PROPERTY VS_DOTNET_TARGET_FRAMEWORK_VERSION "v4.6.1"
)

set_property(TARGET cs1 
    PROPERTY VS_DOTNET_REFERENCES
    "System"
    "System.Drawing"
)

set_target_properties(cs1 PROPERTIES 
    VS_DOTNET_REFERENCE_emgu_cv_world "deps/Emgu.CV.World.dll"
)

【讨论】:

以上是关于如何在 EmguCV 中将图像转换为矩阵,然后将矩阵转换为位图?的主要内容,如果未能解决你的问题,请参考以下文章

如何在opencv中将图像转换为矩阵[重复]

图像处理 - 查找轮廓 EmguCv

如何在 javafx 中将任何文本或字母转换为图像

如何在 Ruby 中将 ppt 转换为图像?

如何在c#中将位图图像转换为黑白? [复制]

如何在 C++ 中将 OpenCV 2D 矩阵转换为 1D 数组?