【Emgu.CV教程】第3篇 、基本方法之图像容器Mat的创建及显示

        还是要从Mat类型的变量创建开始。Emgu.CV里面最重要的一个类就是Mat,因为视频处理、图像分析的每一步都离不开对图像元素的操作。Mat类就是图像的一个容器,包含了采用什么样的颜色空间、通道数量、尺寸大小等各种信息。

        Mat的操作最基础,很重要、很重要、很重要

        首先咱们从创建各种样式的Mat类开始讲起。

1、创建一个黑色的图像

       简单的两句代码,就可以在你WPF的Image控件上显示一张黑色图片,宽640,高360,代码如下:

            Mat m = Mat.Zeros(360, 640, DepthType.Cv8U, 3);
            Image1.Source = m.ToBitmapSource();

       官方对Mat.Zero()函数定义如下:

       public static Mat Zeros(int rows, int cols, DepthType type, int channels)

  • rows,行数,也就是图片高度。
  • cols,列数,也就是图片宽度。
  • type,图片深度,也就是每一个图片的位数。格式是Cv+深度值+符号类型。深度值是8163264,也就就是存储的二进制位数。符号类型有三个值:S,U,F。S:signed int 有符号整形;U:unsigned int 无符号整形;F:float 单精度浮点型。
  • channels,通道数量。

       上面两行代码的意思就是创建一个宽640,高360,8位无符号整型的3通道图像,图像每个点的像素值都是0,是不是很拗口???补充知识:

  • 8位整型是指计算机编程中的一种数据类型,它占用存储空间的大小为8个比特(bit),无符号8位整型取值就是0 到 255。如果是DepthType.Cv8S,就是8位有符号整型,取值是-128 到 127。
  • ToBitmapSource()方法是来自于Emgu.CV的一个官方文件,可以将Mat类型变量显示在WPF的Image控件上,下载路径如下:

emgucv/Emgu.CV.NativeImage/BitmapSourceExtension.cs at master · emgucv/emgucv · GitHub

2、创建一个全部值都为1的图像

       刚才利用Emgu.CV内部的Zero()函数,创建了一个全为0的黑色图片。接下来我们创建一个值全为1的3通道图片,代码如下:

            Mat m = Mat.Ones(360, 640, DepthType.Cv8U, 3);
            Image1.Source = m.ToBitmapSource();

        Ones()的函数定义和Zeros()一样,运行结果如下图:

【Emgu.CV教程】第3篇 、基本方法之图像容器Mat的创建及显示_第1张图片

       VS2022的调试结果显示,只有0通道的值是1,1通道和2通道的值都是0,为什么???? 因为OpenCV里面的Ones()函数就只适用于单通道Mat变量。对于多个通道的Mat变量,Ones()只将第一个通道设置为1。

       如果我想创建一个纯白的图片,也就是3个通道的值都是255,那该怎么办,别着急,请往下看。

3、创建一个白色的图像

       代码如下:

            // Mat m = new Mat(360, 640, DepthType.Cv8U, 3);
            Mat m = new Mat(new System.Drawing.Size(640, 360), DepthType.Cv8U, 3);
            m.SetTo(new MCvScalar(255, 255, 255));
            Image1.Source = m.ToBitmapSource();

       基本思路还是先定义一个空白的Mat变量,这里有两种方式,要注意这两种方式宽、高的顺序不能颠倒。然后再给Mat变量赋值,用到SetTo()函数。这里要注意颜色值的写法:new MCvScalar(Blue, Green, Red) ,因此,要是创建红色图片,就是

       m.SetTo(new MCvScalar(0, 0, 255));

       创建蓝色图片是 m.SetTo(new MCvScalar(255, 0, 0));

       创建绿色图片是 m.SetTo(new MCvScalar(0, 255, 0));

4、Image控件显示从本地文件加载的图片

        代码非常简单,如下:

            Image image = new Image(AppDomain.CurrentDomain.BaseDirectory + "Images/Demo/lena.jpg");
            Image1.Source = image.ToBitmapSource();

       先创建Emgu.CV的Image类变量,然后按照实际路径读取图片文件,再赋值给WPF的Image控件就可以。 

5、CvInvoke.Imread从本地文件加载图片

        官方对Imread()函数的作用描述是:

        Loads an image from the specified file and returns the pointer to the loaded image. Currently the following file formats are supported: Windows bitmaps - BMP, DIB; JPEG files - JPEG, JPG, JPE; Portable Network Graphics - PNG; Portable image format - PBM, PGM, PPM; Sun rasters - SR, RAS; TIFF files - TIFF, TIF; OpenEXR HDR images - EXR; JPEG 2000 images - jp2.

         用大白话来讲,就是Imread()可以读取本地计算机上的图片文件,并转换成Mat变量。图片文件的格式可以是.bmp、.jpg、.jpeg、.png等等。基本上就是常用的图片都可以读出来。其定义如下:

public static Mat Imread(
    string filename, // 图片文件路径
    ImreadModes loadType = ImreadModes.Color // 加载图像的类型
)

         loadType默认值是ImreadModes.Color,代表彩色图像 。还有一个常用的是ImreadModes.Grayscale,在加载时把图像换成单通道的灰度图。

用起来很简单,代码如下:

Mat m = CvInvoke.Imread(AppDomain.CurrentDomain.BaseDirectory + "Images\\Demo\\lena.jpg");

【Emgu.CV教程】第3篇 、基本方法之图像容器Mat的创建及显示_第2张图片

         默认值可以不写,加载完lena.jpg后,Mat变量是BGR格式的颜色空间,Cv8U的图像深度。如果logType = ImreadModes.Grayscale,那Mat变量就变成单通道的、Cv8U的图像深度的图片。请看下面的演示:

【Emgu.CV教程】第3篇 、基本方法之图像容器Mat的创建及显示_第3张图片

6、CvInvoke.Imshow弹窗显示图片 

       刚才利用的是WPF的Image控件显示Mat变量或者Image变量,如果您希望用弹窗的方式,请参考以下代码:

            CvInvoke.DestroyAllWindows();
            Image image = new Image(AppDomain.CurrentDomain.BaseDirectory + "Images/Demo/lena.jpg");
            CvInvoke.Imshow("lena", image);

       官方对Imshow()函数定义如下 

       public static void Imshow(string name, IInputArray image)

  • name,弹窗的名称。
  • image,需要显示的变量,Mat类型,Image类型都可以。

       在使用Imshow()之前,代码其实是先执行了DestroyAllWindows()函数,它的作用是关闭所有已弹出的窗口,避免弹窗重复或累积。WPF执行效果如下:

【Emgu.CV教程】第3篇 、基本方法之图像容器Mat的创建及显示_第4张图片

总结

       Mat类型变量的操作基本上是看一眼就会,没有一点复杂的。下面的文章会一步步介绍Emgu.CV里面的各种图像处理函数,敬请期待。

原创不易,请勿抄袭。共同进步,相互学习。 

你可能感兴趣的:(Emgu.CV使用教程,c#,图像处理,计算机视觉,Emgu.CV)