python 计算图像结构张量(Structure_tensor)

  • Post author:
  • Post category:python

  • 什么是图像结构张量?
    初始的结构张量利用的是梯度算子,来计算符合人类视觉特性的空间结构特征。 结构张量表达方法很好的避免了梯度计算时的正负抵消效应,又具有半正定性,再经线性高斯滤波后即使在有噪声的情况下也可以具有稳定的特性。
    利用平滑后的矩阵场的特征值和特征向量等信息,可以快速的提取
    图像中的结构信息,如图像内目标边缘,目标形状角点特征等
    结构张量技术可以很好的将结构信息突出的部分和结构信息弱的部分区分开,例如区分开图像中的边缘轮廓等细节与平坦光滑的部分。
  • 怎么利用python进行计算?
    二维图像的结构矩阵构成如下:

    T

    =

    [

    R

    x

    2

    R

    x

    R

    y

    R

    x

    R

    y

    R

    y

    2

    ]

    =

    [

    T

    x

    x

    T

    x

    y

    T

    x

    y

    T

    y

    y

    ]

    =

    [

    A

    r

    r

    A

    r

    c

    A

    r

    c

    A

    c

    c

    ]

    T=\begin{bmatrix} Rx^{2} & RxRy\\ RxRy&Ry^{2} \end{bmatrix}=\begin{bmatrix} T_{xx} & T_{xy} \\ T_{xy} &T_{yy} \end{bmatrix}=\begin{bmatrix} A_{rr} & A_{rc} \\ A_{rc} &A_{cc} \end{bmatrix}

    T=[Rx2RxRyRxRyRy2]=[TxxTxyTxyTyy]=[ArrArcArcAcc]

    R

    x

    ,

    R

    y

    Rx,Ry

    Rx,Ry分别为图像的水平与垂直梯度,而后进行求矩阵

    T

    T

    T的行列式

    K

    K

    K与迹

    H

    H

    H
    根据

    K

    K

    K

    H

    H

    H的关系来求得区分图像的平坦、边缘与角点区域:
    平坦区域:

    H

    =

    0

    H=0

    H=0;
    边缘区域:

    H

    >

    0

    ,

    K

    =

    0

    H>0,K=0

    H>0,K=0;
    角点区域:

    H

    >

    0

    ,

    K

    >

    0

    H>0, K>0

    H>0,K>0;
    禁止重复造车,直接使用skimage.feature.structure_tensor(image, sigma=1, mode='constant', cval=0, order=None)函数来进行计算。函数目的就是使用平方差之和计算结构张量。
    skimage.feature.structure_tensor(image, sigma=1, mode='constant', cval=0, order=None)
    参数:
    image: ndarray
    输入图像
    sigma: float or array-like of float, 可选
    用于高斯核的标准差,它用作平方差的局部求和的加权函数。如果 sigma 是可迭代的,则其长度必须等于 image.ndim,并且每个元素都用于沿其各自轴应用的高斯核。
    mode: {‘constant’, ‘reflect’, ‘wrap’, ‘nearest’, ‘mirror’}, 可选
    如何处理图像边框外的值。
    cval: float, 可选
    与模式“常量”结合使用,后者是图像边界外的值。
    order: {‘rc’, ‘xy’},可选
    注意:仅适用于 2D。更高维度必须始终使用“rc”顺序。此参数允许在梯度计算中使用图像轴的反向或正向顺序。“rc”表示最初使用第一个轴

    (

    A

    r

    r

    A

    r

    c

    A

    c

    c

    )

    (Arr,Arc,Acc)

    (ArrArcAcc),而“xy”表示最初使用最后一个轴

    (

    A

    x

    x

    A

    x

    y

    A

    y

    y

    )

    (Axx,Axy,Ayy)

    (AxxAxyAyy)
    返回
    A_elems: list of ndarray
    输入图像中每个像素的结构张量的上对角线元素。
    所以通过上面的函数就可以得到每个像素的结构向量。例如第i行j列像素的结构向量的组成就是:

    A

    i

    j

    =

    [

    A

    r

    r

    i

    j

    A

    r

    c

    i

    j

    A

    r

    c

    i

    j

    A

    c

    c

    i

    j

    ]

    A_{ij}=\begin{bmatrix} A_{rr_{ij}} & A_{rc_{ij}} \\ A_{rc_{ij}} &A_{cc_{ij}} \end{bmatrix}

    Aij=[ArrijArcijArcijAccij]
    例如: A_elems=structure_tensor(img,sigma=6,order=‘rc’) 就得到了img图像的结构张量。
    此时为了还需要进行结构张量特征值的求解。因为是使用结构张量的行列式和迹来进行空间特征判断的。
    引入skimage.feature.structure_tensor_eigenvalues(A_elems)函数来计算计算结构张量的特征值。
    skimage.feature.structure_tensor_eigenvalues(A_elems)
    参数:
    A_elems:list of ndarray
    结构张量的上对角线元素,由structure_tensor返回。
    返回:
    ndarray
    结构张量的特征值,按降序排列。 特征值是前导维度。 也就是说,坐标 [i, j, k] 对应于位置 (j, k) 处的第 i 个最大特征值。
    这样就可以得到图像每个像素结构张量的特征值。依据矩阵特征值与行列式、迹的关系:矩阵的特征值之积等于矩阵的行列式,矩阵的特征值之和等于矩阵的迹
    例如: eigen=structure_tensor_eigenvalues(A_elems),则
    K=eigen.prod(axis=0)#对应项的特征值求积
    H=eigen.sum(axis=0)#对应项的特征值求和
    最后根据

    K

    K

    K

    H

    H

    H的关系来求得区分图像的平坦、边缘与角点区域:
    平坦区域:

    H

    =

    0

    H=0

    H=0;
    边缘区域:

    H

    >

    0

    ,

    K

    =

    0

    H>0,K=0

    H>0,K=0;
    角点区域:

    H

    >

    0

    ,

    K

    >

    0

    H>0, K>0

    H>0,K>0;即可
    实例:

from skimage.feature import structure_tensor
from skimage.feature import structure_tensor_eigenvalues
import matplotlib.pyplot as plt
import cv2 as cv
import numpy as np
file_path=r'F:\segment_all\3.jpg'
image=cv.imread(file_path)
img=cv.cvtColor(image, cv.COLOR_BGR2GRAY)
plt.imshow(img,cmap='gray')
A_elems = structure_tensor(img,sigma=1.5,order='rc')
eigen = structure_tensor_eigenvalues(A_elems)
K=eigen.prod(axis=0)
H=eigen.sum(axis=0)
sd=H<0.01
sdf=sd.astype(float)
plt.imshow(sdf)
plt.colorbar()

在这里插入图片描述在这里插入图片描述
如图所示,根据H可以确定图像中的平面,从而得到图片的边缘特征。


版权声明:本文为weixin_42228166原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。