转载:http://blog.csdn.net/iracer/article/details/51296631

OpenCV的基本矩阵操作与示例

OpenCV中的矩阵操作非常重要,本文总结了矩阵的创建、初始化以及基本矩阵操作,给出了示例代码,主要内容包括:

  • 创建与初始化
  • 矩阵加减法
  • 矩阵乘法
  • 矩阵转置
  • 矩阵求逆
  • 矩阵非零元素个数
  • 矩阵均值与标准差
  • 矩阵全局极值及位置
  • 其他矩阵运算函数列表

1. 创建与初始化矩阵


1.1 数据类型

建立矩阵必须要指定矩阵存储的数据类型,图像处理中常用的几种数据类型如下:

[cpp] view plain copy print ?
  1. CV_8UC1// 8位无符号单通道
  2. CV_8UC3// 8位无符号3通道
  3. CV_8UC4
  4. CV_32FC1// 32位浮点型单通道
  5. CV_32FC3// 32位浮点型3通道
  6. CV_32FC4
CV_8UC1// 8位无符号单通道
CV_8UC3// 8位无符号3通道
CV_8UC4
CV_32FC1// 32位浮点型单通道
CV_32FC3// 32位浮点型3通道
CV_32FC4

包括数据位深度8位、32位,数据类型U:uchar、F:float型以及通道数C1:单通道、C3:三通道、C4:四通道。

1.2 基本方法

我们可以通过载入图像来创建Mat类型矩阵,当然也可以直接手动创建矩阵,基本方法是指定矩阵尺寸和数据类型:

[cpp] view plain copy print ?
  1. // 基本方法
  2. cv::Mat a(cv::Size(5,5),CV_8UC1); // 单通道
  3. cv::Mat b = cv::Mat(cv::Size(5,5),CV_8UC3); //3通道每个矩阵元素包含3个uchar值
  4. cout<<”a  = ”<<endl<<a<<endl<<endl;
  5. cout<<”b  = ”<<endl<<b<<endl<<endl;
  6. system(”pause”);
// 基本方法cv::Mat a(cv::Size(5,5),CV_8UC1); // 单通道cv::Mat b = cv::Mat(cv::Size(5,5),CV_8UC3); //3通道每个矩阵元素包含3个uchar值cout<<"a  = "<<endl<<a<<endl<<endl;cout<<"b  = "<<endl<<b<<endl<<endl;system("pause");

运行结果:

3通道矩阵中,一个矩阵元素包含3个变量。

1.3 初始化方法

上述方法不初始化矩阵数据,因此将出现随机值。如果想避免这种情况,可使用Mat类的几种初始化创建矩阵的方法:

[cpp] view plain copy print ?
  1. // 初始化方法
  2. cv::Mat mz = cv::Mat::zeros(cv::Size(5,5),CV_8UC1); // 全零矩阵
  3. cv::Mat mo = cv::Mat::ones(cv::Size(5,5),CV_8UC1);  // 全1矩阵
  4. cv::Mat me = cv::Mat::eye(cv::Size(5,5),CV_32FC1);  // 对角线为1的对角矩阵
  5. cout<<”mz = ”<<endl<<mz<<endl<<endl;
  6. cout<<”mo = ”<<endl<<mo<<endl<<endl;
  7. cout<<”me = ”<<endl<<me<<endl<<endl;
// 初始化方法cv::Mat mz = cv::Mat::zeros(cv::Size(5,5),CV_8UC1); // 全零矩阵cv::Mat mo = cv::Mat::ones(cv::Size(5,5),CV_8UC1);  // 全1矩阵cv::Mat me = cv::Mat::eye(cv::Size(5,5),CV_32FC1);  // 对角线为1的对角矩阵cout<<"mz = "<<endl<<mz<<endl<<endl;cout<<"mo = "<<endl<<mo<<endl<<endl;cout<<"me = "<<endl<<me<<endl<<endl;

运行结果:

2. 矩阵运算


2.1 基本概念

OpenCV的Mat类允许所有的矩阵运算。

2.2 矩阵加减法

我们可以使用”+”和”-“符号进行矩阵加减运算。

[cpp] view plain copy print ?
  1. cv::Mat a= Mat::eye(Size(3,2), CV_32F);
  2. cv::Mat b= Mat::ones(Size(3,2), CV_32F);
  3. cv::Mat c= a+b;
  4. cv::Mat d= a-b;
cv::Mat a= Mat::eye(Size(3,2), CV_32F);
cv::Mat b= Mat::ones(Size(3,2), CV_32F);
cv::Mat c= a+b;
cv::Mat d= a-b;

2.3 矩阵乘法

