目的
在使用OpenCvSharp过程中,经常需要访问或修改像素值(如At),使用正确的C#数据类型与MatType对应,否则会导致获取或修改的像素值有误,因此,做了个类型做对照表,方便日后查找。
MatType类型
格式:CV_[位数][数据类型]C[通道数]
如:MatType.CV_8UC3 表示3通道8位无符号整数
MatType.CV_64FC4 表示4通道64位浮点数
位数:8位、16位、32位、64位
数据类型:S(Signed integer)有符号整数、U(Unsigned integer)无符号整数、F(Float) 浮点数
通道数:1、2、3、4等(大于0,小于512)
MatType类型C#数据类型对照表
类型 | 数据类型 | 对应C#类型 | 取值范围 |
---|---|---|---|
CV_8U | 8位无符号整数 | byte | 0到255 |
CV_8S | 8位带符号整数 | sbyte | -128到127 |
CV_16U | 16位无符号整数 | ushort char | 0到65,535 |
CV_16S | 16位带符号整数 | short | -32,768 到 32,767 |
CV_32S | 32位带符号整数 | int | -2,147,483,648 到 2,147,483,647 |
CV_32F | 32位浮点数 | float | ±1.5 x 10^−45 至 ±3.4 x 10^38 |
CV_64F | 64位浮点数 | double | ±5.0 × 10^−324 到 ±1.7 × 10^308 |
CV_USERTYPE1 | 自定义 |
MatType的TypeMap属性
/// <summary>
/// typeof(T) -> MatType
/// </summary>
protected static readonly IReadOnlyDictionary<Type, MatType> TypeMap = new Dictionary<Type, MatType>
{
[typeof(byte)] = MatType.CV_8UC1,
[typeof(sbyte)] = MatType.CV_8SC1,
[typeof(short)] = MatType.CV_16SC1,
[typeof(char)] = MatType.CV_16UC1,
[typeof(ushort)] = MatType.CV_16UC1,
[typeof(int)] = MatType.CV_32SC1,
[typeof(float)] = MatType.CV_32FC1,
[typeof(double)] = MatType.CV_64FC1,
[typeof(Vec2b)] = MatType.CV_8UC2,
[typeof(Vec3b)] = MatType.CV_8UC3,
[typeof(Vec4b)] = MatType.CV_8UC4,
[typeof(Vec6b)] = MatType.CV_8UC(6),
[typeof(Vec2s)] = MatType.CV_16SC2,
[typeof(Vec3s)] = MatType.CV_16SC3,
[typeof(Vec4s)] = MatType.CV_16SC4,
[typeof(Vec6s)] = MatType.CV_16SC(6),
[typeof(Vec2w)] = MatType.CV_16UC2,
[typeof(Vec3w)] = MatType.CV_16UC3,
[typeof(Vec4w)] = MatType.CV_16UC4,
[typeof(Vec6w)] = MatType.CV_16UC(6),
[typeof(Vec2i)] = MatType.CV_32SC2,
[typeof(Vec3i)] = MatType.CV_32SC3,
[typeof(Vec4i)] = MatType.CV_32SC4,
[typeof(Vec6i)] = MatType.CV_32SC(6),
[typeof(Vec2f)] = MatType.CV_32FC2,
[typeof(Vec3f)] = MatType.CV_32FC3,
[typeof(Vec4f)] = MatType.CV_32FC4,
[typeof(Vec6f)] = MatType.CV_32FC(6),
[typeof(Vec2d)] = MatType.CV_64FC2,
[typeof(Vec3d)] = MatType.CV_64FC3,
[typeof(Vec4d)] = MatType.CV_64FC4,
[typeof(Vec6d)] = MatType.CV_64FC(6),
[typeof(Point)] = MatType.CV_32SC2,
[typeof(Point2f)] = MatType.CV_32FC2,
[typeof(Point2d)] = MatType.CV_64FC2,
[typeof(Point3i)] = MatType.CV_32SC3,
[typeof(Point3f)] = MatType.CV_32FC3,
[typeof(Point3d)] = MatType.CV_64FC3,
[typeof(Size)] = MatType.CV_32SC2,
[typeof(Size2f)] = MatType.CV_32FC2,
[typeof(Size2d)] = MatType.CV_64FC2,
[typeof(Rect)] = MatType.CV_32SC4,
[typeof(Rect2f)] = MatType.CV_32FC4,
[typeof(Rect2d)] = MatType.CV_64FC4,
[typeof(DMatch)] = MatType.CV_32FC4,
};
源码示例
Mat mat1 = Mat.Ones(new Size(3, 3), MatType.CV_8U);
//正确结果 1
Console.WriteLine(mat1.At<byte>(0, 0));
//错误结果 16843009
Console.WriteLine(mat1.At<int>(0, 0));
Mat mat2 = new Mat(3, 3, MatType.CV_8S, new sbyte[]{-4,-3,-2,
-1,0,1,
2,3,4});
//正确结果 -3
Console.WriteLine(mat2.At<sbyte>(0, 1));
//错误结果 253
Console.WriteLine(mat2.At<byte>(0, 1));
//错误结果 16776957
Console.WriteLine(mat2.At<int>(0, 1));
//错误的初始化
//类型int与MatType.CV_8U不对应
Mat mat3 = new Mat(3, 3, MatType.CV_8U, new int[] {1,2,3,
4,5,6,
7,8,9});
//实际mat3内容
//1, 0, 0
//0, 2, 0
//0, 0, 3
//想得到2,实际是0
Console.WriteLine(mat3.At<byte>(0, 1));