- Opencvsharp
MatType:
//
// 摘要:
// Creates from native cv::Mat* pointer
//
// 参数:
// ptr:
public Mat(IntPtr ptr)
{
if (ptr == IntPtr.Zero)
{
throw new OpenCvSharpException("Native object address is NULL");
}
base.ptr = ptr;
}
//
// 摘要:
// Creates empty Mat
public Mat()
{
NativeMethods.HandleException(NativeMethods.core_Mat_new1(out ptr));
}
//
// 参数:
// m:
protected Mat(Mat m)
{
if (m == null)
{
throw new ArgumentNullException("m");
}
m.ThrowIfDisposed();
NativeMethods.HandleException(NativeMethods.core_Mat_new12(m.ptr, out ptr));
if (ptr == IntPtr.Zero)
{
throw new OpenCvSharpException("imread failed.");
}
}
//
// 摘要:
// Loads an image from a file. (cv::imread)
//
// 参数:
// fileName:
// Name of file to be loaded.
//
// flags:
// Specifies color type of the loaded image
public Mat(string fileName, ImreadModes flags = ImreadModes.Color)
{
if (string.IsNullOrEmpty(fileName))
{
throw new ArgumentNullException("fileName");
}
NativeMethods.HandleException(NativeMethods.imgcodecs_imread(fileName, (int)flags, out ptr));
}
//
// 摘要:
// constructs 2D matrix of the specified size and type
//
// 参数:
// rows:
// Number of rows in a 2D array.
//
// cols:
// Number of columns in a 2D array.
//
// type:
// Array type. Use MatType.CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices,
// or MatType. CV_8UC(n), ..., CV_64FC(n) to create multi-channel matrices.
public Mat(int rows, int cols, MatType type)
{
NativeMethods.HandleException(NativeMethods.core_Mat_new2(rows, cols, type, out ptr));
}
//
// 摘要:
// constructs 2D matrix of the specified size and type
//
// 参数:
// size:
// 2D array size: Size(cols, rows) . In the Size() constructor, the number of rows
// and the number of columns go in the reverse order.
//
// type:
// Array type. Use MatType.CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices,
// or MatType.CV_8UC(n), ..., CV_64FC(n) to create multi-channel matrices.
public Mat(Size size, MatType type)
{
NativeMethods.HandleException(NativeMethods.core_Mat_new2(size.Height, size.Width, type, out ptr));
}
//
// 摘要:
// constructs 2D matrix and fills it with the specified Scalar value.
//
// 参数:
// rows:
// Number of rows in a 2D array.
//
// cols:
// Number of columns in a 2D array.
//
// type:
// Array type. Use MatType.CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices,
// or MatType. CV_8UC(n), ..., CV_64FC(n) to create multi-channel matrices.
//
// s:
// An optional value to initialize each matrix element with. To set all the matrix
// elements to the particular value after the construction, use SetTo(Scalar s)
// method .
public Mat(int rows, int cols, MatType type, Scalar s)
{
NativeMethods.HandleException(NativeMethods.core_Mat_new3(rows, cols, type, s, out ptr));
}
//
// 摘要:
// constructs 2D matrix and fills it with the specified Scalar value.
//
// 参数:
// size:
// 2D array size: Size(cols, rows) . In the Size() constructor, the number of rows
// and the number of columns go in the reverse order.
//
// type:
// Array type. Use MatType.CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices,
// or CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels)
// matrices.
//
// s:
// An optional value to initialize each matrix element with. To set all the matrix
// elements to the particular value after the construction, use SetTo(Scalar s)
// method .
public Mat(Size size, MatType type, Scalar s)
{
NativeMethods.HandleException(NativeMethods.core_Mat_new3(size.Height, size.Width, type, s, out ptr));
}
//
// 摘要:
// creates a matrix header for a part of the bigger matrix
//
// 参数:
// m:
// Array that (as a whole or partly) is assigned to the constructed matrix. No data
// is copied by these constructors. Instead, the header pointing to m data or its
// sub-array is constructed and associated with it. The reference counter, if any,
// is incremented. So, when you modify the matrix formed using such a constructor,
// you also modify the corresponding elements of m . If you want to have an independent
// copy of the sub-array, use Mat::clone() .
//
// rowRange:
// Range of the m rows to take. As usual, the range start is inclusive and the range
// end is exclusive. Use Range.All to take all the rows.
//
// colRange:
// Range of the m columns to take. Use Range.All to take all the columns.
public Mat(Mat m, Range rowRange, Range? colRange = null)
{
if (m == null)
{
throw new ArgumentNullException("m");
}
m.ThrowIfDisposed();
if (colRange.HasValue)
{
NativeMethods.HandleException(NativeMethods.core_Mat_new4(m.ptr, rowRange, colRange.Value, out ptr));
}
else
{
NativeMethods.HandleException(NativeMethods.core_Mat_new5(m.ptr, rowRange, out ptr));
}
GC.KeepAlive(m);
}
//
// 摘要:
// creates a matrix header for a part of the bigger matrix
//
// 参数:
// m:
// Array that (as a whole or partly) is assigned to the constructed matrix. No data
// is copied by these constructors. Instead, the header pointing to m data or its
// sub-array is constructed and associated with it. The reference counter, if any,
// is incremented. So, when you modify the matrix formed using such a constructor,
// you also modify the corresponding elements of m . If you want to have an independent
// copy of the sub-array, use Mat.Clone() .
//
// ranges:
// Array of selected ranges of m along each dimensionality.
public Mat(Mat m, params Range[] ranges)
{
if (m == null)
{
throw new ArgumentNullException("m");
}
if (ranges == null)
{
throw new ArgumentNullException("ranges");
}
if (ranges.Length == 0)
{
throw new ArgumentException("empty ranges", "ranges");
}
m.ThrowIfDisposed();
NativeMethods.HandleException(NativeMethods.core_Mat_new6(m.ptr, ranges, out ptr));
GC.KeepAlive(m);
}
//
// 摘要:
// creates a matrix header for a part of the bigger matrix
//
// 参数:
// m:
// Array that (as a whole or partly) is assigned to the constructed matrix. No data
// is copied by these constructors. Instead, the header pointing to m data or its
// sub-array is constructed and associated with it. The reference counter, if any,
// is incremented. So, when you modify the matrix formed using such a constructor,
// you also modify the corresponding elements of m . If you want to have an independent
// copy of the sub-array, use Mat.Clone() .
//
// roi:
// Region of interest.
public Mat(Mat m, Rect roi)
{
if (m == null)
{
throw new ArgumentNullException("m");
}
m.ThrowIfDisposed();
NativeMethods.HandleException(NativeMethods.core_Mat_new7(m.ptr, roi, out ptr));
GC.KeepAlive(m);
}
//
// 摘要:
// constructor for matrix headers pointing to user-allocated data
//
// 参数:
// rows:
// Number of rows in a 2D array.
//
// cols:
// Number of columns in a 2D array.
//
// type:
// Array type. Use MatType.CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices,
// or MatType. CV_8UC(n), ..., CV_64FC(n) to create multi-channel matrices.
//
// data:
// Pointer to the user data. Matrix constructors that take data and step parameters
// do not allocate matrix data. Instead, they just initialize the matrix header
// that points to the specified data, which means that no data is copied. This operation
// is very efficient and can be used to process external data using OpenCV functions.
// The external data is not automatically de-allocated, so you should take care
// of it.
//
// step:
// Number of bytes each matrix row occupies. The value should include the padding
// bytes at the end of each row, if any. If the parameter is missing (set to AUTO_STEP
// ), no padding is assumed and the actual step is calculated as cols*elemSize()
// .
public Mat(int rows, int cols, MatType type, IntPtr data, long step = 0L)
{
NativeMethods.HandleException(NativeMethods.core_Mat_new8(rows, cols, type, data, new IntPtr(step), out ptr));
}
//
// 摘要:
// constructor for matrix headers pointing to user-allocated data
//
// 参数:
// rows:
// Number of rows in a 2D array.
//
// cols:
// Number of columns in a 2D array.
//
// type:
// Array type. Use MatType.CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices,
// or MatType. CV_8UC(n), ..., CV_64FC(n) to create multi-channel matrices.
//
// data:
// Pointer to the user data. Matrix constructors that take data and step parameters
// do not allocate matrix data. Instead, they just initialize the matrix header
// that points to the specified data, which means that no data is copied. This operation
// is very efficient and can be used to process external data using OpenCV functions.
// The external data is not automatically de-allocated, so you should take care
// of it.
//
// step:
// Number of bytes each matrix row occupies. The value should include the padding
// bytes at the end of each row, if any. If the parameter is missing (set to AUTO_STEP
// ), no padding is assumed and the actual step is calculated as cols*elemSize()
// .
public Mat(int rows, int cols, MatType type, Array data, long step = 0L)
{
NativeMethods.HandleException(NativeMethods.core_Mat_new8(data: AllocGCHandle(data).AddrOfPinnedObject(), rows: rows, cols: cols, type: type, step: new IntPtr(step), returnValue: out ptr));
}
//
// 摘要:
// constructor for matrix headers pointing to user-allocated data
//
// 参数:
// sizes:
// Array of integers specifying an n-dimensional array shape.
//
// type:
// Array type. Use MatType.CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices,
// or MatType. CV_8UC(n), ..., CV_64FC(n) to create multi-channel matrices.
//
// data:
// Pointer to the user data. Matrix constructors that take data and step parameters
// do not allocate matrix data. Instead, they just initialize the matrix header
// that points to the specified data, which means that no data is copied. This operation
// is very efficient and can be used to process external data using OpenCV functions.
// The external data is not automatically de-allocated, so you should take care
// of it.
//
// steps:
// Array of ndims-1 steps in case of a multi-dimensional array (the last step is
// always set to the element size). If not specified, the matrix is assumed to be
// continuous.
public Mat(IEnumerable<int> sizes, MatType type, IntPtr data, IEnumerable<long>? steps = null)
{
if (sizes == null)
{
throw new ArgumentNullException("sizes");
}
if (data == IntPtr.Zero)
{
throw new ArgumentNullException("data");
}
int[] array = (sizes as int[]) ?? sizes.ToArray();
if (steps == null)
{
NativeMethods.HandleException(NativeMethods.core_Mat_new9(array.Length, array, type, data, IntPtr.Zero, out ptr));
return;
}
IntPtr[] steps2 = steps.Select((long s) => new IntPtr(s)).ToArray();
NativeMethods.HandleException(NativeMethods.core_Mat_new9(array.Length, array, type, data, steps2, out ptr));
}
//
// 摘要:
// constructor for matrix headers pointing to user-allocated data
//
// 参数:
// sizes:
// Array of integers specifying an n-dimensional array shape.
//
// type:
// Array type. Use MatType.CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices,
// or MatType. CV_8UC(n), ..., CV_64FC(n) to create multi-channel matrices.
//
// data:
// Pointer to the user data. Matrix constructors that take data and step parameters
// do not allocate matrix data. Instead, they just initialize the matrix header
// that points to the specified data, which means that no data is copied. This operation
// is very efficient and can be used to process external data using OpenCV functions.
// The external data is not automatically de-allocated, so you should take care
// of it.
//
// steps:
// Array of ndims-1 steps in case of a multi-dimensional array (the last step is
// always set to the element size). If not specified, the matrix is assumed to be
// continuous.
public Mat(IEnumerable<int> sizes, MatType type, Array data, IEnumerable<long>? steps = null)
{
if (sizes == null)
{
throw new ArgumentNullException("sizes");
}
if (data == null)
{
throw new ArgumentNullException("data");
}
GCHandle gCHandle = AllocGCHandle(data);
int[] array = (sizes as int[]) ?? sizes.ToArray();
if (steps == null)
{
NativeMethods.HandleException(NativeMethods.core_Mat_new9(array.Length, array, type, gCHandle.AddrOfPinnedObject(), IntPtr.Zero, out ptr));
return;
}
IntPtr[] steps2 = steps.Select((long s) => new IntPtr(s)).ToArray();
NativeMethods.HandleException(NativeMethods.core_Mat_new9(array.Length, array, type, gCHandle.AddrOfPinnedObject(), steps2, out ptr));
}
//
// 摘要:
// constructs n-dimensional matrix
//
// 参数:
// sizes:
// Array of integers specifying an n-dimensional array shape.
//
// type:
// Array type. Use MatType.CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices,
// or MatType. CV_8UC(n), ..., CV_64FC(n) to create multi-channel matrices.
public Mat(IEnumerable<int> sizes, MatType type)
{
if (sizes == null)
{
throw new ArgumentNullException("sizes");
}
int[] array = (sizes as int[]) ?? sizes.ToArray();
NativeMethods.HandleException(NativeMethods.core_Mat_new10(array.Length, array, type, out ptr));
}
//
// 摘要:
// constructs n-dimensional matrix
//
// 参数:
// sizes:
// Array of integers specifying an n-dimensional array shape.
//
// type:
// Array type. Use MatType.CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices,
// or MatType. CV_8UC(n), ..., CV_64FC(n) to create multi-channel matrices.
//
// s:
// An optional value to initialize each matrix element with. To set all the matrix
// elements to the particular value after the construction, use SetTo(Scalar s)
// method .
public Mat(IEnumerable<int> sizes, MatType type, Scalar s)
{
if (sizes == null)
{
throw new ArgumentNullException("sizes");
}
int[] array = (sizes as int[]) ?? sizes.ToArray();
NativeMethods.HandleException(NativeMethods.core_Mat_new11(array.Length, array, type, s, out ptr));
}
其中MatType定义如下
//
// 摘要:
// Matrix data type (depth and number of channels)
public readonly struct MatType : IEquatable<MatType>, IEquatable<int>
{
//
// 摘要:
// Entity value
private readonly int value;
private const int CV_CN_MAX = 512;
private const int CV_CN_SHIFT = 3;
private const int CV_DEPTH_MAX = 8;
//
// 摘要:
// type depth constants
public const int CV_8U = 0;
//
// 摘要:
// type depth constants
public const int CV_8S = 1;
//
// 摘要:
// type depth constants
public const int CV_16U = 2;
//
// 摘要:
// type depth constants
public const int CV_16S = 3;
//
// 摘要:
// type depth constants
public const int CV_32S = 4;
//
// 摘要:
// type depth constants
public const int CV_32F = 5;
//
// 摘要:
// type depth constants
public const int CV_64F = 6;
//
// 摘要:
// type depth constants
public const int CV_USRTYPE1 = 7;
//
// 摘要:
// predefined type constants
public static readonly MatType CV_8UC1 = CV_8UC(1);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_8UC2 = CV_8UC(2);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_8UC3 = CV_8UC(3);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_8UC4 = CV_8UC(4);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_8SC1 = CV_8SC(1);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_8SC2 = CV_8SC(2);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_8SC3 = CV_8SC(3);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_8SC4 = CV_8SC(4);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_16UC1 = CV_16UC(1);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_16UC2 = CV_16UC(2);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_16UC3 = CV_16UC(3);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_16UC4 = CV_16UC(4);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_16SC1 = CV_16SC(1);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_16SC2 = CV_16SC(2);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_16SC3 = CV_16SC(3);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_16SC4 = CV_16SC(4);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_32SC1 = CV_32SC(1);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_32SC2 = CV_32SC(2);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_32SC3 = CV_32SC(3);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_32SC4 = CV_32SC(4);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_32FC1 = CV_32FC(1);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_32FC2 = CV_32FC(2);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_32FC3 = CV_32FC(3);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_32FC4 = CV_32FC(4);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_64FC1 = CV_64FC(1);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_64FC2 = CV_64FC(2);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_64FC3 = CV_64FC(3);
//
// 摘要:
// predefined type constants
public static readonly MatType CV_64FC4 = CV_64FC(4);
//
// 摘要:
// Entity value
public int Value => value;
public int Depth => value & 7;
public bool IsInteger => Depth < 5;
public int Channels => (Value >> 3) + 1;
//
// 参数:
// value:
public MatType(int value)
{
this.value = value;
}
//
// 参数:
// self:
public static implicit operator int(MatType self)
{
return self.value;
}
public int ToInt32()
{
return value;
}
//
// 参数:
// value:
public static implicit operator MatType(int value)
{
return new MatType(value);
}
//
// 参数:
// value:
public static MatType FromInt32(int value)
{
return new MatType(value);
}
public bool Equals(MatType other)
{
return value == other.value;
}
public bool Equals(int other)
{
return value == other;
}
public override bool Equals(object? obj)
{
if (obj == null)
{
return false;
}
if (obj!.GetType() != typeof(MatType))
{
return false;
}
if (obj is MatType)
{
MatType other = (MatType)obj;
return Equals(other);
}
return false;
}
public static bool operator ==(MatType self, MatType other)
{
return self.Equals(other);
}
public static bool operator !=(MatType self, MatType other)
{
return !self.Equals(other);
}
public static bool operator ==(MatType self, int other)
{
return self.Equals(other);
}
public static bool operator !=(MatType self, int other)
{
return !self.Equals(other);
}
public override int GetHashCode()
{
return value.GetHashCode();
}
public override string ToString()
{
string text;
switch (Depth)
{
case 0:
text = "CV_8U";
break;
case 1:
text = "CV_8S";
break;
case 2:
text = "CV_16U";
break;
case 3:
text = "CV_16S";
break;
case 4:
text = "CV_32S";
break;
case 5:
text = "CV_32F";
break;
case 6:
text = "CV_64F";
break;
case 7:
text = "CV_USRTYPE1";
break;
default:
{
DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(25, 1);
defaultInterpolatedStringHandler.AppendLiteral("Unsupported type value (");
defaultInterpolatedStringHandler.AppendFormatted(Value);
defaultInterpolatedStringHandler.AppendLiteral(")");
return defaultInterpolatedStringHandler.ToStringAndClear();
}
}
int channels = Channels;
if (channels <= 4)
{
return text + "C" + channels;
}
return text + "C(" + channels + ")";
}
public static MatType CV_8UC(int ch)
{
return MakeType(0, ch);
}
public static MatType CV_8SC(int ch)
{
return MakeType(1, ch);
}
public static MatType CV_16UC(int ch)
{
return MakeType(2, ch);
}
public static MatType CV_16SC(int ch)
{
return MakeType(3, ch);
}
public static MatType CV_32SC(int ch)
{
return MakeType(4, ch);
}
public static MatType CV_32FC(int ch)
{
return MakeType(5, ch);
}
public static MatType CV_64FC(int ch)
{
return MakeType(6, ch);
}
public static MatType MakeType(int depth, int channels)
{
if (channels <= 0 || channels >= 512)
{
throw new OpenCvSharpException("Channels count should be 1.." + 511);
}
if (depth < 0 || depth >= 8)
{
throw new OpenCvSharpException("Data type depth should be 0.." + 7);
}
return (depth & 7) + (channels - 1 << 3);
}
}
很多人不重视Mat的数据类型,其实,数据类型不对往往会导致溢出、截断等各种问题,使得计算结果看起来不对,让人陷入迷茫。这篇文章我们来深入聊聊Mat的数据类型以及他们之间的转换。
Mat有的数据类型
OpenCV的文档中列出来的数据类型一共有30种,如下表对应。
[图片上传失败...(image-f0e7fb-1658796859452)]
但实际上,大于30的,比如CV_8UC5,这种是可以自己定义的。在程序的开头用一句宏来定义即可。
#define CV_8UC4 CV_MAKETYPE(CV_8U,4)
#define CV_8UC(n) CV_MAKETYPE(CV_8U,(n))
只要认识到,最关键的数据类型其实只有0~6,其他的,都是从0~6扩展通道而已,至于扩展几维,按照你的实际情况来就好。这里再解释一下,0~6的数据类型对应的数据范围:
无符号8bit整型(最常用):Unsigned 8bits uchar 0~255
IplImage: IPL_DEPTH_8U
Mat: CV_8UC1, CV_8UC2, CV_8UC3, CV_8UC4
有符号8bit整型:Signed 8bits char -128~127
IplImage: IPL_DEPTH_8S
Mat: CV_8SC1,CV_8SC2,CV_8SC3,CV_8SC4
无符号16bit整型:Unsigned 16bits ushort 0~65535
IplImage: IPL_DEPTH_16U
Mat: CV_16UC1,CV_16UC2,CV_16UC3,CV_16UC4
有符号16bit整型:Signed 16bits short -32768~32767
IplImage: IPL_DEPTH_16S
Mat: CV_16SC1,CV_16SC2,CV_16SC3,CV_16SC4
有符号32bit整型:Signed 32bits int -2147483648~2147483647
IplImage: IPL_DEPTH_32S
Mat: CV_32SC1,CV_32SC2,CV_32SC3,CV_32SC4
32bit浮点数:Float 32bits float -1.1810-38~3.4010-38**
IplImage: IPL_DEPTH_32F
Mat: CV_32FC1,CV_32FC2,CV_32FC3,CV_32FC4
64bit浮点数:Double 64bits double
Mat: CV_64FC1,CV_64FC2,CV_64FC3,CV_64FC4
几种类型之间转换
要遵循几个原则:
- 在从小的数据范围转向大的数据范围时,必须先改变类型:
以 CV_8U转为CV_16U为例~
mat.convertTo(mat,2); //代表的是16U,注意,转类型的时候不需要考虑通道
mat = mat * 257; //8bit的数据乘以257就转为了16bit
从大范围转小范围,要先转再改变类型。还是以16U转8U为例:
out = mat / 257;
out.convertTo(out, CV_8U);
- 整数类型转小数类型。
先转类型再转数据,遵循这个原则~
Mat img = imread("before.png",IMREAD_UNCHANGED);
cout<<img.type()<<endl;
//先转为32F
img.convertTo(img, 5);
//再转为小数
img = img / 65535;
平常我们对Mat做一些比较复杂的运算,都需要搞清楚参数的范围,最好转为32F的来进行复杂计算,否则可能会因为溢出和截断而产生莫名其妙的BUG。
结语
以上就是关于OpenCV Mat类型的相关知识。
网友评论