通过掩膜操作Mat元素
- 创建Mat变量
using Emgu.CV;
using Emgu.CV.Structure;
Mat B = new Mat(3, 1, Emgu.CV.CvEnum.DepthType.Cv64F, 1);
- 创建同样大小的掩膜
Matrix作为Emgu3.0版本后取代Mat的类,它具有很多实用的矩阵方法,包括获取和设置矩阵元素值。
//
// 摘要:
// Get or Set the data for this matrix
public TDepth[,] Data { get; set; }
可以用Matrix创建掩膜
Matrix<byte> mask = new Matrix<byte>(3, 1);
mask.Data[0, 0] = 1;
- 设置B(0,0)、B(1,0)和B(2,0)元素
B.SetTo(new MCvScalar(4), mask);
mask = new Matrix<byte>(3, 1);
mask.Data[1, 0] = 1;
B.SetTo(new MCvScalar(8), mask);
mask = new Matrix<byte>(3, 1);
mask.Data[2, 0] = 1;
B.SetTo(new MCvScalar(32), mask);
其实这里只是通过掩膜设置了B的元素值,我还没有找到直接读取元素值的方法,但是通过观察B的结构,我发现它的数据以byte[]方式保存,而且Mat类有一个获取数据首地址的方法,所以可以考虑操作内存修改/获取Mat元素值。
通过内存拷贝方式操作Mat元素值
- 首先需要引入命名空间
using System.Runtime.InteropServices;
using Emgu.CV;
using Emgu.CV.CvEnum;
- Mat拓展类
namespace _01_MatExtension
{
/// <summary>
/// 通过指针操作内存,修改or获取Mat元素值
/// </summary>
public static class MatExtension
{
/// <summary>
/// 获取Mat的元素值
/// </summary>
/// <param name="mat">需操作的Mat</param>
/// <param name="row">元素行</param>
/// <param name="col">元素列</param>
/// <returns></returns>
public static dynamic GetValue(this Mat mat, int row, int col)
{
var value = CreateElement(mat.Depth);
Marshal.Copy(mat.DataPointer + (row * mat.Cols + col) * mat.ElementSize, value, 0, 1);
return value[0];
}
/// <summary>
/// 修改Mat的元素值
/// </summary>
/// <param name="mat">需操作的Mat</param>
/// <param name="row">元素行</param>
/// <param name="col">元素列</param>
/// <param name="value">修改值</param>
public static void SetValue(this Mat mat, int row, int col, dynamic value)
{
var target = CreateElement(mat.Depth, value);
Marshal.Copy(target, 0, mat.DataPointer + (row * mat.Cols + col) * mat.ElementSize, 1);
}
/// <summary>
/// 根据Mat的类型,动态解析传入数据的类型
/// </summary>
/// <param name="depthType"></param>
/// <param name="value"></param>
/// <returns></returns>
private static dynamic CreateElement(DepthType depthType, dynamic value)
{
var element = CreateElement(depthType);
element[0] = value;
return element;
}
/// <summary>
/// 获取Mat元素的类型
/// </summary>
/// <param name="depthType"></param>
/// <returns></returns>
private static dynamic CreateElement(DepthType depthType)
{
if (depthType == DepthType.Cv8S)
{
return new sbyte[1];
}
if (depthType == DepthType.Cv8U)
{
return new byte[1];
}
if (depthType == DepthType.Cv16S)
{
return new short[1];
}
if (depthType == DepthType.Cv16U)
{
return new ushort[1];
}
if (depthType == DepthType.Cv32S)
{
return new int[1];
}
if (depthType == DepthType.Cv32F)
{
return new float[1];
}
if (depthType == DepthType.Cv64F)
{
return new double[1];
}
return new float[1];
}
}
}
- demo
static void Main(string[] args)
{
Mat m = new Mat(3,1,Emgu.CV.CvEnum.DepthType.Cv64F,1);
MatExtension.SetValue(m, 0, 0, 3.14);
MatExtension.SetValue(m, 1, 0, 2.14);
MatExtension.SetValue(m, 2, 0, 1.14);
Console.WriteLine(MatExtension.GetValue(m,0,0));
Console.WriteLine(MatExtension.GetValue(m,1,0));
Console.WriteLine(MatExtension.GetValue(m,2,0));
Console.ReadKey();
}
- 运行结果