使用”*”号计算矩阵与标量相乘,矩阵与矩阵相乘(必须满足矩阵相乘的行列数对应规则)

[cpp] view plain copy print ?
  1. Mat m1= Mat::eye(2,3, CV_32F); //使用cv命名空间可省略cv::前缀,下同
  2. Mat m2= Mat::ones(3,2, CV_32F);
  3. cout<<”m1  = ”<<endl<<m1<<endl<<endl;
  4. cout<<”m2  = ”<<endl<<m2<<endl<<endl;
  5. // Scalar by matrix
  6. cout << ”\nm1.*2 = \n” << m1*2 << endl;
  7. // matrix per element multiplication
  8. cout << ”\n(m1+2).*(m1+3) = \n” << (m1+1).mul(m1+3) << endl;
  9. // Matrix multiplication
  10. cout << ”\nm1*m2 = \n” << m1*m2 << endl;
  Mat m1= Mat::eye(2,3, CV_32F); //使用cv命名空间可省略cv::前缀,下同Mat m2= Mat::ones(3,2, CV_32F);cout<<"m1  = "<<endl<<m1<<endl<<endl;cout<<"m2  = "<<endl<<m2<<endl<<endl;// Scalar by matrixcout << "\nm1.*2 = \n" << m1*2 << endl;// matrix per element multiplicationcout << "\n(m1+2).*(m1+3) = \n" << (m1+1).mul(m1+3) << endl;// Matrix multiplicationcout << "\nm1*m2 = \n" << m1*m2 << endl;

2.4 矩阵转置

矩阵转置是将矩阵的行与列顺序对调(第i行转变为第i列)形成一个新的矩阵。OpenCV通过Mat类的t()函数实现。

[cpp] view plain copy print ?
  1. // 转置
  2. Mat m1= Mat::eye(2,3, CV_32F);
  3. Mat m1t = m1.t();
  4. cout<<”m1  = ”<<endl<<m1<<endl<<endl;
  5. cout<<”m1t  = ”<<endl<<m1t<<endl<<endl;
  6. system(”pause”);
// 转置Mat m1= Mat::eye(2,3, CV_32F);  Mat m1t = m1.t();cout<<"m1  = "<<endl<<m1<<endl<<endl;cout<<"m1t  = "<<endl<<m1t<<endl<<endl;system("pause");

运行结果:

2.5 求逆矩阵

逆矩阵在某些算法中经常出现,在OpenCV中通过Mat类的inv()方法实现

[cpp] view plain copy print ?
  1. // 求逆
  2. Mat meinv = me.inv();
  3. cout<<”me  = ”<<endl<<me<<endl<<endl;
  4. cout<<”meinv = ”<<endl<<meinv<<endl<<endl;
  5. system(”pause”);
// 求逆Mat meinv = me.inv();cout<<"me  = "<<endl<<me<<endl<<endl;cout<<"meinv = "<<endl<<meinv<<endl<<endl;system("pause");
运行结果:

单位矩阵的逆就是其本身。

2.6 计算矩阵非零元素个数

计算物体的像素或面积常需要用到计算矩阵中的非零元素个数,OpenCV中使用countNonZero()函数实现。

[cpp] view plain copy print ?
  1. // 非零元素个数
  2. int nonZerosNum = countNonZero(me); // me为输入矩阵或图像
  3. cout<<”me  = ”<<endl<<me<<endl;
  4. cout<<”me中非零元素个数 = ”<<nonZerosNum<<endl<<endl;
  5. system(”pause”);
// 非零元素个数int nonZerosNum = countNonZero(me); // me为输入矩阵或图像cout<<"me  = "<<endl<<me<<endl;cout<<"me中非零元素个数 = "<<nonZerosNum<<endl<<endl;system("pause");
运行结果:

2.7 均值和标准差

OpenCV提供了矩阵均值和标准差计算功能,可以使用meanStdDev(src,mean,stddev)函数实现。

参数

  • src – 输入矩阵或图像
  • mean – 均值,OutputArray
  • stddev – 标准差,OutputArray
[cpp] view plain copy print ?
  1. // 均值方差
  2. Mat mean;
  3. Mat stddev;
  4. meanStdDev(me, mean, stddev); //me为前文定义的5×5对角阵
  5. cout<<”mean = ”<<mean<<endl;
  6. cout<<”stddev = ”<<stddev<<endl;
  7. system(”pause”);
// 均值方差Mat mean;Mat stddev;meanStdDev(me, mean, stddev); //me为前文定义的5×5对角阵cout<<"mean = "<<mean<<endl;cout<<"stddev = "<<stddev<<endl;system("pause");

