EmguCV学习笔记 VB.Net 2.5 Mat类、Matrix类和Image类的相互转换

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。

EmguCV学习笔记目录 Vb.net

EmguCV学习笔记目录 C#

笔者的博客网址:************VB.Net-CSDN博客****************

教程相关说明以及如何获得pdf教程和代码(博客上的教程内容会和pdf教程一致,教程中也会包含所有代码),请移步:************EmguCV学习笔记****************

​​​​​​​

2.5 Mat类、Matrix类和Image类的相互转换

Mat 类、Matrix 类和Image 类的联系:

1、Mat和Image都可以用于存储图像数据,但Image只能用于存储具有颜色和深度信息的图像数据。

2、Mat和Image都可以进行图像的基本操作,如剪裁、缩放、旋转等。

3、Matrix和Mat都可以用于存储矩阵数据,并可以进行矩阵的基本操作,如转置、逆运算、矩阵乘法等。

4、此外,Cvinvoke类提供的方法,既支持Mat也支持Image,例如Add方法。

Mat 类、Matrix 类和Image 类的区别:

1、Mat可以存储任意类型的图像数据,包括单通道和多通道的数据;而Image只能用于存储具有颜色和深度信息的图像数据。

2、Matrix只能用于存储矩阵数据,不能用于存储图像数据。

在使用时,我们应该根据实际需求选择合适的类来处理图像和矩阵数据。如果只是简单的图像处理,可以使用Image类;如果需要进行更复杂的矩阵运算,可以使用Mat类;而如果需要更高效、更灵活的矩阵运算,可以使用Matrix类。

Mat 类、Matrix 类和Image 类的相互转换

Mat、Image和Matrix都是表示图像和矩阵数据的类。它们之间可以通过一些方法相互转换。

下面的小节将说明如何在Mat、Image、Matrix以及.Net提供的Bitmap类之间相互转换。

2.5.1 Image到Mat的转换

直接使用Image类的Mat属性。

【代码位置:frmChapter2_4】Button1_Click、outputMatInfo、outputMatdata8U1CAfter

'Image转Mat

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click '

Dim img As New Image(Of Gray, Byte)(New Size(3, 4))

img.SetValue(New MCvScalar(200))

'注意,此时m的IsContinuous属性是false,也就是数据不连续

Dim m As Mat

m = img.Mat

Call outputMatInfo(m)

Call outputMatdata8U1CAfter(m)

End Sub

'输出Mat信息

Private Sub outputMatInfo(ByVal m As Mat)

Console.WriteLine("Cols:" & m.Cols)

Console.WriteLine("Rows:" & m.Rows)

Console.WriteLine("Depth:" & m.Depth)

Console.WriteLine("ElementSize:" & m.ElementSize)

Console.WriteLine("Height:" & m.Height)

Console.WriteLine("Width:" & m.Width)

Console.WriteLine("NumberOfChannels:" & m.NumberOfChannels)

Console.WriteLine("Step:" & m.Step)

Console.WriteLine("Width*Height:" & m.Size.Width & "*" & m.Size.Height)

Console.WriteLine("IsContinuous:" & m.IsContinuous)

Console.WriteLine("=====================")

End Sub

'修改后的方法(考虑数据不连续的情况)

'输出矩阵,为简化说明,这里参数为8U单通道Mat

Private Sub outputMatdata8U1CAfter(ByVal m As Mat)

Dim colcount As Integer = m.Cols

Dim rowcount As Integer = m.Rows

Dim matstep As Integer = m.Step

'每次读取数据时候的指针位置

Dim pos As IntPtr = IntPtr.Zero

For i As Integer = 0 To rowcount 1

'检查指针位置,

'如果是第一次循环,即pos初始为0,那么指针位置为mat的指针位置

'否则,应该将指针位置增加step

If pos = IntPtr.Zero Then

pos = m.DataPointer

Else

pos += matstep

End If

Dim bufferSize As Integer = colcount

Dim buffer() As Byte

ReDim buffer(bufferSize 1)

