c++ opencv

devtools/2024/12/22 20:05:32/

文章目录

  • 错误
    • 1. C2039 "channels": 不是 "cv::DataType<_Tp>" 的成员
    • 2. 注意cv::mat的类型
    • 3. cv::mat求inv
    • 4. vector subscript out of range
    • 5. 使用determinant求行列式注意点
  • 其他
    • 1.Vec3b的赋值与访问
    • 2. cv::mean
    • 3. 将cv::mat三通道改为单通道且保持形状不变

错误

1. C2039 “channels”: 不是 “cv::DataType<_Tp>” 的成员

在对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;

2. 注意cv::mat的类型

当你发现使用at出错时,应该先看是不是类型错误
时刻要注意类型应保持一致,比如cv::mat dataVec3f类型的,你用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);
}

3. cv::mat求inv

求矩阵的逆时矩阵必须为floatdouble类型的

Mat m = (Mat_<double>(3, 3) << 1, 0, 0, 0, 1, 0, 0, 0, 1);
cout << m.inv() << endl;

4. vector subscript out of range

在求矩阵的逆的时候碰到了vector subscript out of range错误,后面发现是因为求逆后把逆放入vector容器中,而那个vector未初始化就直接使用下标,应该先初始化。

CovInv[i] = Cov[i].inv();

5. 使用determinant求行列式注意点

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))即可得知错误原因。



其他

1.Vec3b的赋值与访问

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指定打印类型打印。

2. cv::mean

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]

3. 将cv::mat三通道改为单通道且保持形状不变

若直接用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(xix)(yiy),而协方差的公式是 ∑ 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} n1i=1n(xix)(yiy),相差了一个分母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]

http://www.ppmy.cn/devtools/19323.html

相关文章

第二章:计算机系统基础知识之计算机网络

计算机网络 计算机网络是利用通信线路将地理上分散的、具有独立功能的计算机系统和通信设备按不同的形式连接起来&#xff0c;并依靠网络软件及通信协议实现资源共享和信息传递的系统。   计算机网络技术主要涵盖通信技术、网络技术、组网技术和网络工程等四个方面。 计算机…

安装 wsl-ubuntu 24.04

安装 wsl-ubuntu 24.04 1. 安装 Ubuntu-24.042. (可选)配置阿里云软件源3. 系统更新 1. 安装 Ubuntu-24.04 安装 Ubuntu-24.04&#xff0c;默认会安装在 C 盘&#xff0c; wsl --install -d Ubuntu-24.04导出 Ubuntu-24.04&#xff0c; wsl --export Ubuntu-24.04 D:\tmp\Ub…

Mac如何更换终端默认的python版本

一、Mac中如何更换终端默认的python版本 1、打开终端输入下列代码&#xff0c;打开配置文件 open ~/.bash_profile 2.在打开的配置文件中输入&#xff08;以下代码3.12替换为所下载的版本即可&#xff09; #下面是修改python版本的命令就是环境变量 export PYTHON_HOME/Lib…

深拷贝与浅拷贝-附深拷贝工具类

深拷贝与浅拷贝的区别 浅拷贝只是拷贝了源对象的地址&#xff0c;所以当源对象发生改变时&#xff0c;拷贝的对象的值也会对应发生改变。 深拷贝则是拷贝了源对象的所有值&#xff0c;而不是地址&#xff0c;所以深拷贝对象中的值不会随着源对象中的值的改变而改变。 浅拷贝只是…

【java毕业设计】 基于Spring Boot+mysql的高校心理教育辅导系统设计与实现(程序源码)-高校心理教育辅导系统

基于Spring Bootmysql的高校心理教育辅导系统设计与实现&#xff08;程序源码毕业论文&#xff09; 大家好&#xff0c;今天给大家介绍基于Spring Bootmysql的高校心理教育辅导系统设计与实现&#xff0c;本论文只截取部分文章重点&#xff0c;文章末尾附有本毕业设计完整源码及…

pnpm 安装后 node_modules 是什么结构?为什么 webpack 不识别 pnpm 安装的包?

本篇研究&#xff1a;使用 pnpm 安装依赖时&#xff0c;node_modules 下是什么结构 回顾 npm3 之前&#xff1a;依赖树 缺点&#xff1a; frequently packages were creating too deep dependency trees, which caused long directory paths issue on Windowspackages were c…

【机器学习】农田智能监控系统的实践探索

机器学习赋能现代农业&#xff1a;农田智能监控系统的实践探索 一、机器学习在现代农业中的重要作用二、机器学习在农田智能监控系统中的应用三、农田智能监控系统的实践意义 在科技飞速发展的今天&#xff0c;机器学习技术正以其强大的数据处理和模式识别能力&#xff0c;逐步…

如何有效的将丢失的mfc140u.dll修复,几种mfc140u.dll丢失的解决方法

当你在运行某个程序或应用程序时&#xff0c;突然遭遇到mfc140u.dll丢失的错误提示&#xff0c;这可能会对你的电脑运行产生一些不利影响。但是&#xff0c;不要担心&#xff0c;以下是一套详细的mfc140u.dll丢失的解决方法。 mfc140u.dll缺失问题的详细解决步骤 步骤1&#x…