【Emgu CV教程】2.1、基本方法之图像容器Mat的创建及显示
Emgu CV、图像容器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+深度值+符号类型。深度值是
8
,16
,32
,64,也就
就是存储的二进制位数。符号类型有三个值: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()
一样,运行结果如下图:
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<Bgr, Byte> image = new Image<Bgr, byte>(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 // 加载图像的类型
)
oadType默认值是ImreadModes.Color,代表彩色图像 。还有一个常用的是ImreadModes.Grayscale,在加载时把图像换成单通道的灰度图。
用起来很简单,代码如下:
Mat m = CvInvoke.Imread(AppDomain.CurrentDomain.BaseDirectory + "Images\\Demo\\lena.jpg");
默认值可以不写,加载完lena.jpg后,Mat变量是BGR格式的颜色空间,Cv8U的图像深度。如果logType = ImreadModes.Grayscale,那Mat变量就变成单通道的、Cv8U的图像深度的图片。请看下面的演示:
6、CvInvoke.Imshow弹窗显示图片
刚才利用的是WPF的Image控件显示Mat变量或者Image变量,如果您希望用弹窗的方式,请参考以下代码:
CvInvoke.DestroyAllWindows();
Image<Bgr, Byte> image = new Image<Bgr, byte>(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执行效果如下:
总结
Mat类型变量的操作基本上是看一眼就会,没有一点复杂的。下面的文章会一步步介绍Emgu CV里面的各种图像处理函数,敬请期待。
原创不易,请勿抄袭。共同进步,相互学习。
更多推荐
所有评论(0)