'每次循环从新的指针位置拷贝数据,拷贝的数量为mat的列数。

System.Runtime.InteropServices.Marshal.Copy(pos, buffer, 0, bufferSize)

For col As Integer = 0 To colcount 1

Console.Write(buffer(col) & " ")

Next

Console.WriteLine()

Next

End Sub

运行后如下图所示:

图2-75 Image转Mat后的信息

**注意:**上述代码运行后返回的信息:

Step:4

IsContinuous:False

这是因为在EmguCV中,Image类的Data属性表示图像数据的指针。对于一个M*N的单通道图像,其Data属性的大小本应该是M*N个字节。但是,由于内存对齐的原因(通常是按照4个字节来对齐),实际上分配给图像数据的内存大小可能会大于M*N个字节。

针对上述代码,其中创建了一个3*4的单通道图像img,该图像的深度为Byte,每个像素占用1个字节。因此,该图像的总共应该占用3*4=12个字节。但是,由于内存对齐的原因,这里总共分配了16个字节给该图像数据。

2.5.2 Matrix转Mat

直接使用Matrix类的Mat属性。

在【2.3.1 构造函数】中已经讲解过,这里不再赘述。

2.5.3 Image转Matrix

使用Image类的CopyTo方法。

【代码位置:frmChapter2_4】Button2_Click

'灰度Image转matrix

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click

Dim img As New Image(Of Gray, Byte)("C:\learnEmgucv\lena.jpg")

'分配Matrix大小

Dim matr As New Matrix(Of Byte)(img.Size)

img.CopyTo(matr)

'matrix不能直接转图片

Dim mDst As Mat

mDst = matr.Mat

'这里使用.Net的PictureBox,使用Mat转为了Bitmap

PictureBox1.Image = mDst.ToBitmap

End Sub

运行后如下图所示:

图2-76 灰度图像转matrix后的显示

【代码位置:frmChapter2_4】Button3_Click

'彩色Image转matrix

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

'由于使用Image(Of Bgr, Byte),后面的matr必须指明通道数(3)

Dim img As New Image(Of Bgr, Byte)("C:\learnEmgucv\lena.jpg")

'分配Matrix大小,注意,这里指明了3通道

Dim matr As New Matrix(Of Byte)(img.Rows, img.Cols, 3)

img.CopyTo(matr)

'matrix不能直接转图片

Dim mDst As Mat

mDst = matr.Mat

'这里使用.Net的PictureBox,使用Mat转为了Bitmap

PictureBox1.Image = mDst.ToBitmap

End Sub

运行后如下图所示:

图2-77 彩色图像转matrix后的显示

2.5.4 Mat转Matrix

使用Mat类的CopyTo方法。

【代码位置:frmChapter2_4】Button4_Click

'Mat转Matrix

Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click

Dim m As New Mat("C:\learnEmgucv\lena.jpg", CvEnum.ImreadModes.Grayscale)

'需要注意通道数

Dim matr As New Matrix(Of Byte)(m.Size)

'Mat的CopyTo方法

m.CopyTo(matr)

Dim mDst As Mat

mDst = matr.Mat

PictureBox1.Image = mDst.ToBitmap

End Sub

运行后如下图所示:

图2-78 Mat转matrix后的显示

2.5.5 Image转Bitmap

使用Image类的ToBitmap方法。

【代码位置:frmChapter2_4】Button5_Click

'Image转Bitmap

Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click

Dim img As New Image(Of Bgr, Byte)("C:\learnEmgucv\lena.jpg")

Dim bmp As Bitmap = img.ToBitmap()

PictureBox1.Image = bmp

End Sub

运行后如下图所示:

图2-79 Image转Bitmap后的显示

2.5.6 Bitmap转Image

使用BitmapExtension类的ToImage方法进行转换。

【代码位置:frmChapter2_4】Button6_Click

'Bitmap转Image

Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click

Dim bmp As New Bitmap("C:\learnEmgucv\lena.jpg")

Dim img As Image(Of Bgr, Byte)

