还是要从Mat类型的变量创建开始。Emgu.CV里面最重要的一个类就是Mat,因为视频处理、图像分析的每一步都离不开对图像元素的操作。Mat类就是图像的一个容器,包含了采用什么样的颜色空间、通道数量、尺寸大小等各种信息。
Mat的操作最基础,很重要、很重要、很重要。
首先咱们从创建各种样式的Mat类开始讲起。
简单的两句代码,就可以在你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)
8
,16
,32
,64,也就
就是存储的二进制位数。符号类型有三个值:S,U,F。S:signed int 有符号整形;U:unsigned int 无符号整形;F:float 单精度浮点型。上面两行代码的意思就是创建一个宽640,高360,8位无符号整型的3通道图像,图像每个点的像素值都是0,是不是很拗口???补充知识:
emgucv/Emgu.CV.NativeImage/BitmapSourceExtension.cs at master · emgucv/emgucv · GitHub
刚才利用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,那该怎么办,别着急,请往下看。
代码如下:
// 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));
代码非常简单,如下:
Image image = new Image(AppDomain.CurrentDomain.BaseDirectory + "Images/Demo/lena.jpg");
Image1.Source = image.ToBitmapSource();
先创建Emgu.CV的Image类变量,然后按照实际路径读取图片文件,再赋值给WPF的Image控件就可以。
官方对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");
默认值可以不写,加载完lena.jpg后,Mat变量是BGR格式的颜色空间,Cv8U的图像深度。如果logType = ImreadModes.Grayscale,那Mat变量就变成单通道的、Cv8U的图像深度的图片。请看下面的演示:
刚才利用的是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)
在使用Imshow()之前,代码其实是先执行了DestroyAllWindows()函数,它的作用是关闭所有已弹出的窗口,避免弹窗重复或累积。WPF执行效果如下:
Mat类型变量的操作基本上是看一眼就会,没有一点复杂的。下面的文章会一步步介绍Emgu.CV里面的各种图像处理函数,敬请期待。
原创不易,请勿抄袭。共同进步,相互学习。