您可以通过使用 DataPointer 复制非托管内存块并将托管类型转换为非托管类型来从 Mat 获取元素。设置值是相反方向的编组。
例如,您可以使用这样的扩展类
public static class MatExtension
{
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];
}
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);
}
private static dynamic CreateElement(DepthType depthType, dynamic value)
{
var element = CreateElement(depthType);
element[0] = value;
return element;
}
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];
}
}
然后可以通过单个方法调用来获取和设置值
var row = 2;
var col = 1;
var mat = new Mat(3, 3, DepthType.Cv64F, 3);
mat.SetValue(row, col, 3.14);
var value = mat.GetValue(row, col);
200000000 次操作的测试表明,动态类型版本可能比静态版本慢约 2.5 倍。
public static double GetDoubleValue(this Mat mat, int row, int col)
{
var value = new double[1];
Marshal.Copy(mat.DataPointer + (row * mat.Cols + col) * mat.ElementSize, value, 0, 1);
return value[0];
}
public static void SetDoubleValue(this Mat mat, int row, int col, double value)
{
var target = new[] { value };
Marshal.Copy(target, 0, mat.DataPointer + (row * mat.Cols + col) * mat.ElementSize, 1);
}