Opencv理解Mat与基本操作
数据类型
CV_8UC1*// 8位无符号单通道*
CV_8UC3*// 8位无符号3通道*
CV_8UC4
CV_32FC1*// 32位浮点型单通道*
CV_32FC3*// 32位浮点型3通道*
包括数据位深度8位、32位,数据类型U:uchar、F:float型以及通道数C1:单通道、C3:三通道、C4:四通道。
构造函数
1 |
|
Create方法
该方法不能为矩阵设置初始值,只是在改变尺寸时为矩阵数据重新分配内存。
1 |
|
几种特殊矩阵初始化方式的说明
1 |
|
小矩阵的初始化
1 |
|
矩阵运算
加减法
1 |
|
$$
\begin{bmatrix}
1 & 0 & 0 \
0 & 1 & 0
\end{bmatrix}+
\begin{bmatrix}
1 & 1 & 1 \
1 & 1 & 1
\end{bmatrix}=
\begin{bmatrix}
2 & 1 & 1 \
1 & 2 & 1
\end{bmatrix} \\
\begin{bmatrix}
1 & 0 & 0 \
0 & 1 & 0
\end{bmatrix}-
\begin{bmatrix}
1 & 1 & 1 \
1 & 1 & 1
\end{bmatrix}=
\begin{bmatrix}
0 & -1 & -1 \
-1 & 0 & -1
\end{bmatrix}
$$
矩阵乘法
1.按位相乘($A_{m*n}.B_{mn}$)
1 |
|
2.点乘法($A_{mn}B_{np}$)
1 |
|
$$
\begin{bmatrix}
1 & 0 & 0 \
0 & 1 & 0
\end{bmatrix}2=
\begin{bmatrix}
2 & 0 & 0 \
0 & 2 & 0
\end{bmatrix} \\
\begin{bmatrix}
2 & 1 & 1 \
1 & 2 & 1
\end{bmatrix}.
\begin{bmatrix}
4 & 3 & 3 \
3 & 4 & 3
\end{bmatrix}=
\begin{bmatrix}
8 & 3 & 3 \
3 & 8 & 3
\end{bmatrix}\\
\begin{bmatrix}
1 & 0 & 0 \
0 & 1 & 0
\end{bmatrix}*
\begin{bmatrix}
1 & 1 \
1 & 1 \
1 & 1
\end{bmatrix}=
\begin{bmatrix}
1 & 1 \
1 & 1
\end{bmatrix}
$$
矩阵的转置
1 |
|
矩阵的逆
1 |
|
计算矩阵非零元素个数
1 |
|
矩阵的均值和标准差
1 |
|
求最大最小值
1 |
|
- src – 输入单通道矩阵(图像).
- minVal – 指向最小值的指针, 如果未指定则使用NULL
- maxVal – 指向最大值的指针, 如果未指定则使用NULL
- minLoc – 指向最小值位置(2维情况)的指针, 如果未指定则使用NULL
- maxLoc – 指向最大值位置(2维情况)的指针, 如果未指定则使用NULL
- mask – 可选的蒙版,用于选择待处理子区域
1 |
|
其他矩阵运算
Function (函数名) | Use (函数用处) |
---|---|
add | 矩阵加法,A+B的更高级形式,支持mask |
scaleAdd | 矩阵加法,一个带有缩放因子dst(I) = scale * src1(I) + src2(I) |
addWeighted | 矩阵加法,两个带有缩放因子dst(I) = saturate(src1(I) * alpha + src2(I) * beta + gamma) |
subtract | 矩阵减法,A-B的更高级形式,支持mask |
multiply | 矩阵逐元素乘法,同Mat::mul()函数,与A*B区别,支持mask |
gemm | 一个广义的矩阵乘法操作 |
divide | 矩阵逐元素除法,与A/B区别,支持mask |
abs | 对每个元素求绝对值 |
absdiff | 两个矩阵的差的绝对值 |
exp | 求每个矩阵元素 src(I) 的自然数 e 的 src(I) 次幂 dst[I] = esrc(I) |
pow | 求每个矩阵元素 src(I) 的 p 次幂 dst[I] = src(I)p |
log | 求每个矩阵元素的自然数底 dst[I] = log |
sqrt | 求每个矩阵元素的平方根 |
min, max | 求每个元素的最小值或最大值返回这个矩阵 dst(I) = min(src1(I), src2(I)), max同 |
minMaxLoc | 定位矩阵中最小值、最大值的位置 |
compare | 返回逐个元素比较结果的矩阵 |
bitwise_and, bitwise_not, bitwise_or, bitwise_xor | 每个元素进行位运算,分别是和、非、或、异或 |
cvarrToMat | 旧版数据CvMat,IplImage,CvMatND转换到新版数据Mat |
extractImageCOI | 从旧版数据中提取指定的通道矩阵给新版数据Mat |
randu | 以Uniform分布产生随机数填充矩阵,同 RNG::fill(mat, RNG::UNIFORM) |
randn | 以Normal分布产生随机数填充矩阵,同 RNG::fill(mat, RNG::NORMAL) |
randShuffle | 随机打乱一个一维向量的元素顺序 |
theRNG() | 返回一个默认构造的RNG类的对象 theRNG()::fill(…) |
reduce | 矩阵缩成向量 |
repeat | 矩阵拷贝的时候指定按x/y方向重复 |
split | 多通道矩阵分解成多个单通道矩阵 |
merge | 多个单通道矩阵合成一个多通道矩阵 |
mixChannels | 矩阵间通道拷贝,如Rgba[]到Rgb[]和Alpha[] |
sort, sortIdx | 为矩阵的每行或每列元素排序 |
setIdentity | 设置单元矩阵 |
completeSymm | 矩阵上下三角拷贝 |
inRange | 检查元素的取值范围是否在另两个矩阵的元素取值之间,返回验证矩阵 |
checkRange | 检查矩阵的每个元素的取值是否在最小值与最大值之间,返回验证结果bool |
sum | 求矩阵的元素和 |
mean | 求均值 |
meanStdDev | 均值和标准差 |
countNonZero | 统计非零值个数 |
cartToPolar, polarToCart | 笛卡尔坐标与极坐标之间的转换 |
flip | 矩阵翻转 |
transpose | 矩阵转置,比较 Mat::t() AT |
trace | 矩阵的迹 |
determinant | 行列式 |
eigen | 矩阵的特征值和特征向量 |
invert | 矩阵的逆或者伪逆,比较 Mat::inv() |
magnitude | 向量长度计算 dst(I) = sqrt(x(I)2 + y(I)2) |
Mahalanobis | Mahalanobis距离计算 |
phase | 相位计算,即两个向量之间的夹角 |
norm | 求范数,1-范数、2-范数、无穷范数 |
normalize | 标准化 |
mulTransposed | 矩阵和它自己的转置相乘 AT * A, dst = scale(src - delta)T(src - delta) |
convertScaleAbs | 先缩放元素再取绝对值,最后转换格式为8bit型 |
calcCovarMatrix | 计算协方差阵 |
solve | 求解1个或多个线性系统或者求解最小平方问题(least-squares problem) |
solveCubic | 求解三次方程的根 |
solvePoly | 求解多项式的实根和重根 |
dct, idct | 正、逆离散余弦变换,idct同dct(src, dst, flags |
dft, idft | 正、逆离散傅立叶变换, idft同dft(src, dst, flags |
LUT | 查表变换 |
getOptimalDFTSize | 返回一个优化过的DFT大小 |
mulSpecturms | 两个傅立叶频谱间逐元素的乘法 |
Mat基础
- 1、在计算机内存中,数字图像是采用矩阵的方式保存的。Opencv2中,保存图像像素信息的是数据结构Mat阵,它包含两部分:矩阵头和一个指向像素数据的矩阵针。矩阵头主要包含:矩阵尺寸、存储方式、存储地址、引用计数等。矩阵头的大小是一定的,不会随着图像的大小改变而改变,通常图像像素数据都会很大。因此,在图像的复制和传递过程中不需要复制整个Mat数据,只复制矩阵头和指向像素矩阵的指针即可。
- 2、由此会出现多个Mat共用一个矩阵数据的情况,那么内存回收的时候会存在什么时候释放矩阵数据的问题,对于释放内存的时候引用计数就会起作用了,当Mat对象被复制一次时,引用计数会加一,而销毁一个Mat对象(共用同一个图像矩阵数据)时引用计数减一,当引用计数为0的时候,矩阵数据就会被除。
- 3、在使用Mat的时候:
a、OpenCV中内存通常是自动分配,特殊情况需要特别指定。
b、使用OpenCV的C++接口时不用考虑内存释放问题。
c、需要复制矩阵数据,可以使用Image.clone()和Image1.copyTo(Image2)。
Mat存储方法
Mat矩阵中不同的每个元素可以使用不同数据类型,最小的数据类型是char型,占用一个字节(1byte=8bits),可以是有符号(0到255)和无符号(-127到127)的。在RGB颜色空间中,使用三个char型可以表示1600万种颜色.在Opencv中可以使用cv::Scalar(b,g,r)或者CV_RGB(r,g,b)表示。
Mat的创建
1、构造函数
官方文档指定规则如下:
CV_[The number of bits per item][Signed or Unsigned][TypePrefix]C[The channel number]
四部分分别指定:元素的大小,是有符号还是无符号,数据类型以及通道数。
cv::Mat img(20, 20, CV_8UC3, cv::Scalar(0,0,255));
上述代码创建了一个20行20列的矩阵,矩阵元素使用8位无符号char类型保存,具有3通道,每个像素的初始值是(0,0,255)即红色,Scalar是short型的vector,提供矩阵的初始化。
2、Create方法
该方法不能为矩阵设置初始值,只是在改变尺寸时为矩阵数据重新分配内存。创建一个4行4列有2个通道的矩阵:
img.create(4, 4, CV_8UC2);
3、几种特殊矩阵初始化方式的说明
cv::Mat e = cv::Mat::eye(4,4,CV_64F);
cv::Mat o = cv::Mat::ones(2,2,CV_32F);
cv::Mat z = cv::Mat::zeros(3,3,CV_8UC1);
Mat e是4行4列的对角矩阵
Mat z是2行2列的单位矩阵
Mat o是3行3列的零矩阵
4、小矩阵的初始化
Mat m =(Mat_
(3,3)<<-3,-2,-1,0,1,2,3,4,5);
Mat的输入输出
使用imread函数,向Mat对象中写入一个图像:
1 |
|
filename指定要读取图像的位置flags指定图像的颜色空间
flags > 0 三通道的彩色图像
flags = 0 灰度图像
flags < 0 不作改变也可以有以下的枚举值
CV_LOAD_IMAGE_ANYDEPTH、
CV_LOAD_IMAGE_COLOR、
CV_LOAD_IMAGE_GRAYSCALE
使用imwrite函数,将Mat对象保存到指定的文件中。imwrite的函数原型如下:
1 |
|
filename,指定的文件
img 要保存的Mat对象
params 用来指定图像的保存编码方式。
使用filename的扩展名来指定图像的保存格式(.jpg .png .bmp),对于不同的图像保存类型,params是不同的值
- JPEG,params用来指定图像的质量(0到100),CV_IMWRITE_JPEG_QUALITY
默认的是95 .- PNG,params用来指定图像的压缩级别(0到9),压缩级别越高图像占用的空间越小,保存图像所用的时间越久。默认值是3. CV_IMWRITE_PNG_COMPRESSION
- PPM,PGM,PBM,params是一个标记(0或者1),CV_IMWRITE_PXM_BINARY
默认的是1。imwrite只能保存8位(或者是16位无符号(CV_16UC)的PNG,JPEG200或者TIFF图像)单通道或者三通道的图像,如果要保存的不是这样的图片,可以使用convertTo或者cvtColor来进行转变。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!