img = BitmapExtension.ToImage(Of Bgr, Byte)(bmp)

'如果转灰度,应将Bgr修改为Gray,如下代码:

'Dim img As Image(Of Gray, Byte)

'img = BitmapExtension.ToImage(Of Gray, Byte)(bmp)

PictureBox1.Image = img.ToBitmap

End Sub

运行后如下图所示:

图2-80 Bitmap转Image后的显示

2.5.7 Mat转Bitmap

使用Mat类的ToBitmap方法。

【代码位置:frmChapter2_4】Button7_Click

'Mat转Bitmap

Private Sub Button7_Click(sender As Object, e As EventArgs) Handles Button7.Click

Dim m As New Mat("C:\learnEmgucv\lena.jpg", CvEnum.ImreadModes.Color)

Dim bmp As Bitmap = m.ToBitmap()

PictureBox1.Image = bmp

End Sub

运行后如下图所示:

图2-81 Mat转Bitmap后的显示

2.5.8 Bitmap转Mat

1、使用BitmapExtension的ToMat方法

【代码位置:frmChapter2_4】Button8_Click

'Bitmap转Mat1

Private Sub Button8_Click(sender As Object, e As EventArgs) Handles Button8.Click

Dim bmp As New Bitmap("C:\learnEmgucv\lena.jpg")

Dim m As New Mat

m = BitmapExtension.ToMat(bmp)

PictureBox1.Image = m.ToBitmap

End Sub

运行后如下图所示:

图2-82 Bitmap转Mat后的显示

2、使用BitmapData

【代码位置:frmChapter2_4】Button9_Click

'Bitmap转Mat2

Private Sub Button9_Click(sender As Object, e As EventArgs) Handles Button9.Click

Dim bmp As New Bitmap("C:\learnEmgucv\lena.jpg")

Dim bmpdata As BitmapData = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb)

'需要计划好Mat的大小、深度、通道数、步长

Dim m As New Mat(bmp.Height, bmp.Width, CvEnum.DepthType.Cv8U, 3, bmpdata.Scan0, bmpdata.Stride)

bmp.UnlockBits(bmpdata)

PictureBox1.Image = m.ToBitmap

End Sub

运行后如下图所示:

图2-83 Bitmap转Mat后的显示

相关推荐
点云侠1 小时前
二维椭圆拟合算法及推导过程
开发语言·c++·算法·计算机视觉·matlab
howard20055 小时前
1.2 图像处理基本操作
opencv·读取图像·显示图像·保存图像
jndingxin13 小时前
OpenCV视觉分析之目标跟踪(12)找到局部的最大值函数meanShift()的使用
人工智能·opencv·目标跟踪
王哈哈^_^15 小时前
【数据集】【YOLO】【目标检测】树木倒塌识别数据集 9957 张,YOLO道路树木断裂识别算法实战训练教程!
人工智能·深度学习·算法·yolo·目标检测·计算机视觉·pyqt
美狐美颜sdk15 小时前
直播美颜SDK开发指南:实时美颜技术的架构与优化策略
人工智能·深度学习·计算机视觉·音视频·美颜sdk·视频美颜sdk·美颜api
深度学习lover15 小时前
<项目代码>YOLOv7 草莓叶片病害识别<目标检测>
人工智能·yolo·目标检测·计算机视觉·草莓叶片病害识别
好喜欢吃红柚子17 小时前
【目标检测】目标检测中全连接层(Fully Connected Layer)
人工智能·pytorch·python·目标检测·计算机视觉
9分钟带帽18 小时前
opencv_相关的问题
人工智能·opencv·计算机视觉
王哈哈^_^19 小时前
【数据集】【YOLO】【目标检测】航拍船只识别数据集 3550 张,YOLO航拍水面船只识别算法实战训练教程!
人工智能·深度学习·算法·yolo·目标检测·计算机视觉·pyqt
一直在努力的小宁20 小时前
⭐SmartControl: Enhancing ControlNet for Handling Rough Visual Conditions
算法·机器学习·计算机视觉