运行结果:

需要说明的是,如果src是多通道图像或多维矩阵,则函数分别计算不同通道的均值与标准差,因此返回值mean和stddev为对应维度的向量。

[cpp] view plain copy print ?
  1. Mat mean3;
  2. Mat stddev3;
  3. Mat m3(cv::Size(5,5),CV_8UC3,Scalar(255,200,100));
  4. cout<<”m3  = ”<<endl<<m3<<endl<<endl;
  5. meanStdDev(m3, mean3, stddev3);
  6. cout<<”mean3 = ”<<mean3<<endl;
  7. cout<<”stddev3 = ”<<stddev3<<endl;
  8. system(”pause”);
  Mat mean3;Mat stddev3;Mat m3(cv::Size(5,5),CV_8UC3,Scalar(255,200,100));cout<<"m3  = "<<endl<<m3<<endl<<endl;meanStdDev(m3, mean3, stddev3);cout<<"mean3 = "<<mean3<<endl;cout<<"stddev3 = "<<stddev3<<endl;system("pause");

多通道矩阵运算结果:

2.8 求最大最小值

求输入矩阵的全局最大最小值及其位置,可使用函数:

[cpp] view plain copy print ?
  1. void minMaxLoc(InputArray src, CV_OUT double* minVal,
  2. CV_OUT double* maxVal=0, CV_OUT Point* minLoc=0,
  3. CV_OUT Point* maxLoc=0, InputArray mask=noArray());
void minMaxLoc(InputArray src, CV_OUT double* minVal,CV_OUT double* maxVal=0, CV_OUT Point* minLoc=0,CV_OUT Point* maxLoc=0, InputArray mask=noArray());

参数:

  • src – 输入单通道矩阵(图像).
  • minVal – 指向最小值的指针, 如果未指定则使用NULL
  • maxVal – 指向最大值的指针, 如果未指定则使用NULL
  • minLoc – 指向最小值位置(2维情况)的指针, 如果未指定则使用NULL
  • maxLoc – 指向最大值位置(2维情况)的指针, 如果未指定则使用NULL
  • mask – 可选的蒙版,用于选择待处理子区域
[cpp] view plain copy print ?
  1. // 求极值 最大、最小值及其位置
  2. Mat img = imread(”Lena.jpg”,0);
  3. imshow(”original image”,img);
  4. double minVal=0,maxVal=0;
  5. cv::Point minPt, maxPt;
  6. minMaxLoc(img,&minVal,&maxVal,&minPt,&maxPt);
  7. cout<<”min value  = ”<<minVal<<endl;
  8. cout<<”max value  = ”<<maxVal<<endl;
  9. cout<<”minPt = (“<<minPt.x<<“,”<<minPt.y<<“)”<<endl;
  10. cout<<”maxPt = (“<<maxPt.x<<“,”<<maxPt.y<<“)”<<endl;
  11. cout<<endl;
  12. cv::Rect rectMin(minPt.x-10,minPt.y-10,20,20);
  13. cv::Rect rectMax(maxPt.x-10,maxPt.y-10,20,20);
  14. cv::rectangle(img,rectMin,cv::Scalar(200),2);
  15. cv::rectangle(img,rectMax,cv::Scalar(255),2);
  16. imshow(”image with min max location”,img);
  17. cv::waitKey();
// 求极值 最大、最小值及其位置Mat img = imread("Lena.jpg",0);imshow("original image",img);double minVal=0,maxVal=0;cv::Point minPt, maxPt;minMaxLoc(img,&minVal,&maxVal,&minPt,&maxPt);cout<<"min value  = "<<minVal<<endl;cout<<"max value  = "<<maxVal<<endl;cout<<"minPt = ("<<minPt.x<<","<<minPt.y<<")"<<endl;cout<<"maxPt = ("<<maxPt.x<<","<<maxPt.y<<")"<<endl;cout<<endl;cv::Rect rectMin(minPt.x-10,minPt.y-10,20,20);cv::Rect rectMax(maxPt.x-10,maxPt.y-10,20,20);cv::rectangle(img,rectMin,cv::Scalar(200),2);cv::rectangle(img,rectMax,cv::Scalar(255),2);imshow("image with min max location",img);cv::waitKey();

运行结果:

输入图像及其最大最小值位置

3. 其他矩阵运算

其他矩阵运算函数见下表:

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|src(I)| (if src != 0)

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

行列式 |A|, det(A)

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 | DCT_INVERSE)

dft, idft

正、逆离散傅立叶变换, idft同dft(src, dst, flags | DTF_INVERSE)

LUT

查表变换

