OpenCV—基本矩阵操作与示例[通俗易懂]

OpenCV—基本矩阵操作与示例[通俗易懂]图像处理中对矩阵的操作非常重要,本文总结了使用OpenCV进行矩阵的创建、初始化以及基本矩阵操作,给出了示例代码。

大家好,又见面了,我是你们的朋友全栈君。

 

OpenCV的基本矩阵操作与示例

OpenCV—基本矩阵操作与示例[通俗易懂]
 

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

 

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

 

 

 

1. 创建与初始化矩阵

 

1.1 数据类型

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

 

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类型矩阵,当然也可以直接手动创建矩阵,基本方法是指定矩阵尺寸和数据类型:

// 基本方法
	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");

运行结果:

OpenCV—基本矩阵操作与示例[通俗易懂]

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

1.3 初始化方法

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

 

// 初始化方法
	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;

运行结果:

OpenCV—基本矩阵操作与示例[通俗易懂]

 

 

2. 矩阵运算

 

2.1 基本概念

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

 

2.2 矩阵加减法

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

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;

 

OpenCV—基本矩阵操作与示例[通俗易懂]

 

 

 

2.3 矩阵乘法

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

 

	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 matrix
	cout << "\nm1.*2 = \n" << m1*2 << endl;
	// matrix per element multiplication
	cout << "\n(m1+2).*(m1+3) = \n" << (m1+1).mul(m1+3) << endl;
	// Matrix multiplication
	cout << "\nm1*m2 = \n" << m1*m2 << endl;

 

OpenCV—基本矩阵操作与示例[通俗易懂]

 

2.4 矩阵转置

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

 

// 转置
	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");

运行结果:

 

OpenCV—基本矩阵操作与示例[通俗易懂]

 

 

2.5 求逆矩阵

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

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

OpenCV—基本矩阵操作与示例[通俗易懂]

 

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

 

2.6 计算矩阵非零元素个数

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

 

 

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

OpenCV—基本矩阵操作与示例[通俗易懂]

 

 

 

2.7 均值和标准差

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

 

参数

 

 

  • src – 输入矩阵或图像
  • mean – 均值,OutputArray
  • stddev – 标准差,OutputArray

 

// 均值方差
	Mat mean;
	Mat stddev;
	meanStdDev(me, mean, stddev); //me为前文定义的5×5对角阵
	cout<<"mean = "<<mean<<endl;
	cout<<"stddev = "<<stddev<<endl;
	system("pause");

运行结果:

OpenCV—基本矩阵操作与示例[通俗易懂]

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

 

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

多通道矩阵运算结果:

OpenCV—基本矩阵操作与示例[通俗易懂]

 

OpenCV—基本矩阵操作与示例[通俗易懂]

 

2.8 求最大最小值

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

 

 

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 – 可选的蒙版,用于选择待处理子区域

 

// 求极值 最大、最小值及其位置
	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();

运行结果:


OpenCV—基本矩阵操作与示例[通俗易懂]

 

OpenCV—基本矩阵操作与示例[通俗易懂]
输入图像及其最大最小值位置

 

 

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


更多内容在《机器学习原理与编程实战》中,连接原理与实战:

https://blog.csdn.net/iracer/article/details/116051674?spm=1001.2014.3001.5501

OpenCV—基本矩阵操作与示例[通俗易懂]

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/148710.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • java数据库查询类建议收藏

    通用查询数据库辅助类,可实现任意查询语句的查询,还可以进行多结果集查询。类的代码:1packagecom.hongyuan.db;23importjava.math.BigDecimal

    2021年12月20日
  • Qt中自定义QTreeWidget实现节点拖拽复制功能[通俗易懂]

    Qt中自定义QTreeWidget实现节点拖拽复制功能[通俗易懂]QT中在QWidget支持拖拽功能,QTreeWidget继承自QWidget,所以自然也具有节点的拖拽功能。拖拽包含两个功能:一个是拖动(Drag),一个是放下(Drop)。拖动的数据是QMimeData数据,MIME数据定义格式:类型/数据(注意中间有斜线)。若被拖动的对象放下的控件,不接受拖动的对象,Qt光标显示禁用的形状(一个禁用形状)。开始拖动:通过调用QDrag::exec()…

  • JavaScript清空数组的三种方法

    JavaScript清空数组的三种方法1、length用length方法可以很轻松地清空数组,代码示例:vararr=[1,2,3];console.log(arr);arr.length=0;console.log(arr);结果如下:2、splisesplice()方法向/从数组中添加/删除项目,然后返回被删除的项目vararr=[1,2,3]…

  • 页面中插入百度地图(使用百度地图API)

    页面中插入百度地图(使用百度地图API)

  • Shiro安全框架入门篇(登录验证实例详解与源码)

    Shiro安全框架入门篇(登录验证实例详解与源码)

    2020年11月12日
  • 大数据管理与分析技术(1)[通俗易懂]

    大数据管理与分析技术(1)[通俗易懂]一、大数据的基本概念摘要:大数据基本概念考点:大数据的4V特征、类型(结构化与非结构化大数据)、核心技术(分布式存储和分布式处理)、大数据计算模式(批处理计算、流计算、图计算、查询分析计算)、每类计算模式典型的代表产品。大数据的4V特征规模性(volume)、多样性(variety)、价值密度(value)和高速性(velocity)大数据的类型结构化大数据:能够用数据或统一的结构加以表示的,如数字、符号。传统的关系数据模型,行数据,存储于数据库,可用二维表结构表示。非结构化大数据:是指其字段

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号