赞
踩
在对cv::mat
类型赋值时,使用了uint
,改为uchar
即可
Mat mask(4, 1, CV_8UC1, Scalar(0));
mask.at<uint>(0,0) = 1;
改为
Mat mask(4, 1, CV_8UC1, Scalar(0));
mask.at<uchar>(0,0) = 1;
当你发现使用at
出错时,应该先看是不是类型错误
时刻要注意类型应保持一致,比如cv::mat data
是Vec3f
类型的,你用at
访问时却写成了data.at<Vec3b>
,此时就会报错:
OpenCV(4.5.5) Error: Assertion failed (((0x28442211 >> ((traits::Depth<_Tp>::value) & ((1 << 3) - 1))*4) & 15) == elemSize1()) in cv::Mat::at, file E:\ProfessionApp\opencv-4.5.5\build\include\opencv2\core\mat.inl.hpp, line 900
如下示例,其中data
的类型为CV_32F
,故访问它时就不能用Vec3b
:
for (int i = 0; i < data.rows; ++i) {
Vec3b& tmp = data.at<Vec3b>(i, 0);
}
应改为:
for (int i = 0; i < data.rows; ++i) {
Vec3f& tmp = data.at<Vec3f>(i, 0);
}
求矩阵的逆时矩阵必须为float
或double
类型的
Mat m = (Mat_<double>(3, 3) << 1, 0, 0, 0, 1, 0, 0, 0, 1);
cout << m.inv() << endl;
在求矩阵的逆的时候碰到了vector subscript out of range
错误,后面发现是因为求逆后把逆放入vector
容器中,而那个vector
未初始化就直接使用下标,应该先初始化。
CovInv[i] = Cov[i].inv();
cv::mat需要为CV_32F或者CV_64类型,可以通过convertTo
进行修改;并且需要行数等于列数,其中行数为3列数为1三通道是不行的,若要求其行列式,可以利用reshape
将其改为单通道,这样列数就变为了3
M.convertTo(M, CV_32F);
M = M.reshape(1, 0);
另外可以从报错可以看出来错误的原因:
OpenCV(4.5.5) Error: Assertion failed (mat.rows == mat.cols && (type == CV_32F || type == CV_64F)) in cv::determinant, file C:\build\master_winpack-build-win64-vc15\opencv\modules\core\src\lapack.cpp, line 776
通过(mat.rows == mat.cols && (type == CV_32F || type == CV_64F))
即可得知错误原因。
Vec3b v1;
v1[0] = 97;
v1[1] = 243;
v1[2] = 2;
cout << "v1:"<<v1 << endl;
cout << v1[0] << endl;
输出:
v1:[97, 243, 2]
a
访问单个元素(如v1[0])输出的是ascii码表中对应的值,所以有时候会打印不出来内容,此时可以用printf
指定打印类型打印。
Scalar mean(InputArray src, InputArray mask=noArray())
参数
参数 src 输入数组,具有1到4个通道,结果保存在Scalar_ 。
参数 mask 可选参数,操作掩摸,用于标记求取哪些区域的均值和标准差。
当有mask参数时,计算mask参数值大于0的对应的rgb三通道的均值
Mat mask(4, 1, CV_8UC1, Scalar(1)); mask.at<uchar>(2,0) = 0; Scalar m1 = mean(M3, mask); cout << M3 << endl; cout << mask << endl; cout << m1 << endl; // 只计算了第0、1、3个rgb的均值 输出: [245, 207, 173; 244, 202, 167; 254, 200, 165; 246, 206, 171] [ 1; 1; 0; 1] [245, 205, 170.333, 0]
当mask值都大于0但各不相同的时候,和没有mask得到的结果一致,计算的是所有数据的rgb的均值
Mat mask(4, 1, CV_8UC1, Scalar(1)); mask.at<uchar>(2,0) = 2; Scalar m1 = mean(M3, mask); cout << M3 << endl; cout << mask << endl; cout << m1 << endl; cout << mean(M3) << endl; // 只计算了第0、1、3个rgb的均值 输出: [245, 207, 173; 244, 202, 167; 254, 200, 165; 246, 206, 171] [ 1; 1; 2; 1] [247.25, 203.75, 169, 0] [247.25, 203.75, 169, 0]
若直接用calcCovarMatrix
计算三通道cv::mat,则会报以下错:
OpenCV(4.5.5) Error: Assertion failed (src.channels() == 1) in cv::mulTransposed, file C:\build\master_winpack-build-win64-vc15\opencv\modules\core\src\matmul.dispatch.cpp, line 886
报错上写了failed (src.channels() == 1)
,说明通道数应为1,此时直接用cv::reshape
改其通道数即可,另外需要注意的是,cv::cvtColor(image, image, cv::COLOR_BGR2RGB)
也可以将三通道转换为单通道,但是这个的转换是指将三个通道取平均值变为单通道的值,比如像素点(0,0)的rgb值分别为240,236,242,则转换后的单通道值为239.33。
另外需要注意的是,得到的结果不是协方差,而是
∑
i
=
1
n
(
x
i
−
x
‾
)
(
y
i
−
y
‾
)
\sum_{i=1}^{n}(x_i-\overline x)(y_i-\overline y)
∑i=1n(xi−x)(yi−y),而协方差的公式是
∑
i
=
1
n
(
x
i
−
x
‾
)
(
y
i
−
y
‾
)
n
−
1
\frac{\sum_{i=1}^{n}(x_i-\overline x)(y_i-\overline y)}{n-1}
n−1∑i=1n(xi−x)(yi−y),相差了一个分母n-1
Mat Mat::reshape(int cn,int rows=0) const
cn:表示通道数(channels),如果设置为0,则表示通道不变;
如果设置为其他数字,表示要设置的通道数
rows:表示矩阵行数,如果设置为0,则表示保持原有行数不变,如果设置为其他数字,表示要设置的行数
Mat img = cv::imread("./img.jpg"); Mat M3; M3.push_back(img.at<Vec3b>(0, 0)); M3.push_back(img.at<Vec3b>(0, 1)); M3.push_back(img.at<Vec3b>(0, 2)); M3.push_back(img.at<Vec3b>(1, 0)); cout << M3 << endl; Mat samples; M3.convertTo(samples, CV_32FC1); cout << "samples:" << endl << samples << endl; cout << "samples channels:" << samples.channels() << endl; // 第一个参数:通道数,第二个参数:函数,0表示不变 samples = samples.reshape(1, 0); cout << "samples channels:" << samples.channels() << endl; Mat cov, mu; calcCovarMatrix(samples, cov, mu, CV_COVAR_NORMAL | CV_COVAR_ROWS); cout << cov << endl; cout << mu << endl;
输出:
[245, 207, 173;
244, 202, 167;
254, 200, 165;
246, 206, 171]
samples:
[245, 207, 173;
244, 202, 167;
254, 200, 165;
246, 206, 171]
samples channels:3
samples channels:1
[62.75, -29.75, -32;
-29.75, 32.75, 36;
-32, 36, 40]
[247.25, 203.75, 169]
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。