getOptimalDFTSize

返回一个优化过的DFT大小

mulSpecturms

两个傅立叶频谱间逐元素的乘法

上表引自:http://blog.sina.com.cn/s/blog_7908e1290101i97z.html

转载请注明出处(本文更新链接):http://blog.csdn.net/iracer/article/details/51296631

OpenCV的基本矩阵操作与示例相关推荐

  1. OpenCV—基本矩阵操作与示例

    https://blog.csdn.net/iracer/article/details/51296631

  2. OpenCV —数据持久化: FileStorage类的数据存取操作与示例

    OpenCV -FileStorage类的数据读写操作与示例 OpenCV的许多应用都需要使用数据的存储于读取,例如经过3D校准后的相机,需要存储校准结果矩阵,以方便下次调用该数据:基于机器学习的应用 ...

  3. OpenCV通过形态学操作提取水平线和垂直线

    OpenCV通过形态学操作提取水平线和垂直线 通过形态学操作提取水平线和垂直线 目标 理论 形态学运算 结构元素 代码 说明/结果 载入图片 灰阶 灰度到二进制图像 输出图像 结构要素 优化边缘/结果 ...

  4. OpenCV中视频操作及人脸识别案例

    目录 OpenCV中视频操作及人脸识别案例 视频操作 视频读写 从文件中读取视频并播放 保存视频 小结 视频追踪 meanshift Camshift 算法总结 小结 案例:人脸案例 人脸识别基础 实 ...

  5. opencv —— morphology形态学操作函数讲解(python)

    opencv -- morphology形态学操作函数讲解 目录 opencv -- morphology形态学操作函数讲解 形态学滤波:morphologyEx 函数 开运算:先腐蚀后膨胀. 闭运算 ...

  6. [opencv]常用阵列操作函数总结

    /*=========================================================================*/ // 阵列操作 /*============ ...

  7. 基于Ubuntu安装opencv以及相关操作

    目录 一.基于Ubuntu下安装opencv 二.相关操作之图片 三.相关操作之视屏 四.总结 五.参考资料 一.基于Ubuntu下安装opencv 1.opencv依赖环境的安装 1.1 安装cma ...

  8. OpenCV 基本阈值操作Thresholding Operations

    OpenCV 基本阈值操作Thresholding Operations 基本阈值操作Thresholding Operations 目标 门槛? 阈值类型 阈值二进制 阈值二进制,反转 截短 阈值为 ...

  9. 使用Python,OpenCV进行形态学操作

    使用Python,OpenCV进行形态学操作) 1. 效果图 2. 原理 3. 源码 3.1 [制作logo源码](https://blog.csdn.net/qq_40985985/article/ ...

最新文章

  1. Visual Studio中的快捷键
  2. 转码与重定向的区别之于SpringMVC
  3. Django多表查询练习题
  4. mysql职业要求_运维职业要求
  5. 搭建nginx服务器
  6. Google浏览器清除缓存快捷键
  7. 如何修复图片清晰度呢?这三款软件不要错过
  8. 超详细|开关电源电路图及原理讲解;以UC3842为中心的开关电源介绍,重点是以光耦和电流互感器为关键的反馈电路,以及在此基础上的过压欠压短路等各种保护稳压电路措施
  9. Citrix PVS架构和工作原理
  10. 推荐一个C# 制作免安装程序的工具和方法,超级好用 fody
  11. 【UPCOJ】21185问题 H: 买二送一
  12. Sqoop——MySQL_to_HDFS的脚本详解
  13. 单品秒杀(百万次秒杀、亿万次秒杀)
  14. 阿里P8级架构师怎么处理电商业务中的数值计算的精度/舍入/溢出问题?
  15. java毕业设计读书网络社区设计Mybatis+系统+数据库+调试部署
  16. 十七.用户注册 ---- 图形验证码 2021-04-03
  17. 软件测试规范如写诗一样有多重要?
  18. linux下运行的游戏(持续更新中)
  19. fastboot出现错误:no permissions fastboot
  20. 画思维导图哪个软件好用

热门文章

  1. VUE常用指令v-xxx
  2. 2019年最新出搜索引擎蜘蛛网页爬虫大全
  3. 阿里云普通硬盘与NAS盘的读写速度测试
  4. Jmeter之常用断言总结篇
  5. vscode运行python没有结果输出
  6. 哔咔漫画怎样切换横屏?
  7. CSS样式怎样修改滚动条的样式
  8. 淘宝宝贝图片批量下载教程
  9. javaEye上对于南京软件公司的讨论
  10. linux将一段时间内文件压缩,在 Linux 上压缩文件的 5 种方法