OpenCV的基本矩阵操作与示例

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

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

1. 创建与初始化矩阵


1.1 数据类型

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

  1. CV_8UC1// 8位无符号单通道
  2. CV_8UC3// 8位无符号3通道
  3. CV_8UC4
  4. CV_32FC1// 32位浮点型单通道
  5. CV_32FC3// 32位浮点型3通道
  6. CV_32FC4

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

1.2 基本方法

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

  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");

运行结果:

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

1.3 初始化方法

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

  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;

运行结果:

2. 矩阵运算


2.1 基本概念

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

2.2 矩阵加减法

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

  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;

2.3 矩阵乘法

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

  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;

2.4 矩阵转置

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

  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");

运行结果:

2.5 求逆矩阵

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

  1. // 求逆
  2. Mat meinv = me.inv();
  3. cout<<"me = "<<endl<<me<<endl<<endl;
  4. cout<<"meinv = "<<endl<<meinv<<endl<<endl;
  5. system("pause");
运行结果:

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

2.6 计算矩阵非零元素个数

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

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

2.7 均值和标准差

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

参数

  • src – 输入矩阵或图像
  • mean – 均值,OutputArray
  • stddev – 标准差,OutputArray
  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");

运行结果:

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

  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");

多通道矩阵运算结果:

2.8 求最大最小值

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

  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());

参数:

  • src – 输入单通道矩阵(图像).
  • minVal – 指向最小值的指针, 如果未指定则使用NULL
  • maxVal – 指向最大值的指针, 如果未指定则使用NULL
  • minLoc – 指向最小值位置(2维情况)的指针, 如果未指定则使用NULL
  • maxLoc – 指向最大值位置(2维情况)的指针, 如果未指定则使用NULL
  • mask – 可选的蒙版,用于选择待处理子区域
  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();

运行结果:

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

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

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

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

  1. OpenCv学习笔记(二)--Mat矩阵(图像容器)的创建及CV_8UC1,CV_8UC2等参数详解

    (一)Mat矩阵(图像容器)创建时CV_8UC1,CV_8UC2等参数详解 1--Mat不但是一个非常有用的图像容器类,同时也是一个通用的矩阵类 2--创建一个Mat对象的方法很多,我们现在先看一下M ...

  2. OpenCV的各种矩阵基本运算、基本操作及示例代码(加、减、乘、点乘、点除、乘方、开方、累加、转置、比较等)

    OpenCV的各种矩阵基本运算.基本操作及示例代码(加.减.乘.点乘.点除.乘方.开方.累加.转置.比较等) OpenCV的各种矩阵基本运算.基本操作及示例代码 目录 01-两个矩阵相加.矩阵和标量相 ...

  3. OpenCV Mat矩阵(图像Mat)初始化及访问方法

    一.Mat初始化 1.使用Mat构造函数 //方法一: Mat M( 2, 2, CV_8UC3, Scalar(0,255,0) );//其实是2*6的矩阵,因为每个元素有3个通道. Mat M1( ...

  4. 【OpenCv】c++ 入门认识 Mat 类,单通道 Mat 的基本操作

    文章目录 前言 Mat 类 Mat 类的构造方式 Mat 基本操作 单通道 Mat 的基本操作 使用成员变量 rows 和 cols 获取矩阵的行数和列数 使用成员函数 size() 来获取矩阵的尺寸 ...

  5. Opencv中 Mat矩阵中属性【随笔记】

    Opencv Mat矩阵中data.size.depth.elemSize.step等属性的理解 data: uchar类型的指针,指向Mat数据矩阵的首地址.可以理解为标示一个房屋的门牌号: dim ...

  6. OpenCV Java入门三 Mat的基本操作

    环境好了,我们就可以进入正文了. 在之前入门一.二中分别已经有画图的两个例子了.但没有细节展开我们的代码和OpenCV到底在干什么. 使用OpenCV时你需要补充的知识 你需要熟练使用Java Swi ...

  7. Opencv Mat矩阵操作

    Opencv Mat矩阵操作 1.生成矩阵: Mat image(240, 320, CV8UC3); 第一个参数是rows,该矩阵的行数:第二个参数是cols,该矩阵的列数:第三个参数是该矩阵元素的 ...

  8. Opencv Surf算子中keyPoints,描述子Mat矩阵,配对向量DMatch里都包含了哪些好玩的东东?

    Surf算法是一把牛刀,我们可以很轻易的从网上或各种Opencv教程里找到Surf的用例,把例程中的代码或贴或敲过来,满心期待的按下F5,当屏幕终于被满屏花花绿绿的小圆点或者N多道连接线条霸占时,内心 ...

  9. OpenCv:Mat矩阵的初始化

    在研究Mat矩阵的初始化的时候,发现其不能像Matx轻量级矩阵那样,直接利用数组来进行初始化,而是利用一个内部的变量类型:Scalar来进行初始化的.参考手册中的构造函数如下所示: (1) Mat:: ...

最新文章

  1. 计算机在幼儿园美术区域的应用,让幼儿在美术区域活动中快乐成长!
  2. 字典树实现_反怼面试官系列之 字典树
  3. ALV 简单实现HTML抬头的方法 (介绍 二)
  4. 计算机科学1pdf,计算机科学导论1.pdf
  5. PHP 服务器变量 $_SERVER(转)
  6. 鸿星尔克因公司系统崩溃、恳请顾客退款;乔布斯首份手写求职信拍卖出222万;OpenAI 开源 Triton语言|极客头条...
  7. 睡觉的时候,程序能不能自动查 bug?
  8. c语言程序创建的基本步骤,c语言程序设计基本步骤
  9. java替换特殊字符,如何替换字符串中的特殊字符?
  10. 计算机主板的接口结构名称10,[pc玩家]主板接口大盘点,细数历年主流的主板接口:内部接口...
  11. centos 6.5 mysql 5.5 安装,centos6.5 安装mysql-5.5
  12. JBE、JNBE、JA、JL指令详解(从原理上)
  13. Consider defining a bean of type `xxx` in your configuration问题解决
  14. java精确小数位数的几种方法
  15. shiro教程1(HelloWorld)
  16. 孩子立刻就不玩游戏了,因为他找到更好玩的东西!
  17. NTC热敏电阻计算温度之C代码
  18. UserWarning: Previous unbuffered result was left incomplete
  19. BUAA 439 孟竹屌丝玩儿游戏
  20. 什么是机器学习? 来自数据的情报

热门文章

  1. java.lang.RuntimeException: Parcelable encountered IOException writing
  2. The Android Gradle plugin supports only Kotlin Gradle plugin version 1.3.0 and higher.
  3. android 调用百度sdk点位当前城市
  4. TabLayout 遇到那些坑 tab标签不显示问题
  5. Unable to inject views for 包名.activity
  6. Oracl 12c (课本)
  7. 金蝶K/3 BOS产品培训教案
  8. 2022-2028年中国石油套管行业市场研究及前瞻分析报告
  9. [纪录]仿IOS滚轮效果(竖直滑动选择器)
  10. 将ADS1.2的工程迁移到KEIL上-基于2440