精华内容
下载资源
问答
  • 主要介绍了python矩阵运算,转置,逆运算,共轭矩阵实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • #先定义两个矩阵X=np.array([[1,2104,5,1,45],[1,1416,3,2,40],[1,1534,3,2,30],[1,852,2,1,36]])y=np.array([45,40,30,36])#内积以后发现c=np.dot(X.T,X)carray([[ 4, 5906, 13, 6, 151],[ 5906, 951093...

    我就废话不多说了,大家还是直接看代码吧!#先定义两个矩阵

    X=np.array([[1,2104,5,1,45],[1,1416,3,2,40],[1,1534,3,2,30],[1,852,2,1,36]])

    y=np.array([45,40,30,36])

    #内积以后发现

    c=np.dot(X.T,X)

    c

    array([[ 4, 5906, 13, 6, 151],

    [ 5906, 9510932, 21074, 8856, 228012],

    [ 13, 21074, 47, 19, 507],

    [ 6, 8856, 19, 10, 221],

    [ 151, 228012, 507, 221, 5821]])

    c.I

    d=np.dot(c.I,X.T)

    Traceback (most recent call last):

    File "

    d=np.dot(c.I,X.T)

    AttributeError: 'numpy.ndarray' object has no attribute 'I'

    #说明array进行内积以后已经不是array对象,成为ndarray对象,不能再进行.I,.T,.M的操作。

    #解决方法:把结果转为matrix就可以

    a=np.matrix([[ 4, 5906, 13, 6, 151],

    [ 5906, 9510932, 21074, 8856, 228012],

    [ 13, 21074, 47, 19, 507],

    [ 6, 8856, 19, 10, 221],

    [ 151, 228012, 507, 221, 5821]])

    a.I

    matrix([[ -4.12181049e+13, 1.93633440e+11, -8.76643127e+13,

    -3.06844458e+13, 2.28487459e+12],

    [ 1.93633440e+11, -9.09646601e+08, 4.11827338e+11,

    1.44148665e+11, -1.07338299e+10],

    [ -8.76643127e+13, 4.11827338e+11, -1.86447963e+14,

    -6.52609055e+13, 4.85956259e+12],

    [ -3.06844458e+13, 1.44148665e+11, -6.52609055e+13,

    -2.28427584e+13, 1.70095424e+12],

    [ 2.28487459e+12, -1.07338299e+10, 4.85956259e+12,

    1.70095424e+12, -1.26659193e+11]])

    补充知识:矩阵和向量共轭

    矩阵包括实数矩阵和复数矩阵。

    矩阵的转置是将其行列互换位置,

    矩阵的共轭转置则是在矩阵转置的基础上(行列互换位置)对其每一个元素取共轭。

    形如 a+bi的复数,其共轭为a-bi。实数的共轭等于它本身。

    所以,实数矩阵的共轭转置矩阵就是转置矩阵,复数矩阵的共轭转置矩阵就是行列互换位置后每个元素取共轭。

    在Fortran中,其调用函数为:

    CONJG(x)求x的共轭复数。x:C, 结果:C

    以上这篇python矩阵运算,转置,逆运算,共轭矩阵实例就是小编分享给大家的全部内容了,希望能给大家一个参考。

    展开全文
  • #先定义两个矩阵X=np.array([[1,2104,5,1,45],[1,1416,3,2,40],[1,1534,3,2,30],[1,852,2,1,36]])y=np.array([45,40,30,36])#内积以后发现c=np.dot(X.T,X)carray([[ 4, 5906, 13, 6, 151],[ 5906, 951093...

    我就废话不多说了,大家还是直接看代码吧!

    #先定义两个矩阵

    X=np.array([[1,2104,5,1,45],[1,1416,3,2,40],[1,1534,3,2,30],[1,852,2,1,36]])

    y=np.array([45,40,30,36])

    #内积以后发现

    c=np.dot(X.T,X)

    c

    array([[ 4, 5906, 13, 6, 151],

    [ 5906, 9510932, 21074, 8856, 228012],

    [ 13, 21074, 47, 19, 507],

    [ 6, 8856, 19, 10, 221],

    [ 151, 228012, 507, 221, 5821]])

    c.I

    d=np.dot(c.I,X.T)

    Traceback (most recent call last):

    File "", line 1, in

    d=np.dot(c.I,X.T)

    AttributeError: 'numpy.ndarray' object has no attribute 'I'

    #说明array进行内积以后已经不是array对象,成为ndarray对象,不能再进行.I,.T,.M的操作。

    #解决方法:把结果转为matrix就可以

    a=np.matrix([[ 4, 5906, 13, 6, 151],

    [ 5906, 9510932, 21074, 8856, 228012],

    [ 13, 21074, 47, 19, 507],

    [ 6, 8856, 19, 10, 221],

    [ 151, 228012, 507, 221, 5821]])

    a.I

    matrix([[ -4.12181049e+13, 1.93633440e+11, -8.76643127e+13,

    -3.06844458e+13, 2.28487459e+12],

    [ 1.93633440e+11, -9.09646601e+08, 4.11827338e+11,

    1.44148665e+11, -1.07338299e+10],

    [ -8.76643127e+13, 4.11827338e+11, -1.86447963e+14,

    -6.52609055e+13, 4.85956259e+12],

    [ -3.06844458e+13, 1.44148665e+11, -6.52609055e+13,

    -2.28427584e+13, 1.70095424e+12],

    [ 2.28487459e+12, -1.07338299e+10, 4.85956259e+12,

    1.70095424e+12, -1.26659193e+11]])

    补充知识:矩阵和向量共轭

    矩阵包括实数矩阵和复数矩阵。

    矩阵的转置是将其行列互换位置,

    矩阵的共轭转置则是在矩阵转置的基础上(行列互换位置)对其每一个元素取共轭。

    形如 a+bi的复数,其共轭为a-bi。实数的共轭等于它本身。

    所以,实数矩阵的共轭转置矩阵就是转置矩阵,复数矩阵的共轭转置矩阵就是行列互换位置后每个元素取共轭。

    在Fortran中,其调用函数为:

    CONJG(x)

    求x的共轭复数。x:C, 结果:C

    以上这篇python矩阵运算,转置,逆运算,共轭矩阵实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

    展开全文
  • 一种计算方程共轭复根Matlab程序实例,已在Matlab验证可行,适合Matlab初学者,分享共同学习。
  • 下面小编就为大家分享一篇对python 矩阵转置transpose的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 共轭函数

    2021-03-31 19:45:05
    共轭函数   设函数f:Rn→Rf:\mathrm{R}^{n}\rightarrow \mathrm{R}f:Rn→R,定义函数f∗:Rn→Rf^{*}:\mathrm{R}^{n}\rightarrow\mathrm{R}f∗:Rn→R为f∗(y)=sup⁡x∈dom(y⊤x−f(x))f^{*}(y)=\underset{x \in \...

    1.共轭函数

      设函数 f : R n → R f:\mathrm{R}^{n}\rightarrow \mathrm{R} f:RnR,定义函数 f ∗ : R n → R f^{*}:\mathrm{R}^{n}\rightarrow\mathrm{R} f:RnR f ∗ ( y ) = sup ⁡ x ∈ d o m ( y ⊤ x − f ( x ) ) , f^{*}(y)=\underset{x \in \mathrm{dom}}{\operatorname{sup}}(y^{\top}x-f(x)), f(y)=xdomsup(yxf(x))此函数称为函数 f f f的共轭函数。使上述上确界有限,即差值 y ⊤ x − f ( x ) y^{\top}x-f(x) yxf(x) d o m f \mathrm{dom}f domf有上界的所有 y ∈ R n y \in \mathrm{R}^{n} yRn构成共轭函数的定义域。

     如上图所示,函数 f : R → R f:\mathrm{R}\rightarrow\mathrm{R} f:RR以及某一 y ∈ R y \in \mathrm{R} yR。共轭函数 f ∗ ( y ) f^{*}(y) f(y)是线性函数 y x yx yx f ( x ) f(x) f(x)之间的最大差值,见红色虚线所示。如果 f f f可微,在满足 f ′ ( x ) = y f^{\prime}(x)=y f(x)=y的点 x x x处差值最大。显而易见, f ∗ f^{*} f是凸函数,这是因为它是一系列 y y y的凸函数(实质上是仿射函数)的逐点上确界。无论 f f f是否是凸函数, f ∗ f^{*} f都是凸函数(注意到这里当 f f f是凸函数时,下标 x ∈ d o m f x \in \mathrm{dom}f xdomf可以去掉,这里是因为根据之前关于扩展延伸的定义,对于 x ∉ d o m f , y ⊤ x − f ( x ) = − ∞ x \notin \mathrm{dom}f,y^{\top}x-f(x)=-\infty x/domf,yxf(x)=

    2.具体实例

    2.1 凸函数的共轭函数

    • 仿射函数 f ( x ) = a x + b f(x)=ax+b f(x)=ax+b:作为 x x x的函数,当且仅当 y = a y=a y=a,即为常数时, y x − a x − b yx-ax-b yxaxb有界。因此共轭函数 f ∗ f^{*} f的定义域为单点集 { a } \{a\} {a},且 f ∗ ( a ) = − b f^{*}(a)=-b f(a)=b
    • 负对数函数 f ( x ) = − log ⁡ x f(x)=-\log x f(x)=logx:定义域为 d o m f = R + + \mathrm{dom}f=\mathrm{R}^{++} domf=R++。当 y ≥ 0 y \geq 0 y0时,函数 x y + log ⁡ x xy+\log x xy+logx无上界,当 y < 0 y < 0 y<0时,在 x = − 1 / y x=-1/y x=1/y处函数达到最大值。因此,定义域 d o m f ∗ = { y ∣ y < 0 } = − R + + \mathrm{dom}f^{*}=\{y|y<0\}=-\mathrm{R}_{++} domf={yy<0}=R++,共轭函数为 f ∗ ( y ) = − log ⁡ ( − y ) − 1 ( y < 0 ) f^{*}(y)=-\log(-y)-1(y<0) f(y)=log(y)1(y<0)
    • 指数函数 f ( x ) = e x f(x)=e^{x} f(x)=ex:当 y < 0 y<0 y<0时,函数 x y − e x xy-e^{x} xyex无界。当 y > 0 y>0 y>0时,函数 x y − e x xy-e^{x} xyex x = log ⁡ y x=\log y x=logy处达到最大值。因此, f ∗ ( y ) = y log ⁡ y − y f^{*}(y)=y\log y-y f(y)=ylogyy。当 y = 0 y=0 y=0s时, f ∗ ( y ) = s u p x − e x = 0 f^{*}(y)=\underset{x}{\mathrm{sup}}-e^{x}=0 f(y)=xsupex=0。综合起来, d o m f ∗ = R + \mathrm{dom}f^{*}=\mathrm{R}_{+} domf=R+ f ∗ ( y ) = y log ⁡ y − y f^{*}(y)=y\log y-y f(y)=ylogyy(其中规定 0 log ⁡ 0 = 0 0\log 0=0 0log0=0)。
    • 负熵函数 f ( x ) = x l o g x f(x)=xlogx f(x)=xlogx:定义域为 d o m f = R + \mathrm{dom}f=\mathrm{R}_{+} domf=R+。对所有 y y y,函数 x y − x log ⁡ x xy-x\log x xyxlogx关于 x x x R + \mathrm{R}_{+} R+上有界,因此 d o m f ∗ = R \mathrm{dom}f^{*}=\mathrm{R} domf=R。在 x = e y − 1 x=e^{y-1} x=ey1处,函数达到最大值。因此 f ∗ ( y ) = e y − 1 f^{*}(y)=e^{y-1} f(y)=ey1
    • 反函数 f ( x ) = 1 / x f(x)=1/x f(x)=1/x:当 y > 0 y>0 y>0时, y x − 1 / x yx-1/x yx1/x无上界。当 y = 0 y=0 y=0时,函数有上确界0;当 y < 0 y<0 y<0时,在 x = ( − y ) − 1 / 2 x=(-y)^{-1/2} x=(y)1/2处达到上确界。因此, f ∗ ( y ) = − 2 ( − y ) 1 / 2 f^{*}(y)=-2(-y)^{1/2} f(y)=2(y)1/2 d o m f ∗ = − R + \mathrm{dom}f^{*}=-\mathrm{R}_{+} domf=R+

    2.2 严格凸的二次函数

      考虑函数 f ( x ) = 1 2 x ⊤ Q x , Q ∈ S + + n f(x)=\frac{1}{2}x^{\top}Qx,Q \in S^{n}_{++} f(x)=21xQx,QS++n。对所有的 y y y x x x的函数 y ⊤ x − 1 2 x ⊤ Q x y^{\top}x-\frac{1}{2}x^{\top}Qx yx21xQx都有上界并在 x = Q − 1 y x=Q^{-1}y x=Q1y处达到上确界,因此 f ∗ ( y ) = 1 2 y ⊤ Q − 1 y . f^{*}(y)=\frac{1}{2}y^{\top}Q^{-1}y. f(y)=21yQ1y.

    2.3 对数行列式

     考虑 S + + n \mathrm{S}_{++}^{n} S++n上定义的函数 f ( X ) = log ⁡ det ⁡ X − 1 f(X)=\log \det X^{-1} f(X)=logdetX1。其共轭函数定义为 f ∗ ( Y ) = s u p X ≻ 0 ( t r ( Y X ) + log ⁡ det ⁡ X ) , f^{*}(Y)=\underset{X \succ 0}{\mathrm{sup}}(\mathrm{tr}(YX)+\log \det X), f(Y)=X0sup(tr(YX)+logdetX),其中, t r ( Y X ) \mathrm{tr}(YX) tr(YX) S n \mathrm{S}^{n} Sn上的标准内积。首先说明当只有 Y ≺ 0 Y\prec 0 Y0时, t r ( Y X ) + log ⁡ det ⁡ X \mathrm{tr}(YX)+\log \det X tr(YX)+logdetX才有上界。如果 Y ⊀ 0 Y \nprec 0 Y0,则有 Y Y Y有特征向量 v v v ∥ v ∥ 2 = 1 \|v\|_2=1 v2=1且对应的特征值 λ ≥ 0 \lambda \geq 0 λ0。令 X = I + t v v ⊤ X=I+tvv^{\top} X=I+tvv,则有 t r ( Y X ) + log ⁡ det ⁡ X = t r Y + t λ + log ⁡ det ⁡ ( I + t v v ⊤ ) = t r Y + t λ + log ⁡ ( 1 + t ) , \mathrm{tr}(YX)+\log \det X =\mathrm{tr} Y +t\lambda+\log \det(I+tvv^{\top})=\mathrm{tr} Y+t\lambda+\log(1+t), tr(YX)+logdetX=trY+tλ+logdet(I+tvv)=trY+tλ+log(1+t), t → ∞ t \rightarrow \infty t时,上式无界。接下来考虑 Y ≺ 0 Y \prec 0 Y0的情形,为了求最大值,令对 X X X的偏导为零,则 ∇ X ( t r ( Y X ) + log ⁡ det ⁡ X ) = Y + X − 1 = 0 \nabla_X(\mathrm{tr}(YX)+\log \det X)=Y+X^{-1}=0 X(tr(YX)+logdetX)=Y+X1=0 X = − Y − 1 X=-Y^{-1} X=Y1 X X X是正定的)。因此 f ∗ ( Y ) = log ⁡ det ⁡ ( − Y ) − 1 − n , f^{*}(Y)=\log \det(-Y)^{-1}-n, f(Y)=logdet(Y)1n,其定义域为 d o m f ∗ = − S + + n \mathrm{dom}f^{*}=-\mathrm{S}_{++}^{n} domf=S++n

    2.4 示性函数

     设 I S I_S IS是某个集合 S ⊆ R n S \subseteq \mathrm{R}^n SRn(不一定是凸集)的示性函数,即当 x x x d o m I S = S \mathrm{dom}I_S=S domIS=S内时, I S ( x ) = 0 I_S(x)=0 IS(x)=0。示性函数的共轭函数为 I S ∗ ( y ) = s u p x ∈ S y ⊤ x , I^{*}_S(y)=\underset{x \in S}{\mathrm{sup}}y^{\top}x, IS(y)=xSsupyx,它是集合 S S S的支撑函数。

    2.5 指数和的对数函数

      为了得到指数和的对数函数 f ( x ) = log ⁡ ( ∑ i = 1 n e x i ) f(x)=\log (\sum\limits_{i=1}^{n}e^{x_i}) f(x)=log(i=1nexi)的共轭函数,首先考察 y y y取何值时 y ⊤ x − f ( x ) y^{\top}x-f(x) yxf(x)的最大值可以得到。对 x x x求导,令其为零,得到如下条件: y i = e x i ∑ j = 1 n e x j , i = 1 , ⋯   , n . y_i=\frac{e^{x_i}}{\sum\limits_{j=1}^{n}e^{x_j}},i=1,\cdots,n. yi=j=1nexjexi,i=1,,n.当且仅当 y ≻ 0 y \succ 0 y0以及 1 ⊤ y = 1 \boldsymbol{1}^{\top}y=1 1y=1时上述方程有解。将 y i y_i yi的表达式代入 y ⊤ x − f ( x ) y^{\top}x-f(x) yxf(x)可得 f ∗ ( y ) = ∑ i = 1 n y i log ⁡ y i f^{*}(y)=\sum\limits_{i=1}^{n}y_i\log y_i f(y)=i=1nyilogyi。根据前面的约定, 0 log ⁡ 0 0 \log 0 0log0等于0,因此只要满足 y ⪰ 0 y \succeq 0 y0以及 1 ⊤ y = 1 \boldsymbol{1}^{\top}y=1 1y=1,即使当 y y y的某些分量为零时, f ∗ f^{*} f的表达式仍然正确。
    &esmsp; 事实上 f ∗ f^{*} f的定义域即为 1 ⊤ y = 1 , y ⪰ 0 \boldsymbol{1}^{\top}y=1,y \succeq0 1y=1,y0。为了说明这一点,假设 y y y的某个分量是负的,比如说 y k < 0 y_k < 0 yk<0,令 x k = − t x_k=-t xk=t x i = 0 x_i=0 xi=0 i ≠ k i \neq k i=k,令 t t t趋向于无穷, y ⊤ x − f ( x ) y^{\top}x-f(x) yxf(x)无上界。如果 y ⪰ 0 y \succeq 0 y0但是 1 ⊤ y ≠ 1 \boldsymbol{1}^{\top}y \neq1 1y=1,令 x = t 1 x=t_1 x=t1,可得 y ⊤ x − f ( x ) = t 1 ⊤ y − t − log ⁡ n . y^{\top}x-f(x)=t_1^{\top}y-t-\log n. yxf(x)=t1ytlogn. 1 ⊤ y > 1 \boldsymbol{1}^{\top}y>1 1y>1,当 t → ∞ t \rightarrow \infty t时上述表达式无界;当 1 ⊤ y < 1 \boldsymbol{1}^{\top}y < 1 1y<1时,若 t → t \rightarrow t时其无界。总之 f ∗ ( y ) = { ∑ i = 1 n y i log ⁡ y i y ⪰ 0 and 1 ⊤ y = 1 ∞ o t h e r w i s e f^{*}(y)=\left\{\begin{array}{ll}\sum\limits_{i=1}^{n}y_i \log y_i & y \succeq 0 \text{and} \boldsymbol{1}^{\top}y=1 \\ \infty &\mathrm{otherwise}\end{array}\right. f(y)=i=1nyilogyiy0and1y=1otherwise换言之,指数和的对数函数的共轭函数是概率单纯形内的负熵函数。

    2.6 范数

      令 ∥ ⋅ ∥ \|\cdot\| 表示 R n \mathrm{R}^{n} Rn上的范数,其对偶范数为 ∥ ⋅ ∥ ∗ \|\cdot\|_{*} 。则其共轭函数为 f ∗ ( y ) = { 0 ∥ y ∥ ∗ ≤ 1 ∞ o t h e r w i s e f^{*}(y)=\left\{\begin{array}{ll}0 & \|y\|_{*}\leq 1\\\infty&\mathrm{otherwise}\end{array}\right. f(y)={0y1otherwise即范数的共轭函数是对偶范数单位球的示性范数。如果 ∥ y ∥ ∗ > 1 \|y\|_{*}>1 y>1,根据对偶范数的定义,存在 z ∈ R n z \in \mathrm{R}^{n} zRn ∥ z ∥ ≤ 1 \|z\|\leq1 z1使得 y ⊤ z > 1 y^{\top}z>1 yz>1。取 x = t z x=tz x=tz,令 t → ∞ t \rightarrow\infty t可得 y ⊤ x − ∥ x ∥ = t ( y ⊤ z − ∥ z ∣ ∣ ) → ∞ , y^{\top}x-\|x\|=t(y^{\top}z-\|z||)\rightarrow \infty, yxx=t(yzz), f ∗ ( y ) = ∞ f^{*}(y)=\infty f(y)=,没有上界。反之,若 ∥ y ∥ ∗ ≤ 1 \|y\|_{*}\leq 1 y1,对任意 x x x,有 y ⊤ x ≤ ∥ x ∥ ∥ y ∥ ∗ y^{\top}x \leq \|x\|\|y\|_{*} yxxy,即对任意 x x x y ⊤ x − ∥ x ∥ ≤ 0 y^{\top}x-\|x\|\leq 0 yxx0。因此,在 x = 0 x=0 x=0处, y ⊤ x − ∥ x ∥ y^{\top}x-\|x\| yxx达到最大值0。

    2.7 范数的平方

      考虑函数 f ( x ) = 1 2 ∥ x ∥ 2 f(x)=\frac{1}{2}\|x\|^{2} f(x)=21x2,其中 ∥ ⋅ ∥ \|\cdot\| 是范数,对偶范数为 ∥ ⋅ ∥ ∗ \|\cdot\|_{*} 。此函数的共轭函数为 f ∗ ( y ) = 1 2 ∥ y ∥ ∗ 2 f^{*}(y)=\frac{1}{2}\|y\|_{*}^{2} f(y)=21y2。由 y ⊤ x ≤ ∥ y ∥ ∗ ∥ x ∥ y^{\top}x \leq\|y\|_{*}\|x\| yxyx可知,对任意 x x x下式成立 y ⊤ x − 1 2 ∥ x ∥ 2 ≤ ∥ y ∥ ∗ ∥ x ∥ − 1 2 ∥ x ∥ 2 . y^{\top}x-\frac{1}{2}\|x\|^2\leq \|y\|_{*}\|x\|-\frac{1}{2}\|x\|^2. yx21x2yx21x2.上式右端是 ∥ x ∥ \|x\| x的二次函数,其最大值为 ( 1 / 2 ) ∥ y ∥ ∗ 2 (1/2)\|y\|^2_{*} (1/2)y2。因此对任意 x x x,则有 y ⊤ x − ( 1 / 2 ) ∥ x ∥ 2 ≤ ( 1 / 2 ) ∥ y ∥ ∗ 2 , y^{\top}x-(1/2)\|x\|^{2}\leq(1/2)\|y\|_{*}^{2}, yx(1/2)x2(1/2)y2, f ∗ ( y ) ≤ ( 1 / 2 ) ∥ y ∥ ∗ 2 f^{*}(y)\leq(1/2)\|y\|^{2}_{*} f(y)(1/2)y2。为了说明 f ∗ ( y ) ≥ ( 1 / 2 ) ∥ y ∥ ∗ f^{*}(y)\geq(1/2)\|y\|_{*} f(y)(1/2)y,任取满足 y ⊤ x = ∥ y ∥ ∗ ∥ x ∥ y^{\top}x=\|y\|_{*}\|x\| yx=yx的向量 x x x,对其进行伸缩使得 ∥ x ∥ = ∥ y ∥ ∗ \|x\|=\|y\|_{*} x=y。对于此 x x x y ⊤ x − ( 1 / 2 ) ∥ x ∥ 2 = ( 1 / 2 ) ∥ y ∥ ∗ 2 , y^{\top}x-(1/2)\|x\|^{2}=(1/2)\|y\|^{2}_{*}, yx(1/2)x2=(1/2)y2,因此 f ∗ ( y ) ≥ ( 1 / 2 ) ∥ y ∥ ∗ 2 f^{*}(y)\geq (1/2)\|y\|_{*}^{2} f(y)(1/2)y2

    3.基本性质

    3.1 Fenchel 不等式

     从共轭函数的定义可以得到,对任意 x x x y y y,如下不等式成立 f ( x ) + f ( y ) ≥ x ⊤ y , f(x)+f(y)\geq x^{\top}y, f(x)+f(y)xy,上述不等式为Fenchel不等式(当 f f f可微的时候亦称Young不等式)。
      以函数 f ( x ) = ( 1 / 2 ) x ⊤ Q x f(x)=(1/2)x^{\top}Qx f(x)=(1/2)xQx为例,其中 Q ∈ S + + n Q \in \mathrm{S}^{n}_{++} QS++n,可以得到如下不等式 x ⊤ y ≤ ( 1 / 2 ) x ⊤ Q x + ( 1 / 2 ) y ⊤ Q − 1 y . x^{\top}y \leq (1/2)x^{\top}Qx+(1/2)y^{\top}Q^{-1}y. xy(1/2)xQx+(1/2)yQ1y.

    3.2 共轭的共轭

      凸函数的共轭函数的共轭函数是原函数。也即:如果函数 f f f是凸函数且 f f f是闭的(即 e p i f \mathrm{epi} f epif是闭集),则 f ∗ ∗ = f f^{**}=f f=f

    3.3 可微函数

      可微函数 f f f的共轭函数亦称为函数 f f f的Legendre变换。(为了区分一般情况和可微情况下所定义的共轭,一般函数的共轭有时称为Fenchel共轭。)
      设函数 f f f是凸函数且可微,其定义域为 d o m f = R n \mathrm{dom}f=\mathrm{R}^{n} domf=Rn,使 y ⊤ x − f ( x ) y^{\top}x-f(x) yxf(x)取最大的 x ∗ x^{*} x满足 y = ∇ f ( x ∗ ) y=\nabla f(x^{*}) y=f(x),反之,若 x ∗ x^{*} x满足KaTeX parse error: Expected '}', got 'EOF' at end of input: …\nabla f(x^{*]),y^{\top}x-f(x)在 x ∗ x^{*} x处取最大值。因此如果 y = ∇ f ( x ∗ ) y=\nabla f(x^{*}) y=f(x),则有 f ∗ ( y ) = x ∗ ∇ f ( x ∗ ) − f ( x ∗ ) . f^{*}(y)=x^{*}\nabla f(x^{*})-f(x^{*}). f(y)=xf(x)f(x).所以,给定任意 y y y,我们可以求解梯度方程 y = ∇ f ( z ) y=\nabla f(z) y=f(z),从而得到 y y y处的共轭函数 f ∗ ( y ) f^{*}(y) f(y)。亦可以换个角度理解,任选 z ∈ R n z \in \mathrm{R}^{n} zRn,令 y = ∇ f ( z ) y=\nabla f(z) y=f(z),则 f ∗ ( y ) = z ⊤ ∇ f ( z ) − f ( z ) . f^{*}(y)=z^{\top}\nabla f(z)-f(z). f(y)=zf(z)f(z).

    3.4 伸缩变换和复合仿射变换

     若 a > 0 a>0 a>0以及 b ∈ R b \in \mathrm{R} bR g ( x ) = a f ( x ) + b g(x)=af(x)+b g(x)=af(x)+b的共轭函数为 g ∗ ( y ) = a f ∗ ( y / a ) − b g^{*}(y)=af^{*}(y/a)-b g(y)=af(y/a)b。设 A ∈ R n × n A \in \mathrm{R}^{n \times n} ARn×n非奇异, b ∈ R n b\in \mathrm{R}^{n} bRn,则函数 g ( x ) = f ( A x + b ) g(x)=f(Ax+b) g(x)=f(Ax+b)的共轭函数为 g ∗ ( y ) = f ∗ ( A − ⊤ y ) − b ⊤ A − ⊤ y , g^{*}(y)=f^{*}(A^{-\top}y)-b^{\top}A^{-\top}y, g(y)=f(Ay)bAy,其定义域为 d o m g ∗ = A ⊤ d o m f ∗ \mathrm{dom}g^{*}=A^{\top}\mathrm{dom}f^{*} domg=Adomf

    3.5 独立函数的和

      如果函数 f ( u , v ) = f 1 ( u ) + f 1 ( v ) f(u,v)=f_1(u)+f_1(v) f(u,v)=f1(u)+f1(v),其中 f 1 f_1 f1 f 2 f_2 f2是凸函数,且共轭函数分别为 f 1 ∗ f^{*}_1 f1 f 2 ∗ f^{*}_2 f2,则 f ∗ ( w , z ) = f 1 ∗ ( w ) + f 2 ∗ ( z ) f^{*}(w,z)=f^{*}_1(w)+f^{*}_2(z) f(w,z)=f1(w)+f2(z)换言之,独立函数的和的共轭函数是各个凸函数的共轭函数的和。(“独立”的含义是各个函数具有不同的变量。)

    展开全文
  • 第三节 矩阵操作 OpenCV对矩阵操作提供了丰富的操作函数。本节将详细描述常用基本的矩阵和图像算子。 1、cv::abs 和cv::absdiff cv::abs:计算矩阵每个元素的绝对值。 float data[] = {-1,-2,-3,4,5,6,7,8,9}; cv::...

    第三节 矩阵操作

    OpenCV对矩阵操作提供了丰富的操作函数。本节将详细描述常用基本的矩阵和图像算子。

    1、cv::abs 和cv::absdiff


    cv::abs:计算矩阵每个元素的绝对值。

    float data[] = {-1,-2,-3,4,5,6,7,8,9};
    cv::Mat m1(cv::Size(3,3),CV_32FC1,data);
    cv::Mat m2 = cv::abs(m1);
    std::cout << "m2 = " << m2 << std::endl;
    

    cv::absdiff:计算两个数组之间或数组与标量之间的每个元素的绝对差。其原型为:

    void cv::absdiff(InputArray src1,InputArray src2,OutputArray dst )

    • 当两个数组的大小和类型相同时,它们之间的绝对差为: dst ( I ) = saturate ( ∣ src1 ( I ) − src2 ( I ) ∣ ) \texttt{dst}(I) = \texttt{saturate} (| \texttt{src1}(I) - \texttt{src2}(I)|) dst(I)=saturate(src1(I)src2(I))

    • 当第二个数组是由Scalar构造或具有与其中的通道数一样多的元素时,数组与标量之间的绝对差: dst ( I ) = saturate ( ∣ src1 ( I ) − src2 ∣ ) \texttt{dst}(I) = \texttt{saturate} (| \texttt{src1}(I) - \texttt{src2} |) dst(I)=saturate(src1(I)src2)

    • 当第一个数组由Scalar构造或具有与src2中的通道数一样多的元素时,标量和数组之间的绝对差: dst ( I ) = saturate ( ∣ src1 − src2 ( I ) ∣ ) \texttt{dst}(I) = \texttt{saturate} (| \texttt{src1} - \texttt{src2}(I) |) dst(I)=saturate(src1src2(I))

    cv::Mat m3(cv::Size(3,3),CV_32FC1,data2);
    cv::Mat m4;
    cv::absdiff(m1,m3,m4);
    std::cout << "cv::absdiff(m1,m3,m4) = " << m4 << std::endl;
    cv::Mat m5;
    cv::absdiff(m1,0.3,m5);
    std::cout << "cv::absdiff(m1,0.3,m5) = " << m5 << std::endl;
    

    2、cv::add、cv::addWeighted、cv::scaleAdd


    1)cv::add:计算两个数组或一个数组和一个标量的每个元素的总和。

    void cv::add(InputArraysrc1,InputArray src2,OutputArray dst,InputArray mask = noArray(),int dtype = -1)

    以下几种情况

    • 当两个输入数组具有相同的大小和相同的通道数时,两个数组的总和: dst ( I ) = saturate ( src1 ( I ) + src2 ( I ) ) if   mask ( I ) ≠ 0 \texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) + \texttt{src2}(I)) \quad \texttt{if mask}(I) \ne0 dst(I)=saturate(src1(I)+src2(I))if mask(I)=0
    • 从scalar构造src2或与src1.channels()具有相同数量的元素时,数组和标量的总和: dst ( I ) = saturate ( src1 ( I ) + src2 ) if   mask ( I ) ≠ 0 \texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) + \texttt{src2} ) \quad \texttt{if mask}(I) \ne0 dst(I)=saturate(src1(I)+src2)if mask(I)=0
    • 当从Scalar构造src1或与src2.channels()具有相同数量的元素时,标量和数组的和: dst ( I ) = saturate ( src1 + src2 ( I ) ) if   mask ( I ) ≠ 0 \texttt{dst}(I) = \texttt{saturate} ( \texttt{src1} + \texttt{src2}(I) ) \quad \texttt{if mask}(I) \ne0 dst(I)=saturate(src1+src2(I))if mask(I)=0

    其中,参数I是数组元素的多维索引。 在多通道阵列的情况下,每个通道都是独立处理的。输入阵列和输出阵列都可以具有相同或不同的深度。例如,可以将一个16位无符号数组添加到一个8位有符号数组中,并将和存储为32位浮点数组。 输出数组的深度由dtype参数确定。 在上面的第二种和第三种情况以及第一种情况下,当src1.depth()== src2.depth()时,dtype可以设置为默认值-1。 在这种情况下,输出数组将具有与输入数组相同的深度,无论是src1,src2还是两者。

    // 创建矩阵
    float data1[] = {1,2,3,4,5,6,7,8,9};
    float data2[] = {1,3,5,7,9,11,13,15,17};
    float maskdata[] = {1,1,1,0,0,0,1,1,1};
    cv::Mat src1(3,3,CV_32FC1,data1);
    cv::Mat src2(3,3,CV_32FC1,data2);
    cv::Mat mask(3,3,CV_8UC1,maskdata);
    // 矩阵相加,与output = src1 + src2 结果相同
    cv::Mat output;
    cv::add(src1,src2,output);
    cout << "src1 + src2 = " << output << endl;
    
    // 与常量相加
    cv::add(src1,0.5,output);
    cout << "src1 + 0.5 = " << output << endl;
    
    // 带有marsk矩阵相加
    cv::add(src1,src2,output,mask);
    cout << "src1 + src2 marsked = " << output << endl;
    

    2)cv::addWeighted:计算两个数组的加权和。

    **void cv::addWeighted(InputArray src1,double alpha,InputArray src2,double beta,double gamma,OutputArray dst,int dtype = -1) **

    函数addWeighted计算两个数组的加权和,如下所示:

    dst ( I ) = saturate ( src1 ( I ) ∗ alpha + src2 ( I ) ∗ beta + gamma ) \texttt{dst} (I)= \texttt{saturate} ( \texttt{src1} (I)* \texttt{alpha} + \texttt{src2} (I)* \texttt{beta} + \texttt{gamma} ) dst(I)=saturate(src1(I)alpha+src2(I)beta+gamma)

    // 带权重相加
    cv::addWeighted(src1,0.5,src2,0.5,0.75,output);
    std::cout << "src1 * 0.5 + src2*0.5+ 0.75 = " << output << endl;
    

    3)cv::scaleAdd:计算缩放数组和另一个数组的总和。

    void cv::scaleAdd(InputArray src1,double alpha,InputArray src2,OutputArray dst)

    函数scaleAdd是经典的原始线性代数运算之一,在BLAS中称为DAXPY或SAXPY。 它计算缩放数组和另一个数组的和: dst ( I ) = scale ⋅ src1 ( I ) + src2 ( I ) \texttt{dst} (I)= \texttt{scale} \cdot \texttt{src1} (I) + \texttt{src2} (I) dst(I)=scalesrc1(I)+src2(I)

    3、cv::batchDistance


    最近邻域搜索

    void cv::batchDistance(InputArray src1,InputArray src2,OutputArray dist,int dtype,OutputArray nidx,int normType = NORM_L2,int K = 0,InputArray mask = noArray(),int update = 0,bool crosscheck = false)

    float data1[] = {0,0,1,
                         1,1,1,
                         0,0,1};
    float data2[] = {1,1,0,
                         0,0,0,
                         1,1,0};
    cv::Mat src1(3,3,CV_32FC1,data1);
    cv::Mat src2(3,3,CV_32FC1,data2);
    cv::Mat dst;
    cv::Mat ndix;
    cv::batchDistance(src1,src2,dst,CV_32FC1,ndix,cv::NORM_L2,2);
    cout << "dst = " << dst << endl;
    cout << "ndix = " << ndix << endl;
    

    4、bitwise_and、bitwise_not、bitwise_or、bitwise_xor


    1)bitwise_and:计算两个数组或一个数组和一个标量的每个元素的按位与操作。

    void cv::bitwise_and (InputArray src1,InputArray src2,OutputArray dst,InputArray mask = noArray())

    • src1和src2具有相同大小时的两个数组: dst ( I ) = src1 ( I ) ∧ src2 ( I ) if   mask ( I ) ≠ 0 \texttt{dst} (I) = \texttt{src1} (I) \wedge \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0 dst(I)=src1(I)src2(I)if mask(I)=0
    • 从scalar构造src2或具有与src1.channels()相同数量的元素时的数组和标量: dst ( I ) = src1 ( I ) ∧ src2 if   mask ( I ) ≠ 0 \texttt{dst} (I) = \texttt{src1} (I) \wedge \texttt{src2} \quad \texttt{if mask} (I) \ne0 dst(I)=src1(I)src2if mask(I)=0
    • 当src1由Scalar构造或具有与src2.channels()相同数量的元素时,一个标量和一个数组: dst ( I ) = src1 ∧ src2 ( I ) if   mask ( I ) ≠ 0 \texttt{dst} (I) = \texttt{src1} \wedge \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0 dst(I)=src1src2(I)if mask(I)=0

    对于浮点数组,其机器特定的位表示形式(通常符合IEEE754)用于操作。 在多通道阵列的情况下,每个通道都是独立处理的。 在上述第二种和第三种情况下,首先将标量转换为数组类型。

    // 逻辑与操作
    // 相同大小矩阵
    cv::bitwise_and(src1,src2,dst);
    cout << "src1 & src2 = " << dst << endl;
    // 与常量运算
    cv::bitwise_and(src1,0x0E,dst);
    cout << "src1 & 0x0E = " << dst << endl;
    

    2)bitwise_not:反转数组的每一位。

    void cv::bitwise_not (InputArray src,OutputArray dst,InputArray mask = noArray())

    dst ( I ) = ¬ src ( I ) \texttt{dst} (I) = \neg \texttt{src} (I) dst(I)=¬src(I)

    对于浮点输入数组,其特定于机器的位表示形式(通常符合IEEE754)用于操作。 在多通道阵列的情况下,每个通道都是独立处理的。

    // 逻辑非操作
    cv::bitwise_not(src1,dst);
    cout << "~src1 = " << dst << endl;
    

    3)bitwise_or:计算两个数组或一个数组和一个标量的每个元素的按位或操作。

    void cv::bitwise_or(InputArray src1,InputArray src2,OutputArray dst,InputArray mask = noArray())

    • src1和src2具有相同大小时的两个数组: dst ( I ) = src1 ( I ) ∨ src2 ( I ) if   mask ( I ) ≠ 0 \texttt{dst} (I) = \texttt{src1} (I) \vee \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0 dst(I)=src1(I)src2(I)if mask(I)=0
    • 当从Scalar构造src2或具有与src1.channels()相同数量的元素时,一个数组和一个标量: dst ( I ) = src1 ( I ) ∨ src2 if   mask ( I ) ≠ 0 \texttt{dst} (I) = \texttt{src1} (I) \vee \texttt{src2} \quad \texttt{if mask} (I) \ne0 dst(I)=src1(I)src2if mask(I)=0
    • 当src1由Scalar构造或具有与src2.channels()相同数量的元素时,一个标量和一个数组: dst ( I ) = src1 ∨ src2 ( I ) if   mask ( I ) ≠ 0 \texttt{dst} (I) = \texttt{src1} \vee \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0 dst(I)=src1src2(I)if mask(I)=0

    对于浮点输入数组,其特定于机器的位表示形式(通常符合IEEE754)用于操作。 在多通道阵列的情况下,每个通道都是独立处理的。

    // 逻辑或操作
    cv::bitwise_or(src1,src2,dst);
    cout << "src1 | src2 = " << dst << endl;
    // 与常量运算
    cv::bitwise_or(src1,0x02,dst);
    cout << "src1 | 0x02 = " << dst << endl;
    

    4)bitwise_xor:计算两个数组或一个数组和一个标量的每个元素的按位“异或”运算。

    void cv::bitwise_xor(InputArray src1,InputArray src2,OutputArray dst,InputArray mask = noArray())

    • src1和src2具有相同大小时的两个数组: dst ( I ) = src1 ( I ) ⊕ src2 ( I ) if   mask ( I ) ≠ 0 \texttt{dst} (I) = \texttt{src1} (I) \oplus \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0 dst(I)=src1(I)src2(I)if mask(I)=0
    • 当从Scalar构造src2或具有与src1.channels()相同数量的元素时,一个数组和一个标量: dst ( I ) = src1 ( I ) ⊕ src2 if   mask ( I ) ≠ 0 \texttt{dst} (I) = \texttt{src1} (I) \oplus \texttt{src2} \quad \texttt{if mask} (I) \ne0 dst(I)=src1(I)src2if mask(I)=0
    • 当src1由Scalar构造或具有与src2.channels()相同数量的元素时,一个标量和一个数组: dst ( I ) = src1 ⊕ src2 ( I ) if   mask ( I ) ≠ 0 \texttt{dst} (I) = \texttt{src1} \oplus \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0 dst(I)=src1src2(I)if mask(I)=0

    对于浮点输入数组,其特定于机器的位表示形式(通常符合IEEE754)用于操作。 在多通道阵列的情况下,每个通道都是独立处理的。

    // 逻辑异或运算
    cv::bitwise_xor(src1,src2,dst);
    cout << "src1 ^ src2 = " << dst << endl;
    // 与常量运算
    cv::bitwise_xor(src1,0x0E,dst);
    cout << "src1 ^ 0x0E = " << dst << endl;
    

    5、cv::calcCovarMatrix


    计算一组向量的协方差矩阵。

    void cv::calcCovarMatrix(const Mat * samples,int nsamples,Mat & covar,Mat & mean,int flags,int ctype = CV_64F)

    flag的类型有:

    • COVAR_SCRAMBLED:输出协方差矩阵计算为: scale ⋅ [ vects [ 0 ] − mean , vects [ 1 ] − mean , . . . ] T ⋅ [ vects [ 0 ] − mean , vects [ 1 ] − mean , . . . ] , \texttt{scale} \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...]^T \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...], scale[vects[0]mean,vects[1]mean,...]T[vects[0]mean,vects[1]mean,...],
    • COVAR_NORMAL: 输出协方差矩阵计算为: scale ⋅ [ vects [ 0 ] − mean , vects [ 1 ] − mean , . . . ] ⋅ [ vects [ 0 ] − mean , vects [ 1 ] − mean , . . . ] T , \texttt{scale} \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...] \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...]^T, scale[vects[0]mean,vects[1]mean,...][vects[0]mean,vects[1]mean,...]T,
    • COVAR_USE_AVG: 该函数不会根据输入向量计算均值,而是使用传递的均值向量。 如果均值已预先计算或事先已知,或者如果协方差矩阵是按零件计算的,则这很有用。 在这种情况下,均值不是向量的输入子集的均值向量,而是整个集合的均值向量
    • COVAR_SCALE:协方差矩阵被缩放。 在“正常”模式下,小数位数为1./nsamples。 在“加扰”模式下,小数位数是每个输入向量中元素总数的倒数。 默认情况下(如果未指定标志),协方差矩阵不缩放(scale = 1)。
    • COVAR_ROWS:所有输入向量都存储为样本矩阵的行。 在这种情况下,均值应为单行向量。
    • COVAR_COLS:所有输入向量都存储为样本矩阵的列。 在这种情况下,均值应为单列向量。
    // 创建矩阵
    float data1[] = {1,1,127,
                         64,32,16,
                         1,1,2};
    float data2[] = {127,64,0,
                         0,0,0,
                         16,8,0};
    cv::Mat src1(3,3,CV_32FC1,data1);
    cv::Mat src2(3,3,CV_32FC1,data2);
    cv::Mat dst;
    cv::Mat mean;
    cv::Mat srcs[] = {src1,src2};
    // 计算矩阵协方差
    cv::calcCovarMatrix(srcs,2,dst,mean,cv::COVAR_SCALE|cv::COVAR_COLS);
    cout << "dst = " << dst << endl;
    cout << "mean = " << mean << endl;
    

    6、cv::cartToPolar、cv::polarToCart


    **1)cv::cartToPolar:**计算2D向量的大小和角度(笛卡尔坐标转极坐标)。

    void cv::cartToPolar (InputArray x,InputArray y,OutputArray magnitude,OutputArray angle,bool angleInDegrees = false)

    magnitude ( I ) = x ( I ) 2 + y ( I ) 2 , angle ( I ) = atan2 ( y ( I ) , x ( I ) ) [ ⋅ 180 / π ] \begin{array}{l} \texttt{magnitude} (I)= \sqrt{\texttt{x}(I)^2+\texttt{y}(I)^2} , \\ \texttt{angle} (I)= \texttt{atan2} ( \texttt{y} (I), \texttt{x} (I))[ \cdot180 / \pi ] \end{array} magnitude(I)=x(I)2+y(I)2 ,angle(I)=atan2(y(I),x(I))[180/π]

    角度的计算精度约为0.3度。对于点(0,0),角度设置为0。

    //建立容器存坐标
    vector<cv::Point2f> sides;
    sides.push_back(cv::Point2f(3, 4));
    sides.push_back(cv::Point2f(6, 8));
    sides.push_back(cv::Point2f(1, 1));
    
    cv::Mat xpts(sides.size(), 1, CV_32F, &sides[0].x, 2 * sizeof(float));
    cv::Mat ypts(sides.size(), 1, CV_32F, &sides[0].y, 2 * sizeof(float));
    
    cout << "x: " << xpts.t() << endl;
    cout << "y: " << ypts.t() << endl;
    
    cv::Mat magnitude, angle;
    cv::cartToPolar(xpts, ypts, magnitude, angle);//调用库函数
    
    cout << "\nmagnitude: " << magnitude.t();
    cout << "\nangle: " << angle.t() *180. / CV_PI <<endl;
    

    2)cv::polarToCart:根据大小和角度计算2D向量的x和y坐标。

    void cv::polarToCart(InputArray magnitude,InputArray angle,OutputArray y,bool angleInDegrees = false)

    函数cv :: polarToCart计算每个2D矢量的笛卡尔坐标,这些矢量由大小和角度的相应元素表示:

    x ( I ) = magnitude ( I ) cos ⁡ ( angle ( I ) ) y ( I ) = magnitude ( I ) sin ⁡ ( angle ( I ) ) \begin{array}{l} \texttt{x} (I) = \texttt{magnitude} (I) \cos ( \texttt{angle} (I)) \\ \texttt{y} (I) = \texttt{magnitude} (I) \sin ( \texttt{angle} (I)) \\ \end{array} x(I)=magnitude(I)cos(angle(I))y(I)=magnitude(I)sin(angle(I))

    估计坐标的相对精度约为1e-6。

    7、cv::checkRange


    检查输入数组的每个元素是否在有效的范围内。

    bool cv::checkRange(InputArray a,bool quiet = true,Point * pos = 0,double minVal = -DBL_MAX,double maxVal = DBL_MAX)

    函数cv :: checkRange检查每个数组元素既不是NaN也不是无限。 当minVal> -DBL_MAX且maxVal <DBL_MAX时,该函数还将检查每个值是否在minVal和maxVal之间。 在多通道阵列的情况下,每个通道都是独立处理的。 如果某些值超出范围,则第一个离群值的位置存储在pos中(当pos!= NULL时)。 然后,该函数将返回false(当quiet = true时)或引发异常。

    float data1[] = {1,1,127,
                         64,32,16,
                         1,1,2};
    cv::Mat src1(3,3,CV_32FC1,data1);
    // 检查元素的范围是否在1~128之间
    bool res = cv::checkRange(src1,true,0,1,128);
    cout << "res = " << res << endl;
    

    8、cv::compare


    对两个数组或数组和标量值执行每个元素的比较。

    void cv::compare (InputArray src1,InputArray src2,OutputArray dst,int cmpop)

    • 当src1和src2具有相同大小时,两个数组的元素: dst ( I ) = src1 ( I )   cmpop   src2 ( I ) \texttt{dst} (I) = \texttt{src1} (I) \,\texttt{cmpop}\, \texttt{src2} (I) dst(I)=src1(I)cmpopsrc2(I)
    • 当src2由标量构造或具有单个元素时,带有标量src2的src1元素: dst ( I ) = src1 ( I )   cmpop   src2 \texttt{dst} (I) = \texttt{src1}(I) \,\texttt{cmpop}\, \texttt{src2} dst(I)=src1(I)cmpopsrc2
    • 当src1由标量构造或具有单个元素时,带有src2元素的src1: dst ( I ) = src1   cmpop   src2 ( I ) \texttt{dst} (I) = \texttt{src1} \,\texttt{cmpop}\, \texttt{src2} (I) dst(I)=src1cmpopsrc2(I)

    如果比较结果为true,则将输出数组的相应元素设置为255。可以用等效的矩阵表达式替换比较操作:

    Mat dst1 = src1 >= src2;
    Mat dst2 = src1 < 8;
    

    cmpop的类型如下:CMP_EQ 、CMP_GT 、CMP_GE 、CMP_LT 、CMP_LE 、CMP_NE

    // 创建矩阵
    float data1[] = {1,1,127,
                         64,32,16,
                         1,1,2};
    float data2[] = {127,64,0,
                         0,0,0,
                         16,8,0};
    cv::Mat src1(3,3,CV_32FC1,data1);
    cv::Mat src2(3,3,CV_32FC1,data2);
    cv::Mat dst;
    // 矩阵比较
    cv::compare(src1,src2,dst,cv::CMP_EQ);
    cout << "dst = " << dst << endl;
    

    9、cv::completeSymm


    将方矩阵的下半部或上半部复制到另一半。

    void cv::completeSymm(InputOutputArray m,bool lowerToUpper = false)

    函数cv :: completeSymm将方矩阵的下半部或上半部复制到另一半。 矩阵对角线保持不变:

    • m i j = m j i \texttt{m}_{ij}=\texttt{m}_{ji} mij=mji for i > j i > j i>j if lowerToUpper=false
    • m i j = m j i \texttt{m}_{ij}=\texttt{m}_{ji} mij=mji for i < j i < j i<j if lowerToUpper=true
    // 创建矩阵
    float data1[] = {1,1,127,
                         64,32,16,
                         1,1,2};
    cv::Mat src1(3,3,CV_32FC1,data1);
    cout << "src1 = \n" << format(src1, cv::Formatter::FMT_PYTHON) << endl;
    // 复制到另一半
    cv::completeSymm(src1);
    cout << "dst = \n" << format(src1, cv::Formatter::FMT_PYTHON) << endl;
    

    10、cv::convertScaleAbs


    缩放,计算绝对值,然后将结果转换为8位类型。

    void cv::convertScaleAbs(InputArray src,OutputArray dst,double alpha = 1,double beta = 0)

    在输入数组的每个元素上,函数convertScaleAbs依次执行三个操作:缩放,获取绝对值,转换为无符号的8位类型:

    dst ( I ) = saturate_cast<uchar> ( ∣ src ( I ) ∗ alpha + beta ∣ ) \texttt{dst} (I)= \texttt{saturate\_cast<uchar>} (| \texttt{src} (I)* \texttt{alpha} + \texttt{beta} |) dst(I)=saturate_cast<uchar>(src(I)alpha+beta)

    如果是多通道阵列,该函数将独立处理每个通道。 当输出不是8位时,可以通过调用Mat :: convertTo方法(或使用矩阵表达式)然后通过计算结果的绝对值来模拟该操作。 例如:

    Mat_<float> A(30,30);
    randu(A, Scalar(-100), Scalar(100));
    Mat_<float> B = A*5 + 3;
    B = abs(B);
    

    11、cv::copyMakeBorder


    边缘填充。

    void cv::copyMakeBorder(InputArray src,OutputArray dst,int top,int bottom,int left,int right,int borderType,const Scalar & value = Scalar())

    该功能将源图像复制到目标图像的中间。 复制的源图像左侧,右侧,上方和下方的区域将被外推像素填充。 这不是基于此功能的过滤功能(它们会即时推断像素),而是其他更复杂的功能(包括您自己的功能)可以用来简化图像边界处理。

    borderType有以下类型:

    BORDER_CONSTANTBORDER_REPLICATE、**BORDER_REFLECT **、BORDER_WRAP、**BORDER_REFLECT_101 **、**BORDER_TRANSPARENT **、**BORDER_REFLECT101 **、**BORDER_DEFAULT **、**BORDER_ISOLATED **

    // 创建矩阵
    cv::Mat src = cv::Mat::ones(15,15,CV_8UC1);
    cout << "src = \n" << src << endl;
    cv::Mat dst;
    
    int top = (int) (0.1 * src.rows);
    int bottom = top;
    int left = (int) (0.1*src.cols);
    int right = left;
    // 边缘填充
    copyMakeBorder(src,dst,top, bottom, left, right,cv::BORDER_CONSTANT);
    cout << "dst = \n" << dst << endl;
    

    12、cv::countNonZero


    计算非零数组元素。

    int cv::countNonZero(InputArray src)

    该函数返回src中非零元素的数量:

    ∑ I :    src ( I ) ≠ 0 1 \sum _{I: \; \texttt{src} (I) \ne0 } 1 I:src(I)=01

    // 创建矩阵
    float data[] = {127,64,0,
                         0,0,0,
                         16,8,0};
    cv::Mat src(3,3,CV_32FC1,data);
    
    // 计算非零元素
    int counts = cv::countNonZero(src);
    cout << "non-zeros counts = " << counts << endl;
    

    13、cv::dct、cv::idct


    1)cv::dct:对1D或2D数组执行正向或反向离散余弦变换。

    void cv::dct(InputArray src,OutputArray dst,int flags = 0)

    函数cv :: dct执行1D或2D浮点数组的正向或反向离散余弦变换(DCT):

    • N个元素的一维向量的正余弦变换:

      Y = C ( N ) ⋅ X Y = C^{(N)} \cdot X Y=C(N)X,其中, C j k ( N ) = α j / N cos ⁡ ( π ( 2 k + 1 ) j 2 N ) C^{(N)}_{jk}= \sqrt{\alpha_j/N} \cos \left ( \frac{\pi(2k+1)j}{2N} \right ) Cjk(N)=αj/N cos(2Nπ(2k+1)j), α 0 = 1 \alpha_0=1 α0=1, α j = 2 \alpha_j=2 αj=2 for j > 0 j > 0 j>0

    • N个元素的一维向量的余弦逆变换:

      X = ( C ( N ) ) − 1 ⋅ Y = ( C ( N ) ) T ⋅ Y X = \left (C^{(N)} \right )^{-1} \cdot Y = \left (C^{(N)} \right )^T \cdot Y X=(C(N))1Y=(C(N))TY

      由于 C ( N ) C^{(N)} C(N)是正交矩阵, C ( N ) ⋅ ( C ( N ) ) T = I C^{(N)} \cdot \left(C^{(N)}\right)^T = I C(N)(C(N))T=I

    • M x N矩阵的正向2D余弦变换: Y = C ( N ) ⋅ X ⋅ ( C ( N ) ) T Y = C^{(N)} \cdot X \cdot \left (C^{(N)} \right )^T Y=C(N)X(C(N))T

    • M x N矩阵的2D余弦逆变换: X = ( C ( N ) ) T ⋅ X ⋅ C ( N ) X = \left (C^{(N)} \right )^T \cdot X \cdot C^{(N)} X=(C(N))TXC(N)

    该函数通过查看输入数组的flags和大小来选择操作模式:

    • 如果(flags&DCT_INVERSE)== 0,则该函数执行正向1D或2D转换。 否则,它是一维或二维逆变换。
    • 如果(flags&DCT_ROWS)!= 0,则该函数对每一行执行一维转换。
    • 如果数组是单列或单行,则该函数执行一维转换。
    • 如果以上条件都不成立,则该函数将执行2D转换。

    当前dct支持偶数大小的数组(2、4、6 …)。 对于数据分析和近似,可以在必要时填充阵列。 而且,函数性能在很大程度上取决于数组大小,而不是单调(请参见getOptimalDFTSize)。 在当前实现中,经由大小为N / 2的向量的DFT来计算大小为N的向量的DCT。 因此,最佳DCT大小N1> = N可以计算为:

    size_t getOptimalDCTSize(size_t N) { return 2*getOptimalDFTSize((N+1)/2); }
    N1 = getOptimalDCTSize(N);
    
    // 创建矩阵
    cv::Mat src(256,256,CV_32FC1);
    // 产生随机矩阵
    cv::randu(src,0,255);
    src.convertTo(src,CV_32FC1,1.0 / 255.0);
    cv::Mat dst;
    // 离散余弦变换
    cv::dct(src,dst);
    
    cv::imshow("src",src);
    cv::imshow("dst",dst);
    cv::waitKey();
    

    2)cv::idct:对1D或2D数组执行离散余弦变逆换。

    void cv::idct(InputArray src,OutputArray dst,int flags = 0)

    14、cv::determinant


    计算浮点类型方阵的行列式

    double cv::determinant(InputArray mtx)

    函数cv :: determinant计算并返回指定矩阵的行列式。 对于小型矩阵(mtx.cols = mtx.rows <= 3),使用直接方法。 对于较大的矩阵,该函数将LU分解与部分旋转配合使用。

    对于对称的正确定矩阵,也可以使用特征分解来计算行列式。

    // 创建矩阵
    float data[] = {1,2,3,4,5,6,7,8,9};
    
    cv::Mat src(3,3,CV_32FC1,data);
    
    // 计算行列式
    double res = cv::determinant(src);
    cout << "res = " << res << endl;
    

    15、cv::dft、cv::idft


    1)cv::dft:对1D或2D浮点数组执行正向或反向离散傅立叶变换。

    void cv::dft(InputArray src,OutputArray dst,int flags = 0,int nonzeroRows = 0)

    函数cv :: dft执行以下操作之一:

    • 对N个元素的一维向量进行傅立叶变换:

      Y = F ( N ) ⋅ X Y = F^{(N)} \cdot X Y=F(N)X,其中, F j k ( N ) = exp ⁡ ( − 2 π i j k / N ) F^{(N)}_{jk}=\exp(-2\pi i j k/N) Fjk(N)=exp(2πijk/N) i = − 1 i=\sqrt{-1} i=1

    • 对N个元素的一维向量进行傅立叶逆变换:

      X ′ = ( F ( N ) ) − 1 ⋅ Y = ( F ( N ) ) ∗ ⋅ y X = ( 1 / N ) ⋅ X , \begin{array}{l} X'= \left (F^{(N)} \right )^{-1} \cdot Y = \left (F^{(N)} \right )^* \cdot y \\ X = (1/N) \cdot X, \end{array} X=(F(N))1Y=(F(N))yX=(1/N)X,

      其中, F ∗ = ( Re ( F ( N ) ) − Im ( F ( N ) ) ) T F^*=\left(\textrm{Re}(F^{(N)})-\textrm{Im}(F^{(N)})\right)^T F=(Re(F(N))Im(F(N)))T

    • M x N矩阵的2D傅里叶变换: Y = F ( M ) ⋅ X ⋅ F ( N ) Y = F^{(M)} \cdot X \cdot F^{(N)} Y=F(M)XF(N)

    • 反转M x N矩阵的2D傅立叶变换:

      X ′ = ( F ( M ) ) ∗ ⋅ Y ⋅ ( F ( N ) ) ∗ X = 1 M ⋅ N ⋅ X ′ \begin{array}{l} X'= \left (F^{(M)} \right )^* \cdot Y \cdot \left (F^{(N)} \right )^* \\ X = \frac{1}{M \cdot N} \cdot X' \end{array} X=(F(M))Y(F(N))X=MN1X

    因此,该函数根据输入数组的flags和大小选择操作模式:

    • 如果设置了DFT_ROWS或输入数组具有单行或单列,则在设置DFT_ROWS时,该函数对矩阵的每一行执行一维正向或逆向变换。 否则,它将执行2D变换。
    • 如果输入数组为实数且未设置DFT_INVERSE,则该函数将执行正向1D或2D转换:
      • 设置DFT_COMPLEX_OUTPUT时,输出是与输入大小相同的复杂矩阵。
      • 如果未设置DFT_COMPLEX_OUTPUT,则输出为与输入大小相同的实数矩阵。 在2D转换的情况下,它使用如上所述的压缩格式。 如果是一个一维变换,则看起来像上面矩阵的第一行。 在进行多个一维转换的情况下(使用DFT_ROWS标志时),输出矩阵的每一行看起来都像上面矩阵的第一行。
    • 如果输入数组为复数,并且未设置DFT_INVERSE或DFT_REAL_OUTPUT,则输出为与输入大小相同的复数数组。 该函数根据标志DFT_INVERSE和DFT_ROWS独立地对整个输入数组或输入数组的每一行执行正向或反向1D或2D变换。
    • 当设置DFT_INVERSE且输入数组为实数,或者复杂但设置了DFT_REAL_OUTPUT时,输出为与输入大小相同的实数数组。 函数根据标志DFT_INVERSE和DFT_ROWS对整个输入数组或每个单独的行执行一维或二维逆变换。

    如果设置了DFT_SCALE,则缩放在转换后完成。

    与dct不同,该函数支持任意大小的数组。 但是,只有那些数组才能得到有效处理,其大小可以乘以较小质数(在当前实现中为2、3和5)的乘积来分解。 可以使用getOptimalDFTSize方法计算这种有效的DFT大小。

    // 获取最优大小
    cv::Mat padded;
    int m = cv::getOptimalDFTSize(I.rows);
    int n = cv::getOptimalDFTSize(I.cols);
    // 边缘填充
    cv::copyMakeBorder(I, padded, 0, m - I.rows, 0, n - I.cols, cv::BORDER_CONSTANT,cv:: Scalar::all(0));
    
    // 合并
    cv::Mat planes[] = { cv::Mat_<float>(padded), cv::Mat::zeros(padded.size(), CV_32F) };
    cv::Mat complexI;
    cv::merge(planes, 2, complexI);
    
    // 离散傅立叶变换
    cv::dft(complexI, complexI);
    
    // 计算幅度并切换到对数尺度
    // => log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
    cv::split(complexI, planes);                   // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
    cv::magnitude(planes[0], planes[1], planes[0]);// planes[0] = magnitude
    cv::Mat magI = planes[0];
    // 切换到对数尺度
    magI += cv::Scalar::all(1);
    cv::log(magI, magI);
    
    // 重新排列傅立叶图像的象限,使原点位于图像中心
    //int cx = magI.cols/2;
    //int cy = magI.rows/2;
    //cv::Mat q0(magI, cv::Rect(0, 0, cx, cy));
    //cv::Mat q1(magI, cv::Rect(cx, 0, cx, cy));
    //cv::Mat q2(magI, cv::Rect(0, cy, cx, cy));
    //cv::Mat q3(magI, cv::Rect(cx, cy, cx, cy));
    //cv::Mat tmp;
    //q0.copyTo(tmp);
    //q3.copyTo(q0);
    //tmp.copyTo(q3);
    //q1.copyTo(tmp);
    //q2.copyTo(q1);
    //tmp.copyTo(q2);
    
    // 规范化
    cv::normalize(magI, magI, 0, 1, cv::NORM_MINMAX);
    

    dft逆变换

    cv::dft(complexI, inverseTransform, cv::DFT_INVERSE|cv::DFT_REAL_OUTPUT);
    

    2)cv::idft:计算一维或二维数组的离散傅立叶逆变换。

    void cv::idft(InputArray src,OutputArray dst,int flags = 0,int nonzeroRows = 0)

    16、cv::divide、cv::multiply、cv::mulTransposed


    1)cv::divide:对两个数组或按数组的标量执行按元素的除法。

    void cv::divide(InputArray src1,InputArray src2,OutputArray dst,double scale = 1,int dtype = -1)

    • 将一个数组除以另一个: dst(I)   =   saturate(src1(I)*scale/src2(I)) \texttt{dst(I) = saturate(src1(I)*scale/src2(I))} dst(I) = saturate(src1(I)*scale/src2(I))
    • 没有src1时按数组标量: dst(I)   =   saturate(scale/src2(I)) \texttt{dst(I) = saturate(scale/src2(I))} dst(I) = saturate(scale/src2(I))

    多通道阵列的不同通道是独立处理的。对于src2(I)为零的整数类型,dst(I)也将为零。

    注意:对于浮点数据,对于零src2(I)值没有特殊定义的行为。 使用常规浮点除法。 期望浮点数据具有正确的IEEE-754行为(具有NaN,Inf结果值)。
    当输出数组的深度为CV_32S时,不应用饱和度。 在溢出的情况下,您甚至可能会得到错误符号的结果。

    // 创建矩阵
    float data1[] = {1,2,3,4,5,6,7,8,9};
    float data2[] = {1,3,5,7,9,11,13,15,17};
    cv::Mat src1(3,3,CV_32FC1,data1);
    cv::Mat src2(3,3,CV_32FC1,data2);
    
    // 除法运算
    // 矩阵之间除法运算
    cv::Mat dst;
    cv::divide(src1,src2,dst);
    cout << "dst = " << dst << endl;
    
    // 与标量除法运算
    cv::divide(1,src2,dst);
    cout << "dst = " << dst << endl;
    

    2)cv::multiply:计算两个数组的按元素缩放的乘积。

    void cv::multiply(InputArray src1,InputArray src2,OutputArray dst,double scale = 1,int dtype = -1)

    函数乘法计算两个数组的每个元素的乘积: dst ( I ) = saturate ( scale ⋅ src1 ( I ) ⋅ src2 ( I ) ) \texttt{dst} (I)= \texttt{saturate} ( \texttt{scale} \cdot \texttt{src1} (I) \cdot \texttt{src2} (I)) dst(I)=saturate(scalesrc1(I)src2(I))

    3)cv::mulTransposed

    计算矩阵的乘积及其转置。

    void cv::mulTransposed(InputArray src,OutputArray dst,bool aTa,InputArray delta = noArray(),double scale = 1,int dtype = -1)

    函数cv :: mulTransposed计算src及其转置的乘积:

    • dst = scale ( src − delta ) T ( src − delta ) \texttt{dst} = \texttt{scale} ( \texttt{src} - \texttt{delta} )^T ( \texttt{src} - \texttt{delta} ) dst=scale(srcdelta)T(srcdelta)
    • 当aTa=true, dst = scale ( src − delta ) ( src − delta ) T \texttt{dst} = \texttt{scale} ( \texttt{src} - \texttt{delta} ) ( \texttt{src} - \texttt{delta} )^T dst=scale(srcdelta)(srcdelta)T

    除此以外。 该函数用于计算协方差矩阵。 增量为零时,当B = A’时,它可用作通用矩阵乘积A * B的更快替代品

    17、cv::eigen、cv::eigenNonSymmetric


    1)cv::eigen:计算对称矩阵的特征值和特征向量。

    bool cv::eigen(InputArray src,OutputArray eigenvalues,OutputArray eigenvectors = noArray())

    函数cv :: eigen仅计算对称矩阵src的特征值或特征值和特征向量:

    src*eigenvectors.row(i).t() = eigenvalues.at<srcType>(i)*eigenvectors.row(i).t()
    
    // 创建矩阵
    float data[] = {
            1,2,3,
            2,1,2,
            3,2,1
        };
    cv::Mat src(3,3,CV_32FC1,data);
    
    // 计算对称矩阵特征值
    cv::Mat eigenValues,eigenVector;
    cv::eigen(src,eigenValues,eigenVector);
    cout << "eigen values = " << eigenValues << endl;
    cout << "eigen vectors = " << eigenValues << endl;
    

    2)cv::eigenNonSymmetric:计算非对称矩阵的特征值和特征向量(仅真实特征值)。

    void cv::eigenNonSymmetric (InputArray src,OutputArray eigenvalues,OutputArray eigenvectors)

    该函数计算方阵src的特征值和特征向量(可选):

    src*eigenvectors.row(i).t() = eigenvalues.at<srcType>(i)*eigenvectors.row(i).t()
    
    // 创建矩阵
    float data2[] = {1,3,5,7,9,11,13,15,17};
    cv::Mat src2(3,3,CV_32FC1,data2);
    cv::eigenNonSymmetric(src,eigenValues,eigenVector);
    cout << "eigen values = " << eigenValues << endl;
    cout << "eigen vectors = " << eigenValues << endl;
    

    18、cv::exp、cv::pow、cv::sqrt、cv::subtract、cv::sum


    1)cv::exp:计算每个数组元素的指数。

    void cv::exp(InputArray src,OutputArray dst)

    函数cv :: exp计算输入数组中每个元素的指数: dst [ I ] = e s r c ( I ) \texttt{dst} [I] = e^{ src(I) } dst[I]=esrc(I)

    单精度输入的最大相对误差约为7e-6,双精度输入的最大相对误差小于1e-10。 当前,该函数将输出的非规格化值转换为零。 不处理特殊值(NaN,Inf)。

    2)cv::pow:将每个数组元素提升为幂。

    void cv::pow(InputArray src,double power,OutputArray dst)

    函数cv :: pow将输入数组的每个元素提升为power:

    dst ( I ) = { src ( I ) p o w e r i f ( power ) i s i n t e g e r ∣ src ( I ) ∣ p o w e r o t h e r w i s e \texttt{dst} (I) = \begin{cases}{\texttt{src}(I)^{power}}{if (\texttt{power}) is integer}\\{|\texttt{src}(I)|^{power}}{otherwise}\end{cases} dst(I)={src(I)powerif(power)isintegersrc(I)powerotherwise

    3)cv::sqrt:计算数组元素的平方根。

    void cv::sqrt(InputArray src,OutputArray dst)

    函数cv :: sqrt计算每个输入数组元素的平方根。 在多通道阵列的情况下,每个通道都是独立处理的。 精度与内置std :: sqrt大致相同。

    4)cv::subtract:计算两个数组或数组与标量之间的每个元素的差。

    void cv::subtract(InputArray src1,InputArray src2,OutputArray dst,InputArray mask = noArray(),int dtype = -1)

    函数减法计算:

    • 当两个输入数组具有相同的大小和相同的通道数时,两个数组之间的差异: dst ( I ) = saturate ( src1 ( I ) − src2 ( I ) ) if   mask ( I ) ≠ 0 \texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) - \texttt{src2}(I)) \quad \texttt{if mask}(I) \ne0 dst(I)=saturate(src1(I)src2(I))if mask(I)=0
    • 当src2由Scalar构造或与src1.channels()具有相同数量的元素时,数组与标量之间的差异: dst ( I ) = saturate ( src1 ( I ) − src2 ) if   mask ( I ) ≠ 0 \texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) - \texttt{src2} ) \quad \texttt{if mask}(I) \ne0 dst(I)=saturate(src1(I)src2)if mask(I)=0
    • 当src1由Scalar构造或与src2.channels()具有相同数量的元素时,标量和数组之间的差异: dst ( I ) = saturate ( src1 − src2 ( I ) ) if   mask ( I ) ≠ 0 \texttt{dst}(I) = \texttt{saturate} ( \texttt{src1} - \texttt{src2}(I) ) \quad \texttt{if mask}(I) \ne0 dst(I)=saturate(src1src2(I))if mask(I)=0
    • 在SubRS情况下,标量和数组之间的反差: dst ( I ) = saturate ( src2 − src1 ( I ) ) if   mask ( I ) ≠ 0 \texttt{dst}(I) = \texttt{saturate} ( \texttt{src2} - \texttt{src1}(I) ) \quad \texttt{if mask}(I) \ne0 dst(I)=saturate(src2src1(I))if mask(I)=0

    其中,我是数组元素的多维索引。 在多通道阵列的情况下,每个通道都是独立处理的。
    上面列表中的第一个函数可以替换为矩阵表达式:

    dst = src1 - src2;
    dst -= src1; // equivalent to subtract(dst, src1, dst);
    

    输入阵列和输出阵列都可以具有相同或不同的深度。 例如,您可以减去8位无符号数组,并将差值存储在16位有符号数组中。 输出数组的深度由dtype参数确定。 在上面的第二种和第三种情况以及第一种情况下,当src1.depth()== src2.depth()时,dtype可以设置为默认值-1。 在这种情况下,输出数组将具有与输入数组相同的深度,无论是src1,src2还是两者。

    5)cv::sum:计算数组元素的总和。

    Scalar cv::sum(InputArray src)

    函数cv :: sum针对每个通道独立计算并返回数组元素的总和。

    19、cv::extractChannel、cv::insertChannel


    1)cv::extractChannel:从src提取单个通道(coi是从0开始的索引)

    void cv::extractChannel(InputArray src,OutputArray dst,int coi)

    cv::Mat src = cv::imread("resources/images/f1.jpg");
    cv::Mat blue;
    cv::extractChannel(src,blue,0);
    cv::imshow("src",src);
    cv::imshow("blue",blue);
    cv::waitKey();
    

    2)cv::insertChannel:将单个通道插入目标矩阵或数组(coi是从0开始的索引)

    void cv::insertChannel(InputArray src,OutputArray dst,int coi)

    20、cv::findNonZero


    计算非零像素位置的列表。

    void cv::findNonZero(InputArray src,OutputArray idx)

    // 创建矩阵
    float data[] = {127,64,0,
                         0,0,0,
                         16,8,0};
    cv::Mat binaryImage(3,3,CV_32FC1,data);
    // 非零元素位置
    cv::Mat locations;
    cv::findNonZero(binaryImage, locations);
    // 访问位置
    // cv::Point pnt = locations.at<cv::Point>(i);
    cout << "locations = " << locations << endl;
    

    21、cv::flip、cv::rotate


    1)cv::flip:围绕垂直轴,水平轴或两个轴翻转2D数组。

    void cv::flip(InputArray src,OutputArray dst,int flipCode)

    函数cv :: flip以三种不同的方式之一翻转数组(行和列索引均基于0):

    dst i j = { src src.rows − i − 1 , j i f    flipCode = 0 src i , src.cols − j − 1 i f    flipCode > 0 src src.rows − i − 1 , src.cols − j − 1 i f    flipCode < 0 \texttt{dst} _{ij} = \left\{ \begin{array}{l l} \texttt{src} _{\texttt{src.rows}-i-1,j} & if\; \texttt{flipCode} = 0 \\ \texttt{src} _{i, \texttt{src.cols} -j-1} & if\; \texttt{flipCode} > 0 \\ \texttt{src} _{ \texttt{src.rows} -i-1, \texttt{src.cols} -j-1} & if\; \texttt{flipCode} < 0 \\ \end{array} \right. dstij=srcsrc.rowsi1,jsrci,src.colsj1srcsrc.rowsi1,src.colsj1ifflipCode=0ifflipCode>0ifflipCode<0

    // 创建矩阵
    float data[] = {127,64,0,
                         0,0,0,
                         16,8,0};
    cv::Mat src(3,3,CV_32FC1,data);
    // 翻转矩阵
    cv::Mat dst;
    cv::flip(src, dst,0);
    // 访问位置
    // cv::Point pnt = locations.at<cv::Point>(i);
    cout << "locations = " << dst << endl;
    

    2)cv::rotate:以90度的倍数旋转2D阵列

    void cv::rotate(InputArray src,int rotateCode)

    函数cv :: rotate以三种不同的方式之一旋转数组:顺时针旋转90度(rotateCode = ROTATE_90_CLOCKWISE)。 顺时针旋转180度(rotateCode = ROTATE_180)。 顺时针旋转270度(rotateCode = ROTATE_90_COUNTERCLOCKWISE)。

    22、cv::gemm


    广义矩阵乘法。

    void cv::gemm(InputArray src1,InputArray src2,double alpha,InputArray src3,double beta,OutputArray dst,int flags = 0)

    函数cv :: gemm执行类似于BLAS 3级中的gemm函数的广义矩阵乘法。例如,gemm(src1,src2,alpha,src3,beta,dst,GEMM_1_T + GEMM_3_T对应于

    dst = alpha ⋅ src1 T ⋅ src2 + beta ⋅ src3 T \texttt{dst} = \texttt{alpha} \cdot \texttt{src1} ^T \cdot \texttt{src2} + \texttt{beta} \cdot \texttt{src3} ^T dst=alphasrc1Tsrc2+betasrc3T

    对于复杂(两通道)数据,请执行复杂矩阵乘法。

    该函数可以替换为矩阵表达式。 例如,上述调用可以替换为:

    dst = alpha*src1.t()*src2 + beta*src3.t();
    
    cv::Mat   T;
    cv::Mat   A=cv::Mat::eye(1,3,CV_32FC1);
    cv::Mat   C=cv::Mat::eye(3,3,CV_32FC1);
    std::cout<<"A="<<A<<std::endl<<"C="<<C<<std::endl;
    cv::gemm(A,C,1,10,0,T,0);//the src3 can't be 0,so if you
    //want to ignore the src3,
    //you should set the b  eater as 0
    std::cout<<"T="<<T;
    

    23、cv::getOptimalDFTSize


    返回给定向量大小的最佳DFT大小。

    DFT性能不是矢量大小的单调函数。 因此,当您计算两个数组的卷积或对一个数组执行光谱分析时,通常有意义的是用零填充输入数据以获得更大的数组,该数组可以比原始数组快得多的速度转换。 大小为2的幂(2、4、8、16、32,…)的阵列处理速度最快。 但是,大小为2、3和5的乘积(例如300 = 5 * 5 * 3 * 2 * 2)的数组也可以得到非常有效的处理。

    函数cv :: getOptimalDFTSize返回大于或等于vecsize的最小值N,以便可以有效处理大小为N的向量的DFT。 在当前实现中,对于一些整数p,q,r,N = 2 ^ p ^ * 3 ^ q ^ * 5 ^ r ^。

    如果vecsize太大(非常接近INT_MAX),则该函数返回负数。

    尽管该函数不能直接用于估计DCT变换的最佳矢量大小(由于当前的DCT实现仅支持偶数大小的矢量),但可以轻松地将其处理为getOptimalDFTSize((vecsize + 1)/ 2)* 2。

    24、cv::hconcat、cv::vconcat


    1)cv::hconcat:水平方向串联应用于给定矩阵。

    void cv::hconcat(const Mat * src,size_t nsrc,OutputArray dst)

    cv::Mat matArray[] = { cv::Mat(4, 1, CV_8UC1, cv::Scalar(1)),
                           cv::Mat(4, 1, CV_8UC1, cv::Scalar(2)),
                           cv::Mat(4, 1, CV_8UC1, cv::Scalar(3)),};
    cv::Mat out;
    cv::hconcat( matArray, 3, out );
    

    2)cv::vconcat:垂直方向串联应用于给定矩阵。

    void cv::vconcat(const Mat * src,size_t nsrc,OutputArray dst)

    cv::Mat matArray[] = { cv::Mat(4, 1, CV_8UC1, cv::Scalar(1)),
                           cv::Mat(4, 1, CV_8UC1, cv::Scalar(2)),
                           cv::Mat(4, 1, CV_8UC1, cv::Scalar(3)),};
    cv::Mat out;
    cv::vconcat( matArray, 3, out );
    

    25、cv::inRange


    检查数组元素是否位于其他两个数组的元素之间。

    void cv::inRange(InputArray src,InputArray lowerb,InputArray upperb,OutputArray dst)

    该函数检查范围如下:

    • 对于单通道输入数组的每个元素: dst ( I ) = lowerb ( I ) 0 ≤ src ( I ) 0 ≤ upperb ( I ) 0 \texttt{dst} (I)= \texttt{lowerb} (I)_0 \leq \texttt{src} (I)_0 \leq \texttt{upperb} (I)_0 dst(I)=lowerb(I)0src(I)0upperb(I)0
    • 对于两通道矩阵: dst ( I ) = lowerb ( I ) 0 ≤ src ( I ) 0 ≤ upperb ( I ) 0 ∧ lowerb ( I ) 1 ≤ src ( I ) 1 ≤ upperb ( I ) 1 \texttt{dst} (I)= \texttt{lowerb} (I)_0 \leq \texttt{src} (I)_0 \leq \texttt{upperb} (I)_0 \land \texttt{lowerb} (I)_1 \leq \texttt{src} (I)_1 \leq \texttt{upperb} (I)_1 dst(I)=lowerb(I)0src(I)0upperb(I)0lowerb(I)1src(I)1upperb(I)1等等。

    也就是说,如果src(I)在指定的1D,2D,3D,…框内,则dst(I)设置为255(全1位),否则设置为0。

    当下边界参数和/或上边界参数为标量时,应忽略上述公式中lowerb和upperb的索引(I)。

    cv::Mat src = cv::imread("resources/images/f1.jpg",0);
    cv::Mat dst;
    cv::inRange(src,cv::Scalar(120, 120, 120), cv::Scalar(200, 200, 200),dst);
    cv::imshow("src",src);
    cv::imshow("dst",dst);
    cv::waitKey();
    

    26、cv::invert

    查找矩阵的逆或伪逆。

    double cv::invert(InputArray src,OutputArray dst,int flags = DECOMP_LU)

    函数cv :: invert反转矩阵src并将结果存储在dst中。 当矩阵src是奇异或非正方形时,该函数计算伪逆矩阵(dst矩阵),以便norm(src * dst-I)最小,其中I是一个单位矩阵。

    在使用DECOMP_LU方法的情况下,如果成功计算了反函数,则函数返回非零值;如果src为奇数,则函数返回0。

    在DECOMP_SVD方法的情况下,该函数返回src的逆条件数(最小奇异值与最大奇异值之比),如果src为奇异,则返回0。 如果src是奇异的,则SVD方法将计算伪逆矩阵。

    与DECOMP_LU相似,方法DECOMP_CHOLESKY仅适用于也应对称且定义明确的非奇异方阵。 在这种情况下,函数将倒置矩阵存储在dst中,并返回非零值。 否则,它返回0。

    // 创建矩阵
    float data[] = {1,2,3,4,5,6,7,8,9};
    cv::Mat src(3,3,CV_32FC1,data);
    
    // 求矩阵的逆或伪逆
    cv::Mat dst;
    cv::invert(src,dst);
    cout << "dst = " << dst << endl;
    

    27、cv::log


    计算每个数组元素的自然对数。

    void cv::log(InputArray src,OutputArray dst)

    函数cv :: log计算输入数组中每个元素的自然对数: dst ( I ) = log ⁡ ( src ( I ) ) \texttt{dst} (I) = \log (\texttt{src}(I)) dst(I)=log(src(I))

    未定义零,负和特殊(NaN,Inf)值的输出。

    28、cv::LUT


    对数组执行查找表转换。

    void cv::LUT(InputArray src,InputArray lut,OutputArray dst)

    函数LUT用查询表中的值填充输出数组。 条目的索引取自输入数组。 也就是说,该函数按以下方式处理src的每个元素:

    dst ( I ) ← lut(src(I)   +   d) \texttt{dst} (I) \leftarrow \texttt{lut(src(I) + d)} dst(I)lut(src(I) + d)

    ,其中:

    KaTeX parse error: Expected '}', got '_' at position 55: … depth \text{CV_̲8U} \\ 128 & if…

    uchar table[256];
    for (int i = 0; i < 256; ++i)
        table[i] = (uchar)(4 * (i/4));
    cv::Mat src = cv::imread("resources/images/f1.jpg");
    cv::Mat dst;
    cv::Mat lut(1,256,CV_8UC3,table);
    cv::LUT(src,lut,dst);
    cv::imshow("src",src);
    cv::imshow("dst",dst);
    cv::waitKey();
    

    29、cv::magnitude


    计算2D向量的量纲。

    void cv::magnitude(InputArray x,InputArray y,OutputArray magnitude)

    函数cv :: magnitude计算由x和y数组的相应元素形成的2D向量的量纲:

    dst ( I ) = x ( I ) 2 + y ( I ) 2 \texttt{dst} (I) = \sqrt{\texttt{x}(I)^2 + \texttt{y}(I)^2} dst(I)=x(I)2+y(I)2

    // 创建矩阵
    float datax[] = {1,2,3,4,5,6,7,8,9};
    float data2[] = {1,3,5,7,9,11,13,15,17};
    cv::Mat srcx(3,3,CV_32FC1,datax);
    cv::Mat srcy(3,3,CV_32FC1,data2);
    
    // 计算2D向量的量纲
    cv::Mat dst;
    cv::magnitude(srcx,srcy,dst);
    cout << "magnitude = " << dst << endl;
    

    30、cv::Mahalanobis


    计算两个矩阵的马氏距离(Mahalanobis Distance)。

    double cv::Mahalanobis(InputArray v1,InputArray v2,InputArray icovar)

    函数cv :: Mahalanobis计算并返回两个向量之间的加权距离:

    d ( vec1 , vec2 ) = ∑ i , j icovar(i,j) ⋅ ( vec1 ( I ) − vec2 ( I ) ) ⋅ ( vec1(j) − vec2(j) ) d( \texttt{vec1} , \texttt{vec2} )= \sqrt{\sum_{i,j}{\texttt{icovar(i,j)}\cdot(\texttt{vec1}(I)-\texttt{vec2}(I))\cdot(\texttt{vec1(j)}-\texttt{vec2(j)})} } d(vec1,vec2)=i,jicovar(i,j)(vec1(I)vec2(I))(vec1(j)vec2(j))

    可以使用calcCovarMatrix函数计算协方差矩阵,然后使用求反函数(最好是使用DECOMP_SVD方法,最精确的求逆函数)求逆。

    //2行5列
    Mat Pt(2, 5, CV_64FC1);
    Pt.at<double>(0, 0) = 2;
    Pt.at<double>(1, 0) = 4;
    
    Pt.at<double>(0, 1) = 2;
    Pt.at<double>(1, 1) = 2;
    
    Pt.at<double>(0, 2) = 3;
    Pt.at<double>(1, 2) = 3;
    
    Pt.at<double>(0, 3) = 4;
    Pt.at<double>(1, 3) = 4;
    
    Pt.at<double>(0, 4) = 4;
    Pt.at<double>(1, 4) = 2;
    cout << Pt << endl;
    
    //计算协方差矩阵
    Mat coVar, meanVar;
    calcCovarMatrix(Pt, coVar, meanVar, COVAR_NORMAL|COVAR_COLS);
    cout << "Covar is:\n" << coVar << endl;
    cout << "Mean is:\n" << meanVar << endl;
    //计算协方差的逆
    Mat iCovar;
    invert(coVar, iCovar, DECOMP_SVD);
    
    Mat pt1(2, 1, CV_64FC1);
    Mat pt2(2, 1, CV_64FC1);
    pt1.at<double>(0, 0) = 1;
    pt1.at<double>(1, 0) = 1;
    pt2.at<double>(0, 0) = 5;
    pt2.at<double>(1, 0) = 5;
    
    double Maha1 = Mahalanobis(pt1, meanVar, iCovar);
    double Maha2 = Mahalanobis(pt2, meanVar, iCovar);
    cout << "Maha distance 1:\t" << Maha1 << endl;
    cout << "Maha distance 2:\t" << Maha2 << endl;
    

    31、cv::max、cv::min


    1)cv::max:函数cv :: max计算两个数组的每个元素的最大值。

    void cv::max(InputArray src1,InputArray src2,OutputArray dst)

    • 当src1、src2为相同尺度的数组时: dst ( I ) = max ⁡ ( src1 ( I ) , src2 ( I ) ) \texttt{dst} (I)= \max ( \texttt{src1} (I), \texttt{src2} (I)) dst(I)=max(src1(I),src2(I))
    • 当src1或src2为标量时: dst ( I ) = max ⁡ ( src1 ( I ) , value ) \texttt{dst} (I)= \max ( \texttt{src1} (I), \texttt{value} ) dst(I)=max(src1(I),value)

    1)cv::min:函数cv :: max计算两个数组的每个元素的最小值。

    void cv::min(InputArray src1,InputArray src2,OutputArray dst)

    // 创建矩阵
    float data1[] = {1,2,3,4,5,6,7,8,9};
    float data2[] = {1,3,5,7,9,11,13,15,17};
    cv::Mat src1(3,3,CV_32FC1,data1);
    cv::Mat src2(3,3,CV_32FC1,data2);
    
    // 计算两个数组的最大值
    cv::Mat dst;
    // 数组间计算
    cv::max(src1,src2,dst);
    cout << "max = " << dst << endl;
    // 标量间计算
    cv::max(src1,5,dst);
    cout << "max = " << dst << endl;
    
    // 计算两个数组最小值
    cv::min(src1,src2,dst);
    cout << "min = " << dst << endl;
    cv::min(src1,5,dst);
    cout << "min = " << dst << endl;
    

    32、cv::mean、cv::meanStdDev


    1)cv::mean:计算数组元素的平均值(均值)。

    Scalar cv::mean (InputArray src,InputArray mask = noArray())

    函数cv :: mean独立于每个通道计算数组元素的平均值M,然后将其返回:

    N = ∑ I :    mask ( I ) ≠ 0 1 M c = ( ∑ I :    mask ( I ) ≠ 0 mtx ( I ) c ) / N \begin{array}{l} N = \sum _{I: \; \texttt{mask} (I) \ne 0} 1 \\ M_c = \left ( \sum _{I: \; \texttt{mask} (I) \ne 0}{ \texttt{mtx} (I)_c} \right )/N \end{array} N=I:mask(I)=01Mc=(I:mask(I)=0mtx(I)c)/N

    当所有mask元素均为0时,该函数返回Scalar :: all(0)

    // 创建矩阵
    float data1[] = {1,2,3,4,5,6,7,8,9};
    float data2[] = {1,3,5,7,9,11,13,15,17};
    cv::Mat src1(3,3,CV_32FC1,data1);
    cv::Mat src2(3,3,CV_32FC1,data2);
    
    // 计算均值
    cv::Scalar result = cv::mean(src1);
    cout << "mean = " << result << endl;
    result = cv::mean(src2);
    cout << "mean = " << result << endl;
    

    2)cv::meanStdDev:计算数组元素的均值和标准差。

    void cv::meanStdDev(InputArray src,OutputArray mean,OutputArray stddev,InputArray mask = noArray())

    函数cv :: meanStdDev为每个通道独立计算数组元素的平均值和标准偏差M,并通过输出参数返回:

    N = ∑ I , mask ( I ) ≠ 0 1 mean c = ∑ I :    mask ( I ) ≠ 0 src ( I ) c N stddev c = ∑ I :    mask ( I ) ≠ 0 ( src ( I ) c − mean c ) 2 N \begin{array}{l} N = \sum _{I, \texttt{mask} (I) \ne 0} 1 \\ \texttt{mean} _c = \frac{\sum_{ I: \; \texttt{mask}(I) \ne 0} \texttt{src} (I)_c}{N} \\ \texttt{stddev} _c = \sqrt{\frac{\sum_{ I: \; \texttt{mask}(I) \ne 0} \left ( \texttt{src} (I)_c - \texttt{mean} _c \right )^2}{N}} \end{array} N=I,mask(I)=01meanc=NI:mask(I)=0src(I)cstddevc=NI:mask(I)=0(src(I)cmeanc)2

    当所有mask元素均为0时,该函数返回Scalar :: all(0)

    // 创建矩阵
    float data1[] = {1,2,3,4,5,6,7,8,9};
    float data2[] = {1,3,5,7,9,11,13,15,17};
    cv::Mat src1(3,3,CV_32FC1,data1);
    cv::Mat src2(3,3,CV_32FC1,data2);
    
    cv::Mat resultMean,resultStdDev;
    cv::meanStdDev(src1,resultMean,resultStdDev);
    cout << "mean = " << resultMean << ",stddev = " << resultStdDev << endl;
    

    33、cv::merge、cv::split、cv::mixChannels


    1)cv::split:将多个单通道矩阵合并成一个多通道矩阵。

    void cv::merge(const Mat * mv,size_t count,OutputArray dst)

    函数cv :: merge合并多个数组以组成单个多通道数组。 也就是说,输出数组的每个元素都是输入数组的元素的串联,其中第i个输入数组的元素被视为mv [i] .channels()-元素向量。

        Mat m1 = (Mat_<uchar>(2,2) << 1,4,7,10);
        Mat m2 = (Mat_<uchar>(2,2) << 2,5,8,11);
        Mat m3 = (Mat_<uchar>(2,2) << 3,6,9,12);
        Mat channels[3] = {m1, m2, m3};
        Mat m;
        merge(channels, 3, m);
        /*
        m =
        [  1,   2,   3,   4,   5,   6;
           7,   8,   9,  10,  11,  12]
        m.channels() = 3
        */
    

    2)cv::split:将一个多通道矩阵拆分成多个单通道矩阵。

    void cv::split(const Mat & src,Mat * mvbegin)

    函数cv :: split将多通道数组拆分为单独的单通道数组: mv [ c ] ( I ) = src ( I ) c \texttt{mv} [c](I) = \texttt{src} (I)_c mv[c](I)=src(I)c

    如果您需要提取单个通道或进行其他一些复杂的通道置换,请使用mixChannels。

    // 创建矩阵
        float data1[] = {1,2,3,4,5,6,7,8,9};
        float data2[] = {1,3,5,7,9,11,13,15,17};
        cv::Mat src1(3,3,CV_32FC1,data1);
        cv::Mat src2(3,3,CV_32FC1,data2);
    
        cv::Mat srcs[] = {src1,src2};
    
        // 矩阵合并
        cv::Mat merged;
        cv::merge(srcs,2,merged);
        cout << "merged = \n" << format(merged, cv::Formatter::FMT_PYTHON) << endl;
    
        // 矩阵拆分
        std::vector<cv::Mat> channels;
        cv::split(merged,channels);
        cout << "channels[0] = \n" << format(channels[0], cv::Formatter::FMT_PYTHON) << endl;
        cout << "channels[1] = \n" << format(channels[1], cv::Formatter::FMT_PYTHON) << endl;
    
    

    3)、cv::mixChannels:函数cv :: mixChannels提供了用于改组图像通道的高级机制。

    void cv::mixChannels(const Mat * src,size_t nsrcs,Mat * dst,size_t ndsts,size_t npairs)

    Mat bgra( 100, 100, CV_8UC4, Scalar(255,0,0,255) );
    Mat bgr( bgra.rows, bgra.cols, CV_8UC3 );
    Mat alpha( bgra.rows, bgra.cols, CV_8UC1 );
    // forming an array of matrices is a quite efficient operation,
    // because the matrix data is not copied, only the headers
    Mat out[] = { bgr, alpha };
    // bgra[0] -> bgr[2], bgra[1] -> bgr[1],
    // bgra[2] -> bgr[0], bgra[3] -> alpha[0]
    int from_to[] = { 0,2, 1,1, 2,0, 3,3 };
    mixChannels( &bgra, 1, out, 2, from_to, 4 );
    

    34、cv::mulSpectrums


    执行两个傅立叶频谱的逐元素乘法。

    void cv::mulSpectrums(InputArray a,InputArray b,int flags,bool conjB = false)

    函数cv :: mulSpectrums执行两个CCS-pakaged或复杂矩阵的逐元素乘法,这两个矩阵是实际或复杂傅立叶变换的结果。

    该函数与dft和idft一起可用于快速计算两个数组的卷积(pass conjB = false)或相关性(pass conjB = true)。 当数组很复杂时,只需将它们与第二个数组元素的可选共轭简单地相乘(每个元素)。 当数组为实数时,假定它们是CCS-pakaged的(有关详细信息,请参阅dft)。

    #include <iostream>
    #include <opencv2/opencv.hpp>
    
    using namespace cv;
    using namespace std;
    
    //http://docs.opencv.org/modules/core/doc/operations_on_arrays.html#dft[2]
    void convolveDFT(Mat A, Mat B, Mat& C)
    {
        // 重新配置空间给输出数组
        C.create(abs(A.rows - B.rows)+1, abs(A.cols - B.cols)+1, A.type());
        Size dftSize;
        // 计算最优DFT大小
        dftSize.width = getOptimalDFTSize(A.cols + B.cols - 1);
        dftSize.height = getOptimalDFTSize(A.rows + B.rows - 1);
    
        // allocate temporary buffers and initialize them with 0's
        Mat tempA(dftSize, A.type(), Scalar::all(0));
        Mat tempB(dftSize, B.type(), Scalar::all(0));
    
        // copy A and B to the top-left corners of tempA and tempB, respectively
        Mat roiA(tempA, Rect(0,0,A.cols,A.rows));
        A.copyTo(roiA);
        Mat roiB(tempB, Rect(0,0,B.cols,B.rows));
        B.copyTo(roiB);
    
        // now transform the padded A & B in-place;
        // use "nonzeroRows" hint for faster processing
        dft(tempA, tempA, 0, A.rows);
        dft(tempB, tempB, 0, B.rows);
    
        // multiply the spectrums;
        // the function handles packed spectrum representations well
        mulSpectrums(tempA, tempB, tempA, DFT_COMPLEX_OUTPUT);
        //mulSpectrums(tempA, tempB, tempA, DFT_REAL_OUTPUT);
    
        // transform the product back from the frequency domain.
        // Even though all the result rows will be non-zero,
        // you need only the first C.rows of them, and thus you
        // pass nonzeroRows == C.rows
        dft(tempA, tempA, DFT_INVERSE + DFT_SCALE, C.rows);
    
        // now copy the result back to C.
        tempA(Rect(0, 0, C.cols, C.rows)).copyTo(C);
    
        // all the temporary buffers will be deallocated automatically
    }
    
    
    int main(int argc, char* argv[])
    {
        const char* filename = "resources/images/f1.jpg";
    
        Mat I = imread(filename, 0);
        if( I.empty())
            return -1;
    
        Mat kernel = (Mat_<float>(3,3) << 1, 1, 1, 1, 1, 1, 1, 1, 1);
        cout << kernel;
    
        Mat floatI = Mat_<float>(I);// change image type into float
        Mat filteredI;
        convolveDFT(floatI, kernel, filteredI);
    
        normalize(filteredI, filteredI, 0, 1, cv::NORM_MINMAX); // Transform the matrix with float values into a
                                                // viewable image form (float between values 0 and 1).
        imshow("image", I);
        imshow("filtered", filteredI);
        waitKey(0);
    
    }
    

    35、cv::norm


    计算数组的绝对范数。

    double cv::norm (InputArray src1,int normType = NORM_L2,InputArray mask = noArray())

    此版本的规范计算src1的绝对规范。 使用NormTypes指定要计算的范式类型:

    • NORM_INF :

      KaTeX parse error: Expected '}', got '_' at position 123: … = \texttt{NORM_̲INF} ) } \\ {\|…

    • NORM_L1 :

      KaTeX parse error: Expected '}', got '_' at position 119: … = \texttt{NORM_̲L1} )} \\{ \| \…

    • NORM_L2 :

      KaTeX parse error: Expected '}', got '_' at position 125: … = \texttt{NORM_̲L2} ) } \\{ \| …

    • NORM_L2SQR:

      KaTeX parse error: Expected '}', got '_' at position 123: … = \texttt{NORM_̲L2SQR} )}\\ { \…

    • NORM_HAMMING :对于一个输入数组,从零开始计算该数组的汉明距离;对于两个输入数组,在两个数组之间,计算汉明距离。

    • NORM_HAMMING2 :与NORM_HAMMING相似,但是在计算中,输入序列的每两位将被添加并视为一个位,以便与NORM_HAMMING进行相同的计算。

    • NORM_TYPE_MASK :位掩码,可用于将规范类型与规范标志分开

    • NORM_RELATIVE :标志

    • NORM_MINMAX :标志

    36、cv::normalize


    规范数组的范数或值范围。

    函数cv :: normalize标准化比例尺并移动输入数组元素:

    ∥ dst ∥ L p = alpha \| \texttt{dst} \| _{L_p}= \texttt{alpha} dstLp=alpha

    (其中p = Inf,1或2)分别在normType = NORM_INF,NORM_L1或NORM_L2时:

    min ⁡ I dst ( I ) = alpha ,    max ⁡ I dst ( I ) = beta \min _I \texttt{dst} (I)= \texttt{alpha} , \, \, \max _I \texttt{dst} (I)= \texttt{beta} minIdst(I)=alpha,maxIdst(I)=beta

    当normType = NORM_MINMAX(仅适用于密集阵列)时。 可选的掩码指定要标准化的子数组。 这意味着在子数组上计算了范数或min-n-max,然后修改了该子数组以进行标准化。 如果只想使用掩码来计算范数或最小最大值,而要修改整个数组,则可以使用范数和Mat :: convertTo。

    不允许对稀疏矩阵进行范围转换。

    vector<double> positiveData = { 2.0, 8.0, 10.0 };
    vector<double> normalizedData_l1, normalizedData_l2, normalizedData_inf, normalizedData_minmax;
    // Norm to probability (total count)
    // sum(numbers) = 20.0
    // 2.0      0.1     (2.0/20.0)
    // 8.0      0.4     (8.0/20.0)
    // 10.0     0.5     (10.0/20.0)
    normalize(positiveData, normalizedData_l1, 1.0, 0.0, NORM_L1);
    // Norm to unit vector: ||positiveData|| = 1.0
    // 2.0      0.15
    // 8.0      0.62
    // 10.0     0.77
    normalize(positiveData, normalizedData_l2, 1.0, 0.0, NORM_L2);
    // Norm to max element
    // 2.0      0.2     (2.0/10.0)
    // 8.0      0.8     (8.0/10.0)
    // 10.0     1.0     (10.0/10.0)
    normalize(positiveData, normalizedData_inf, 1.0, 0.0, NORM_INF);
    // Norm to range [0.0;1.0]
    // 2.0      0.0     (shift to left border)
    // 8.0      0.75    (6.0/8.0)
    // 10.0     1.0     (shift to right border)
    normalize(positiveData, normalizedData_minmax, 1.0, 0.0, NORM_MINMAX);
    

    37、cv::perspectiveTransform、cv::getPerspectiveTransform、cv::warpPerspective


    1)cv::perspectiveTransform:执行向量的透视矩阵转换。

    函数cv :: perspectiveTransform通过以下方式将src的每个元素视为2D或3D向量,从而对其进行转换:

    ( x , y , z ) → ( x ′ / w , y ′ / w , z ′ / w ) (x, y, z) \rightarrow (x'/w, y'/w, z'/w) (x,y,z)(x/w,y/w,z/w),其中 ( x ′ , y ′ , z ′ , w ′ ) = mat ⋅ [ x y z 1 ] (x', y', z', w') = \texttt{mat} \cdot \begin{bmatrix} x & y & z & 1 \end{bmatrix} (x,y,z,w)=mat[xyz1] w = { w ′ , i f ( w ′ ≠ 0 ) ∞ , o t h e r w i s e w = \begin{cases}{w'}, {if (w' \ne 0 )}\\{\infty},{otherwise}\end{cases} w={w,if(w=0),otherwise

    这里显示了3D矢量变换。 在2D矢量变换的情况下,z分量被省略。

    2)cv::getPerspectiveTransform:根据四对对应点计算透视变换。

    Mat cv::getPerspectiveTransform (InputArray src,InputArray dst,int solveMethod = DECOMP_LU)

    该函数计算透视变换的3×3矩阵:

    KaTeX parse error: Expected '}', got '_' at position 72: …} = \texttt{map_̲matrix} \cdot \…,其中, d s t ( i ) = ( x i ′ , y i ′ ) , s r c ( i ) = ( x i , y i ) , i = 0 , 1 , 2 , 3 dst(i)=(x'_i,y'_i), src(i)=(x_i, y_i), i=0,1,2,3 dst(i)=(xi,yi),src(i)=(xi,yi),i=0,1,2,3

    3)cv::warpPerspective:将透视变换应用于图像。

    void cv::warpPerspective(InputArray src,OutputArray dst,InputArray M,Size dsize,int flags = INTER_LINEAR,int borderMode = BORDER_CONSTANT,const Scalar & borderValue = Scalar())

    函数warpPerspective使用指定的矩阵转换源图像:

    dst ( x , y ) = src ( M 11 x + M 12 y + M 13 M 31 x + M 32 y + M 33 , M 21 x + M 22 y + M 23 M 31 x + M 32 y + M 33 ) \texttt{dst} (x,y) = \texttt{src} \left ( \frac{M_{11} x + M_{12} y + M_{13}}{M_{31} x + M_{32} y + M_{33}} , \frac{M_{21} x + M_{22} y + M_{23}}{M_{31} x + M_{32} y + M_{33}} \right ) dst(x,y)=src(M31x+M32y+M33M11x+M12y+M13,M31x+M32y+M33M21x+M22y+M23)

    当设置标志WARP_INVERSE_MAP时。 否则,首先使用invert反转变换,然后将其放在上面的公式中,而不是M中。该函数无法就地操作。

     // Input Quadilateral or Image plane coordinates
        Point2f inputQuad[4];
        // Output Quadilateral or World plane coordinates
        Point2f outputQuad[4];
    
        // Lambda Matrix
        Mat lambda( 2, 4, CV_32FC1 );
        //Input and Output Image;
        Mat input, output;
    
        //Load the image
        input = imread( "resources/images/f1.jpg");
        // Set the lambda matrix the same type and size as input
        lambda = Mat::zeros( input.rows, input.cols, input.type() );
    
        // The 4 points that select quadilateral on the input , from top-left in clockwise order
        // These four pts are the sides of the rect box used as input
        inputQuad[0] = Point2f( -30,-60 );
        inputQuad[1] = Point2f( input.cols+50,-50);
        inputQuad[2] = Point2f( input.cols+100,input.rows+50);
        inputQuad[3] = Point2f( -50,input.rows+50  );
        // The 4 points where the mapping is to be done , from top-left in clockwise order
        outputQuad[0] = Point2f( 0,0 );
        outputQuad[1] = Point2f( input.cols-1,0);
        outputQuad[2] = Point2f( input.cols-1,input.rows-1);
        outputQuad[3] = Point2f( 0,input.rows-1  );
    
    //    // Get the Perspective Transform Matrix i.e. lambda
        lambda = getPerspectiveTransform( inputQuad, outputQuad );
    //    // Apply the Perspective Transform just found to the src image
        warpPerspective(input,output,lambda,output.size() );
    
    
    
        imshow("Input",input);
        imshow("Output",output);
    
        waitKey(0);
    

    38、cv::phase


    计算2D向量的旋转角度(方向场)。

    void cv::phase(InputArray x,OutputArray angle,bool angleInDegrees = false)

    函数cv :: phase计算由x和y的对应元素形成的每个2D矢量的旋转角度: angle ( I ) = atan2 ( y ( I ) , x ( I ) ) \texttt{angle} (I) = \texttt{atan2} ( \texttt{y} (I), \texttt{x} (I)) angle(I)=atan2(y(I),x(I))

    角度估计精度约为0.3度。 当x(I)= y(I)= 0时,相应的角度(I)设置为0。

    	Mat img = cv::imread( "resources/images/f1.jpg",0);
        Mat grad1,grad2,angle;
        Sobel(img, grad1, CV_64FC1, 1, 0); //求梯度
        Sobel(img, grad2, CV_64FC1, 0, 1);
        blur(grad1,grad1,Size(6,6));
        blur(grad2,grad2,Size(6,6));
        phase(grad1, grad2, angle, true); //求角度
        normalize(angle, angle, 0, 255, NORM_MINMAX); //归一化 方便显示,和实际数据没有关系
        angle.convertTo(angle,CV_8UC1);
        imshow("src",img);
        imshow("angle",angle);
        waitKey();
    

    39、cv::PSNR


    计算峰值信噪比(PSNR)图像质量指标。

    double cv::PSNR (InputArray src1,InputArray src2,double R = 255.)

    此函数计算两个输入阵列src1和src2之间的峰值信噪比(PSNR)图像质量度量,以分贝(dB)为单位。 数组必须具有相同的类型。PSNR计算如下:

    PSNR = 10 ⋅ log ⁡ 10 ( R 2 M S E ) \texttt{PSNR} = 10 \cdot \log_{10}{\left( \frac{R^2}{MSE} \right) } PSNR=10log10(MSER2)

    其中R是深度的最大整数值(例如,对于CV_8U数据为255),MSE是两个数组之间的均方误差。

    double compute_PSNR(cv::Mat Mat1, cv::Mat Mat2)
    {
    
        cv::Mat M1 = Mat1.clone();
        cv::Mat M2 = Mat2.clone();
    
        int rows = M2.rows;
        int cols = M2.cols 
        // 确保它们的大小是一致的
        cv::resize(mGND,mGND,cv::Size(cols,rows) );
    
        mGND.convertTo(M1,CV_32F);
        mSR.convertTo(mSR,CV_32F);
        // compute PSNR
        Mat Diff;
        // Diff一定要提前转换为32F,因为uint8格式的无法计算成平方
        Diff.convertTo(Diff,CV_32F);    
        cv::absdiff(M1,M2,Diff); //  Diff = | M1 - M2 |
    
        Diff=  Diff.mul(Diff);            //     | M1 - M2 |.^2
        Scalar S = cv::sum(Diff);  // 分别计算每个通道的元素之和
    
        double sse;   // square error
        if (mDiff.channels()==3)
            sse = S.val[0] +S.val[1] + S.val[2];  // sum of all channels
        else
            sse = S.val[0];
    
        int nTotalElement = mGND.channels()*mGND.total();
        
        double mse = ( sse / (double)nTotalElement );  // 
       
        // 加上0.0000001作为偏置,不至于发生除了的错误
        double psnr = 10.0 * log10( 255*255 / (Mse+0.0000001) );
        std::cout<< "PSNR : " << Psnr << std::endl;
        return psnr;
    

    40、cv::randn、cv::randShuffle、cv::randu


    1)cv::randn:用正态分布的随机数填充数组。

    void cv::randn(InputOutputArray dst,InputArray stddev)

    函数cv :: randn用正态分布的随机数填充矩阵dst,该随机数具有指定的均值向量和标准差矩阵。 剪切生成的随机数以适合输出数组数据类型的值范围。

    2)cv::randShuffle:随机随机排列数组元素。

    void cv::randShuffle(InputOutputArray dst,double iterFactor = 1.,RNG * rng = 0)

    函数cv :: randShuffle通过随机选择元素对并交换它们来对指定的1D数组进行混洗。 此类交换操作的数量为dst.rows * dst.cols * iterFactor。

    3)cv::randu:生成单个均匀分布的随机数或随机数数组。

    void cv::randu(InputOutputArray dst,InputArray low,InputArray high)

    该函数的非模板变量使用指定范围内的均匀分布的随机数填充矩阵dst。 low c ≤ dst ( I ) c < high c \texttt{low} _c \leq \texttt{dst} (I)_c < \texttt{high} _c lowcdst(I)c<highc

    41、cv::reduce


    将矩阵简化为向量。

    void cv::reduce(InputArray src,OutputArray dst,int dim,int dtype = -1)

    函数reduce通过将矩阵行/列视为一组一维向量并对向量执行指定的操作,直到获得单个行/列,将矩阵简化为向量。 例如,该函数可用于计算光栅图像的水平和垂直投影。 如果使用REDUCE_MAX和REDUCE_MIN,则输出图像应与源图像具有相同的类型。 在REDUCE_SUM和REDUCE_AVG的情况下,输出可能具有较大的元素位深度,以保持精度。 这两种归约模式也支持多通道阵列。

     Mat m = (Mat_<uchar>(3,2) << 1,2,3,4,5,6);
            Mat col_sum, row_sum;
            reduce(m, col_sum, 0, REDUCE_SUM, CV_32F);
            reduce(m, row_sum, 1, REDUCE_SUM, CV_32F);
            /*
            m =
            [  1,   2;
               3,   4;
               5,   6]
            col_sum =
            [9, 12]
            row_sum =
            [3;
             7;
             11]
             */
    

    42、cv::repeat


    用输入数组的重复副本填充输出数组。

    void cv::repeat(InputArray src,int ny,OutputArray dst)

    函数cv :: repeat沿着两个轴中的每个轴将输入数组复制一次或多次: dst i j = src i m o d    s r c . r o w s ,    j m o d    s r c . c o l s \texttt{dst} _{ij}= \texttt{src} _{i\mod src.rows, \; j\mod src.cols } dstij=srcimodsrc.rows,jmodsrc.cols

    43、cv::solve、cv::solveCubic、cv::solvePoly


    1)cv::solve:求解一个或多个线性系统或最小二乘问题。

    bool cv::solve(InputArray src1,InputArray src2,OutputArray dst,int flags = DECOMP_LU)

    函数cv :: solve解决了线性系统或最小二乘问题(后者可以通过SVD或QR方法或通过指定标志DECOMP_NORMAL来实现):

    dst = arg ⁡ min ⁡ X ∥ src1 ⋅ X − src2 ∥ \texttt{dst} = \arg \min _X \| \texttt{src1} \cdot \texttt{X} - \texttt{src2} \| dst=argminXsrc1Xsrc2

    如果使用DECOMP_LU或DECOMP_CHOLESKY方法,则该函数返回1

    如果src1或者 src1 T src1 \texttt{src1}^T\texttt{src1} src1Tsrc1是non-singular,返回0,否则返回1。

    在后一种情况下,dst无效。 其他方法在左侧部分为奇数的情况下找到伪解。

    2)cv::solveCubic:查找三次方程的实根。

    int cv::solveCubic(InputArray coeffs,OutputArray roots)

    函数solveCubic查找三次方程的实根:

    • 如果coeffs是4元素向量: coeffs [ 0 ] x 3 + coeffs [ 1 ] x 2 + coeffs [ 2 ] x + coeffs [ 3 ] = 0 \texttt{coeffs} [0] x^3 + \texttt{coeffs} [1] x^2 + \texttt{coeffs} [2] x + \texttt{coeffs} [3] = 0 coeffs[0]x3+coeffs[1]x2+coeffs[2]x+coeffs[3]=0
    • 如果coeffs是3元素向量: x 3 + coeffs [ 0 ] x 2 + coeffs [ 1 ] x + coeffs [ 2 ] = 0 x^3 + \texttt{coeffs} [0] x^2 + \texttt{coeffs} [1] x + \texttt{coeffs} [2] = 0 x3+coeffs[0]x2+coeffs[1]x+coeffs[2]=0

    根存储在roots数组中。

    3)cv::solvePoly:查找多项式方程的实根或复数根。

    double cv::solvePoly(InputArray coeffs,OutputArray roots,int maxIters = 300)

    函数cv :: solvePoly查找多项式方程的实根和复根:

    coeffs [ n ] x n + coeffs [ n − 1 ] x n − 1 + . . . + coeffs [ 1 ] x + coeffs [ 0 ] = 0 \texttt{coeffs} [n] x^{n} + \texttt{coeffs} [n-1] x^{n-1} + ... + \texttt{coeffs} [1] x + \texttt{coeffs} [0] = 0 coeffs[n]xn+coeffs[n1]xn1+...+coeffs[1]x+coeffs[0]=0

    44、cv::sort


    1)cv::sort:对矩阵的每一行或每一列进行排序。

    void cv::sort(InputArray src,OutputArray dst,int flags)

    函数cv :: sort以升序或降序对每个矩阵行或每个矩阵列进行排序。 因此,您应该传递两个操作标志以获得所需的行为。 如果要按字典顺序对矩阵行或列进行排序,则可以将STL std :: sort泛型函数与正确的比较谓词一起使用。

    2)cv::sortIdx:对矩阵的每一行或每一列进行排序。

    void cv::sortIdx(InputArray src,OutputArray dst,int flags)

    函数cv :: sortIdx以升序或降序对每个矩阵行或每个矩阵列进行排序。 因此,您应该传递两个操作标志以获得所需的行为。 它没有对元素本身进行重新排序,而是将已排序元素的索引存储在输出数组中。 例如:

    Mat A = Mat::eye(3,3,CV_32F), B;
    sortIdx(A, B, SORT_EVERY_ROW + SORT_ASCENDING);
    // B will probably contain
    // (because of equal elements in A some permutations are possible):
    // [[1, 2, 0], [0, 2, 1], [0, 1, 2]]
    

    45、cv::trace


    返回矩阵的轨迹。

    Scalar cv::trace(InputArray mtx)

    函数cv :: trace返回矩阵mtx的对角元素之和: t r ( mtx ) = ∑ i mtx ( i , i ) \mathrm{tr} ( \texttt{mtx} ) = \sum _i \texttt{mtx} (i,i) tr(mtx)=imtx(i,i)

    46、cv::transform、cv::transpose


    1)cv::transform:对每个数组元素执行矩阵转换。

    void cv::transform(InputArray src,OutputArray dst,InputArray m)

    函数cv :: transform对数组src的每个元素执行矩阵转换,并将结果存储在dst中:

    • dst ( I ) = m ⋅ src ( I ) \texttt{dst} (I) = \texttt{m} \cdot \texttt{src} (I) dst(I)=msrc(I)(当m.cols = src.channels()时)
    • dst ( I ) = m ⋅ [ src ( I ) ; 1 ] \texttt{dst} (I) = \texttt{m} \cdot [ \texttt{src} (I); 1] dst(I)=m[src(I);1](当m.cols = src.channels()+ 1时)

    N通道数组src的每个元素都被解释为N元素矢量,它使用M x N或M x(N + 1)矩阵m转换为M元素矢量-输出数组dst的对应元素。

    该功能可用于N维点的几何变换,任意线性色彩空间变换(例如各种RGB到YUV变换),混洗图像通道等等。

    2)cv::transpose:转置矩阵。

    void cv::transpose(InputArray src,OutputArray dst)

    函数cv :: transpose转置矩阵src: dst ( i , j ) = src ( j , i ) \texttt{dst} (i,j) = \texttt{src} (j,i) dst(i,j)=src(j,i)

    47、cv::hconcat、cv::vconcat


    1)cv::hconcat:将水平串联应用于给定矩阵。

    void cv::hconcat(const Mat * src,size_t nsrc,OutputArray dst)

    该函数水平连接两个或多个cv :: Mat矩阵(具有相同的行数)。

    cv::Mat matArray[] = { cv::Mat(4, 1, CV_8UC1, cv::Scalar(1)),
                           cv::Mat(4, 1, CV_8UC1, cv::Scalar(2)),
                           cv::Mat(4, 1, CV_8UC1, cv::Scalar(3)),};
    cv::Mat out;
    cv::hconcat( matArray, 3, out );
    //out:
    //[1, 2, 3;
    // 1, 2, 3;
    // 1, 2, 3;
    // 1, 2, 3]
    

    2)cv::vconcat:将垂直串联应用于给定矩阵。

    void cv::vconcat(const Mat * src,size_t nsrc,OutputArray dst)

    cv::Mat matArray[] = { cv::Mat(1, 4, CV_8UC1, cv::Scalar(1)),
                           cv::Mat(1, 4, CV_8UC1, cv::Scalar(2)),
                           cv::Mat(1, 4, CV_8UC1, cv::Scalar(3)),};
    cv::Mat out;
    cv::vconcat( matArray, 3, out );
    //out:
    //[1,   1,   1,   1;
    // 2,   2,   2,   2;
    // 3,   3,   3,   3]
    
    展开全文
  • 非负矩阵分解NMF(应用、原理及基于python的实例)

    千次阅读 多人点赞 2018-10-20 11:46:11
    科学研究中的很多大规模数据的分析方法都是通过矩阵形式进行有效处理的(图像/文本/音频),为高效处理这些通过矩阵存放的数据,一个关键的必要步骤便是对矩阵进行分解操作。通过矩阵分解,一方面将描述问题的矩阵的维...
  • 共轭方向法

    千次阅读 2019-04-02 20:09:40
    文章目录共轭方向法基本的共轭方向算法算法...作为共轭方向法的典型代表,共轭梯度法不需要计算黑塞矩阵; 两次搜索方向之间是共轭的。 对于所有的i≠ji\neq ji̸​=j,有d(i)TQd(j)=0d^{(i)T}Qd^{(j)}=0d(i)TQd...
  • MKL 求解大型稀疏矩阵

    2020-05-04 04:58:22
    inter MKL 求解大型稀疏矩阵 实例(C/C++)。适用与对称或者非对称 稀疏矩阵求解,求解速度非常快。
  • 矩阵论——广义逆矩阵

    千次阅读 2018-12-22 14:40:56
    对投影进行如下的定义(限制条件增强)讨论(由限制条件增强来带的性质)引理及相关证明(由以上性质引出的一些结论)E是幂等矩阵,则有R(I-E)=N(E)$P$是幂等矩阵和$P$投影矩阵互为充要条件投影矩阵实例 闲话 没有...
  • 实例见matlab_norm 矩阵范数 定义如下 ∣∣A∣∣=max⁡x≠0∣∣Ax∣∣∣∣x∣∣||\boldsymbol A||=\max\limits_{\boldsymbol{x\ne 0}}\frac{||\boldsymbol {Ax}||}{||\boldsymbol x||}∣∣A∣∣=x​=0max​∣∣x∣...
  • 最优化方法-共轭梯度法

    千次阅读 2019-03-31 17:16:23
    最优化方法-共轭梯度法 1.简介 共轭梯度法最初由Hesteness和Stiefel于1952年为求解线性方程组而提出的。其基本思想是把共轭性与最速下降方法相结合,利用已知点处的梯度构造一组共轭方向,并沿这组方向进行搜素,求...
  • CvMat矩阵结构

    2013-05-02 22:07:14
    任何时候需要向量,都只需要一个列矩阵(如果需要一个转置或者共轭向量,则需要一个行矩阵)。第二,OpenCV矩阵的概念与我们在线性代数课上学习的概念相比,更抽象,尤其是矩阵的元素,并非只能取简单的数值类型。例如...
  • matlab中关于矩阵转置的学习日记

    千次阅读 2018-10-19 09:25:29
    在matlab做矩阵运算时经常要用到转置运算,如果是复矩阵还需要共轭转置。之前对这两者的认识有误,今天mark一下。 1: ’ %该符号表示共轭转置,当矩阵为实矩阵时表示转置 2: .’ %该符号表示转置运算 运算实例: a...
  • LabVIEW矩阵的基本应用

    2021-03-18 14:57:12
    矩阵转置”是对输入的矩阵进行转化,如输入矩阵是一个复数矩阵,则该VI进行共轭转置。连接至输入矩阵输入端的数据类型决定了所使用的多态实例。 下面介绍如何对一个矩阵进行转置,生成一个新的转置矩阵,然后创建...
  • 用matlab实现共轭梯度法求解实例.doc 用MATLAB 实现共轭梯度法求解实例 康福 201103710031 1.无约束优化方法 1.1 无约束优化方法的必要性 一般机械优化设计问题,都是在一定的限制条件下追求某一指标为最小,它 们...
  • NumPy矩阵运算

    千次阅读 2015-08-25 15:20:46
    8.2 矩阵(Matrix)对象 Matrix类型继承于ndarray类型,因此含有ndarray的所有数据属性和方法。Matrix类型与ndarray类型有六个重要的不同点,当你当Matrix对象当arrays操作时,这些不同点会导致非预期的结果。 1)...
  • SciPy教程 - 稀疏矩阵库scipy.sparse

    万次阅读 多人点赞 2014-12-06 00:15:33
    http://blog.csdn.net/pipisorry/article/details/41762945 sparse模块的官方document:... 一、sparse matrix稀疏矩阵不同的存储形式在sparse模块中对应如下 bsr_matrix(arg1[, sh
  • 要熟练掌握矩阵的运算,首先需具有...矩阵运算包括矩阵的加法,减法,数乘,乘法、转置,共轭共轭转置  矩阵加法:(只有同型矩阵之间才可以进行加法)  矩阵的加法满足下列运算律(A,B,C都是同型矩...
  • #示例:S为特征向量构成的矩阵,Λ为特征值构成的对角矩阵 S^{-1}·A·S=Λ⇒A~Λ #性质: 1.A~B,B~C⇒A~C 2.A~B⇒A与B的特征值相同 Ax=λx⇒A·M·M^{-1}x=λx⇒M^{-1}·A·M·M^{-1}x=λM^{-1}x⇒B·M^{-1}x=λM^{-...
  • Matlab系列之矩阵

    2020-08-09 22:36:06
    前言 上次讲完了数组的基本操作,不知道是否熟悉使用了,本篇将要对矩阵部分的操作再进行介绍,这部分的内容我觉得蛮有意思的,不过你们觉不觉得我就不知了,但还是想让你们...那直接看实例来了解了解: 看到了吧,简
  • 实例说明复数域上的Schur乘积的结论对于半正定的自共轭四元数矩阵的Schur乘积而言,一般是不成立的;并给出实四元数体上矩阵的Schur乘积的正确结论。
  • numpy矩阵的创建和运算

    千次阅读 2019-09-09 16:25:01
    numpy的矩阵可以由矩阵,数组甚至列表转换而来,接下来看一下实例 import numpy as np # 创建矩阵 ---必须是二维的 # mat 生成矩阵的方法1 m1 = np.mat("1 2 3;4 5 6;7 8 9") m2 = np.mat([[1,2,3],[4,5,6],[7,8,9...
  • Matlab基础 数值矩阵 -- 点运算符和矩阵运算符的区别 最近准备数学竞赛需要对Matlab重新进行一个系统的学习,于是将在学习中学到的东西以博客的形式记录一下,首先是Matlab基础的知识...计算方式及其实例--有截图代码
  • 对称矩阵

    千次阅读 2018-11-07 08:54:50
    对称矩阵   特征向量特征值对角化   维基百科,自由的百科全书 线性代数 A = [ 1 2 3 4 ] {\displaystyle \mathbf {A} ={\begin{bmatrix}1&amp;2\\3&amp;4\end{bmatrix))} 向量 · 向量空间 · 行列...
  • MATLAB矩阵处理

    2019-07-31 12:54:33
    1.特殊矩阵 通用的特殊矩阵 zeros函数:产生全0矩阵,即零矩阵。 ones函数:产生全1矩阵。 eye函数:产生对角线全为1的矩阵,当矩阵为方阵时,得到一个单位矩阵。 rand函数:产生(0,1)区间均匀分布的随机...
  • 一文通透优化算法:从随机梯度、随机梯度下降法到牛顿法、共轭梯度       1 什么是梯度下降法 经常在机器学习中的优化问题中看到一个算法,即梯度下降法,那到底什么是梯度下降法呢? 维基百科给出的定义...
  • 矩阵快速幂

    2019-10-08 15:07:32
    矩阵快速幂推公式的。 https://blog.csdn.net/zhangxiaoduoduo/article/details/81807338 HDU 4565不会,涉及共轭复数??????? https://baike.baidu.com/item/%E6%...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,797
精华内容 718
关键字:

共轭矩阵实例