结合此处的代码,重新归纳整理一下算法的流程:

  1. 输入一幅分辨率的

    640

    ×

    480

    640\times 480

    640×480
    的RGB图像,记为

    I

    0

    I_0

    I0
  2. I

    0

    I_0

    I0
    高斯平滑,然后再进行

    s

    =

    2

    s=2

    s=2
    降采样。即将图像尺寸行和列方向缩减一半(代码中是用 cv::pyrDown 函数一次处理),得到

    I

    1

    I_1

    I1
    注:OpenCV实现了用于创建图像金字塔的两个函数 pyrDownpryUp
  3. 重复第2步,得到

    I

    2

    ,

    I

    3

    ,

    I

    4

    ,

    I

    5

    ,

    I

    6

    ,

    I

    7

    ,

    I

    8

    I_2, I_3, I_4, I_5, I_6, I_7, I_8

    I2,I3,I4,I5,I6,I7,I8

    I

    8

    I_8

    I8
    的长宽分别为

    I

    0

    I_0

    I0

    1

    /

    256

    1/256

    1/256
    (注意 640 和480 都不能被 256 整除,个人觉得输入分辨率应该调整为256的倍数,不过这是小问题)
  4. I

    0

    I

    8

    I_0\sim I_8

    I0I8
    分别有

    r

    r

    r

    g

    g

    g

    b

    b

    b
    分量,计算每一个

    I

    k

    I_k

    Ik
    的“扩展颜色”

    R

    R

    R

    G

    G

    G

    B

    B

    B

    Y

    Y

    Y
    分量:

    R

    k

    =

    r

    k

    g

    k

    +

    b

    k

    2

    G

    k

    =

    g

    k

    r

    k

    +

    b

    k

    2

    B

    k

    =

    b

    k

    r

    k

    +

    g

    k

    2

    Y

    k

    =

    (

    r

    k

    +

    g

    k

    )

    r

    k

    g

    k

    2

    b

    k

    \begin{aligned} R_k &= r_k-\frac{g_k + b_k}{2}\\ G_k &= g_k-\frac{r_k + b_k}{2} \\ B_k&=b_k-\frac{r_k + g_k}{2} \\ Y_k&=\frac{(r_k + g_k)-| r_k-g_k |}{2}-b_k \end{aligned}

    RkGkBkYk=rk2gk+bk=gk2rk+bk=bk2rk+gk=2(rk+gk)rkgkbk
    注意这里计算

    r

    r

    r

    g

    g

    g

    b

    b

    b
    分量的时候增加了一步:对于每个分量查找最大值,然后每个分量里面那些小于最大值1/10的点都置零。

    亮度图

    I

    k

    =

    r

    k

    +

    g

    k

    +

    b

    k

    3

    I’_k=\frac{r_k+g_k+b_k}{3}

    Ik=3rk+gk+bk
    亮度图计算时用的

    r

    r

    r

    g

    g

    g

    b

    b

    b
    分量不作处理,直接用。

    方向图

    O

    k

    (

    θ

    )

    =

    c

    o

    n

    v

    2

    d

    (

    I

    k

    ,

    W

    G

    (

    σ

    ,

    θ

    )

    )

    O_k(\theta)=conv2d\left(I’_k,W_G(\sigma,\theta)\right)

    Ok(θ)=conv2d(Ik,WG(σ,θ))

    W

    G

    W_G

    WG
    表示 Gabor 滤波器,用于边缘提取的线性滤波器,其频率和方向表达与人类视觉系统类似,能够提供良好的方向选择和尺度选择特性,而且对于光照变化不敏感,因此十分适合纹理分析。参考代码用 cv::getGaborKernel((8, 8), 4,

    θ

    \theta

    θ
    , 8, 1)
    来求得,忽略掉了不同的尺度

    σ

    \sigma

    σ
    (注意这个

    σ

    \sigma

    σ
    是论文中用来表示尺度的符号,不是 Gabor核函数中的

    σ

    \sigma

    σ
    。Gabor核函数的详细说明看这里),我感觉这样不行。毕竟对于一幅尺寸为

    1024

    ×

    1024

    1024 \times 1024

    1024×1024
    的输入图像,

    I

    8

    I_8

    I8
    的尺寸才

    4

    ×

    4

    4\times 4

    4×4

    θ

    \theta

    θ
    这里用弧度表示,

    [

    0

    °

    ,

    45

    °

    ,

    90

    °

    ,

    135

    °

    ]

    [0\degree,45\degree,90\degree,135\degree]

    [0°,45°,90°,135°]
    分别对应

    [

    0

    ,
      

    π

    /

    4

    ,
      

    π

    /

    2

    ,
      

    3

    π

    /

    4

    ]

    [0,\; \pi/4,\;\pi/2,\;3\pi/4]

    [0,π/4,π/2,3π/4]

    c

    o

    n

    v

    2

    d

    conv2d

    conv2d
    操作用 cv::filter2D 函数实现。
  5. 计算差分特征图:对以上几步形成的

    8

    ×

    9

    =

    72

    8\times 9=72

    8×9=72
    张图进行差分计算,最终得到42张特征图。论文选

    c

    =

    {

    2

    ,

    3

    ,

    4

    }

    c=\{2,3,4\}

    c={2,3,4}
    ,代码中似乎取

    c

    =

    {

    1

    ,

    2

    ,

    3

    }

    c=\{1,2,3\}

    c={1,2,3}
    ,以论文为准吧。

    s

    =

    c

    +

    {

    3

    ,

    4

    }

    s=c+\{3,4\}

    s=c+{3,4}
    则 尺度

    s

    s

    s
    的图像的长宽分别是尺度

    c

    c

    c
    的图像的 1/8或者1/16分之一,先用 cv::resize 函数(interpolation=cv::INTER_NEAREST )对尺度

    s

    s

    s
    的图像进行放大,得到和 尺度

    c

    c

    c
    一样大小的图像,然后逐点减操作。得到

    I

    (

    c

    ,

    s

    )

    \mathcal{I}(c,s)

    I(c,s)

    R

    G

    (

    c

    ,

    s

    )

    \mathcal{RG}(c,s)

    RG(c,s)

    B

    Y

    (

    c

    ,

    s

    )

    \mathcal{BY}(c,s)

    BY(c,s)
    以及

    O

    (

    c

    ,

    s

    ,

    0

    °

    )

    \mathcal{O}(c,s,0\degree)

    O(c,s,0°)

    O

    (

    c

    ,

    s

    ,

    45

    °

    )

    \mathcal{O}(c,s,45\degree)

    O(c,s,45°)

    O

    (

    c

    ,

    s

    ,

    90

    °

    )

    \mathcal{O}(c,s,90\degree)

    O(c,s,90°)

    O

    (

    c

    ,

    s

    ,

    135

    °

    )

    \mathcal{O}(c,s,135\degree)

    O(c,s,135°)
    。参考公式1公式2公式3公式4。每一组

    (

    c

    ,

    s

    )

    (c,s)

    (c,s)
    计算7张图,一共42张图。
  6. 42张特征图合并成一张。在什么尺度上合并呢,在

    σ

    =

    4

    \sigma=4

    σ=4
    的尺度上合并,之前计算的42张特征图尺度分别是

    {

    2

    ,

    3

    ,

    4

    }

    \{2,3,4\}

    {2,3,4}
    ,有24张特征图的长宽需要缩小到原来的1/4,有14张特征图需要缩小到原来的1/2。比如最开始输入的图像是

    640

    ×

    480

    640\times 480

    640×480
    ,则合并的特征图分辨率是

    40

    ×

    30

    40\times 30

    40×30
  7. 特征图的合并分两步进行,首先是组内合并,就是亮度特征和亮度特征合并(公式5),颜色特征和颜色特征合并(公式6(#eq7)),角度特征和角度特征合并([公式7]);第二步是这三个角度上的特征合并,求平均(公式8)。不管哪一步,合并之前都要。需要归一化操作。分两步进行归一化。
  8. 特征图

    A

    A

    A

    N

    (

    A

    )

    \mathcal{N}(A)

    N(A)
    :1) 先找

    max

    (

    a

    i

    ,

    j

    )

    \max(a_{i,j})

    max(ai,j)
    ;2) 再找除了

    a

    i

    ,

    j

    a_{i,j}

    ai,j
    之外的局部最大值的平均

    m

    ˉ

    \bar m

    mˉ
    ;3)

    λ

    =

    (

    max

    (

    a

    i

    ,

    j

    )

    m

    ˉ

    )

    \lambda=(\max(a_{i,j})-\bar m)

    λ=(max(ai,j)mˉ)
    ,特征图里面所有的值都乘以

    λ

    \lambda

    λ
    参考代码求局部最大值的方法有点粗糙,没考虑“左上”、“右下”、“左下”、“右上”这4个点。

版权声明:本文为weixin_41665225原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_41665225/article/details/115422667