opencv-矩阵运算
加法
cv::Mat I1(4, 3, CV_8UC3, cv::Scalar(10, 20, 30)); cv::Mat I2(4, 3, CV_8UC3, cv::Scalar(1, 2, 3)); cv::Mat I = I1 + I2; //加法 cv::Mat II; cv::add(I1, I2, II); //加法 std::cerr << I1 << std::endl; std::cerr << I2 << std::endl; std::cerr << I << std::endl; std::cerr << II << std::endl;
减法
cv::Mat I1(4, 3, CV_8UC3, cv::Scalar(10, 20, 30)); cv::Mat I2(4, 3, CV_8UC3, cv::Scalar(1, 28, 3)); cv::Mat I = I1 - I2; //减法;若I<0,则I=0 cv::Mat II; cv::subtract(I1, I2, II); //减法;若I<0,则I=0 cv::Mat dst; cv::absdiff(I1, I2, dst);//若dst<0,则dst=|dst| std::cerr << I1 << std::endl; std::cerr << I2 << std::endl; std::cerr << I << std::endl; std::cerr << II << std::endl; std::cerr << dst << std::endl;
乘法
A*B是以数学运算中矩阵相乘的方式实现的,即Mat矩阵A和B被当做纯粹的矩阵做乘法运算,这就要求A的列数等 于B的行数时,才能定义两个矩阵相乘。如A是m×n矩阵,B是n×p矩阵,它们的乘积AB是一个m×p矩阵
如上图所示,C=AB。C中第i行第j列所在元素C(i,j)等于A中第i行所有元素跟B中第j列所有元素一一对应的乘积之和
cv::Mat A = cv::Mat::ones(2, 3, CV_32FC1); cv::Mat B = cv::Mat::ones(3, 2, CV_32FC1); cv::Mat AB; A.at<float>(0, 0) = 1; A.at<float>(0, 1) = 2; A.at<float>(0, 2) = 3; A.at<float>(1, 0) = 4; A.at<float>(1, 1) = 5; A.at<float>(1, 2) = 6; B.at<float>(0, 0) = 1; B.at<float>(0, 1) = 2; B.at<float>(1, 0) = 3; B.at<float>(1, 1) = 4; B.at<float>(2, 0) = 5; B.at<float>(2, 1) = 6; AB = A * B; //乘法 std::cerr << A << std::endl; std::cerr << B << std::endl; std::cerr << AB << std::endl;
注意:两个Mat矩阵的数据类型(type)只能是 CV_32F、 CV_64FC1、 CV_32FC2、 CV_64FC2 这4种类型中的一种。若选用其他类型,比如CV_8UC1,编译器会报错
A.mul(B) 对应位乘积
mul会计算两个Mat矩阵对应位的乘积,所以要求参与运算的矩阵A的行列和B的行列数一致。计算结果是跟A或B行列数一致的一个Mat矩阵
以简单的情况为例,对于2*2大小的Mat矩阵A和B:
对A和B执行mul运算:
说明:
1. mul操作不对参与运算的两个矩阵A、B有数据类型上的要求,但要求A,B类型一致,不然报错;
2. Mat AB=A.mul(B),若声明AB时没有定义AB的数据类型,则默认AB的数据类型跟A和B保存一致;
3. 若AB精度不够,可能产生溢出,那就取最大值;
cv::Mat A = cv::Mat::ones(2, 3, CV_8UC1); cv::Mat B = cv::Mat::ones(2, 3, CV_8UC1); A.at<uchar>(0, 0) = 60; A.at<uchar>(0, 1) = 2; A.at<uchar>(0, 2) = 3; A.at<uchar>(1, 0) = 4; A.at<uchar>(1, 1) = 5; A.at<uchar>(1, 2) = 6; B.at<uchar>(0, 0) = 60; B.at<uchar>(0, 1) = 2; B.at<uchar>(0, 2) = 3; B.at<uchar>(1, 0) = 4; B.at<uchar>(1, 1) = 5; B.at<uchar>(1, 2) = 6; cv::Mat AB = A.mul(B); std::cerr << A << std::endl; std::cerr << B << std::endl; std::cerr << AB << std::endl;
除法: 对应位相除
cv::Mat src(5, 4, CV_8UC3, cv::Scalar(10,33,100)); cv::Mat src1(5, 4, CV_8UC3, cv::Scalar(2,3,5)); cv::Mat dst; dst = src / src1; //对应位相除 std::cerr << dst << std::endl;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
2020-10-31 qt--mask蒙版