OpenCV—python 图像显著性检测算法—HC/RC/LC/FT

综述:https://www.cnblogs.com/imzgmc/p/11072100.html
github: https://github.com/wenguanwang/SODsurvey

一、显著性检测研究现状

  1. 建立计算模型进行显著性检测。
    思想是:对输入图像首先进行多个特征通道和多尺度分解,再进行滤波得到特征图,再对特征图融合得到最终显著图。
    2007年,Hou X等人提出SR方法[2],该方法利用谱残差模型进行显著性检测,该方法认为图像的信息都包含在图像的幅度谱信息中,因此从图像的幅度谱中减去先验知识的幅度谱,剩下的就是显著部分的幅度谱,进而得到显著区域。
    一些经典算法,如Itti,SR,FT,GBVS的代码和显著性检测的数据集整理
    相位谱法。

  2. 将显著性检测定义为二元分割问题来处理
    2007年,T.Liu等人提出一种将显著性检测作为图像分割问题来处理的思路[3],自此出现了大量的显著性检测模型,掀起了显著性检测的第二波热潮。

    2009年,Achanta R等人提出FT模型来进行显著性检测[4],此模型可以输出具有明确定义的边界的全分辨率显著图,通过保留来自原始图像的更多频率内容来保留这些边界。此方法利用颜色和亮度特征的中央周边算子来得到显著图,实施简单,计算效率高

    2011年,Cheng M M等人提出了一种基于区域对比度的显著对象提取算法[5]。该算法同时评估全局对比度差异和空间加权相干性得分来确定显著性区域,此算法是简单,高效,多尺度的,并且可以生成全分辨率,高质量的显著图。这些显著图被进一步用于初始化GrabCut的新颖迭代版本,以进行高质量的显著对象分割。

    2012年,Perazzi F等人重新考虑了之前方法的一些设计选择,并提出了基于对比度的显著性检测的概念清晰且直观的算法[6]。此算法由四个基本步骤组成:(1)将给定的图像分解为紧凑且感知均匀的元素,以抽象不必要的细节;(2)基于这种抽象,计算两个对比度度量,评估这些元素的独特性和空间分布;(3)从元素对比度中推导出显著性度的度量,该度量生成一个像素精确的显著图,它统一覆盖感兴趣的对象并始终分离前景和背景;(4)文章表明,完整的对比度和显著性估计可以使用高维高斯滤波器统一制定,这有助于此方法的概念简单性,并使其具有线性复杂性的高效实施。

  3. 基于深度学习进行显著性检测
    2015年,开始引入CNN进行显著性检测,与基于对比线索的大多数经典方法不同,基于CNN的方法消除了对手工特征的需求减轻了对中心偏见知识的依赖,因此被许多科研人员所采用。基于CNN的模型通常包含数十万个可调参数和具有可变接受字段大小的神经元。神经元具有较大的接受范围提供全局信息,可以帮助更好地识别图像中最显著的区域。CNN所能实现前所未有的性能使其逐渐成为显著性物体检测的主流方向。

    2015年,He S等人提出了一种新的超像素卷积神经网络方法,称为SuperCNN,可以有效地学习显著性的内部表示[7]。与传统的卷积网络相比,SuperCNN有四个主要特性:首先,能够学习分层对比度特征;第二,恢复了超级像素之间的上下文信息;第三,受益于超像素机制,对密集标记的图像所需的预测数量大大减少;第四,通过利用多尺度网络结构检测显著性区域可以不受区域大小的约束。

    2017年,Hou Q等人提出了一种新的显著性检测方法,在HED(Holistically-Nested EdgeDetection)的基础上,增加了一种高层信息指导低层信息的Skip Layer结构,从而构建了一种简单,有效,快速的端对端的显著性物体检测网络结构[8]。此方法注意到了边缘检测、语义分割和显著性检测几个领域的一些共性和最新的趋势:

    1. 从局部分析逐渐过渡到的全局分析,
    2. HED中的Skip layer结构对高质量的输出很有帮助,
    3. 显式的让高层语义信息去指导和帮助低层语义信息更好的定位显著性物体位置的同时精确的确定其范围很有帮助。

总而言之:
显著性就是可以快速引起你注意的对象或者物体,在图像或者视频中显著性检测的结果往往是图像或者视频中对象,在神经学科中显著性检测被描述为注意力机制,目的是聚焦或者缩小看到的对象场景重要部分,显著性检测可以自动处理图像中对象表示。
生物皮层对图像对比度比较敏感,通过图像对比度可以实现图像显著性特征提取。

二、基于谱残差法的显著性检测

从信息理论角度:信息可分为冗余部分和变化部分。人们的视觉对变化部分更敏感。视觉系统的一个基本原则就是抑制对频繁出现的特征的响应,同时对非常规的特征保持敏感。那么就将图像分为如下两部分:
在这里插入图片描述
作者对图像的 log ⁡ \log log 频谱发下了如下规律(log是自然对数): E { A ( f ) } ∝ 1 / f E\{ \mathcal{A}(f) \} \propto 1/f E{A(f)}1/f
大量图像的 log ⁡ \log log 频谱的平均值是和频率呈现正比关系的。(左下图)

在这里插入图片描述
如图可知大量图像的log频谱和频率的曲线形状,在log-log scale上,几乎是一条直线。文中的log频谱就是对图像傅里叶变换后的振幅谱取自然对数。然后作者又提出了既然大量图像的log振幅谱都差不多趋近一条直线,那么一幅图像的log振幅谱减去平均log振幅谱不就是显著性部分了吗?这就是作者提出的:Spectral Residual理论。(右上图)

作者定义Spectral Residual: R ( f ) = L ( f ) − A ( f ) \mathcal{R}(f) = \mathcal{L} (f) - \mathcal{A}(f) R(f)=L(f)A(f)

给定图像 I ( x ) \mathcal{I}(x) I(x) 首先计算其2维离散傅里叶变换,将其从空间域转换到频域,对幅值取对数后得到 log谱 L ( f ) \mathcal{L}(f) L(f): 由于 log ⁡ \log log 曲线满足局部线性条件,所以用局部平均滤波器 h n ( f ) h_n(f) hn(f)对其进行平滑,获得 log ⁡ \log log谱的大致形状。 R ( f ) \mathcal{R}(f) R(f) 就是图像f的Spectral Residual。计算过程如下表示:
A ( f ) = ∣ F [ I ( x ) ] ∣ P ( f ) = φ ( F [ I ( x ) ] ) L ( f ) = log ⁡ ( A ( f ) ) R ( f ) = L ( f ) − h n ( f ) ∗ L ( f ) \begin{aligned} \mathcal{A}(f) &= | F[ \mathcal{I} (x) ]| \\ \mathcal{P}(f) &= \varphi(F[ \mathcal{I} (x) ]) \\ \mathcal{L}(f) &= \log(\mathcal{A}(f)) \\ \mathcal{R}(f) &= \mathcal{L}(f) - h_n(f)*\mathcal{L}(f) \\ \end{aligned} A(f)P(f)L(f)R(f)=F[I(x)]=φ(F[I(x)])=log(A(f))=L(f)hn(f)L(f)

S ( f ) = g ( x ) ∗ { F − 1 [ exp ⁡ ( R ( f ) + i P ( f ) ) ] 2 } \mathcal{S}(f) = g(x) * \left \{ F^{-1}\left [ \exp(\mathcal{R}(f) + i \mathcal{P}(f) ) \right ] ^2 \right \} S(f)=g(x){F1[exp(R(f)+iP(f))]2}

参数说明:

F F F 代表2维离散傅里叶变换,|·|代表其幅值, φ φ φ 代表其相位
I ( x ) \mathcal{I}(x) I(x)为输入图像,对其傅里叶变换,并且求出振幅谱为 A ( f ) \mathcal{A}(f) A(f)
P ( f ) \mathcal{P}(f) P(f)是其相位谱(复数 x+i*y 的相位是arctan(y/x))。
L ( f ) \mathcal{L}(f) L(f)是log振幅谱。h是一个n*n均值滤波的卷积核,作者设n=3。
R ( f ) \mathcal{R}(f) R(f)就是Spectral Residual谱。再将 R(f)+i*P(f)求出自然指数exp。
注意:由欧拉公式可知:
exp ⁡ ( r + i ∗ Θ ) = exp ⁡ ( r ) ∗ ( cos ⁡ ( Θ ) + i ∗ sin ⁡ ( Θ ) ) = exp ⁡ ( r ) ∗ cos ⁡ ( Θ ) + i ∗ exp ⁡ ( r ) ∗ sin ⁡ ( Θ ) \begin{aligned} \exp(r+i*Θ)&=\exp(r)* (\cos(Θ) + i*\sin(Θ)) \\ &= \exp(r)*\cos(Θ) + i*\exp(r)*\sin(Θ) \end{aligned} exp(r+iΘ)=exp(r)(cos(Θ)+isin(Θ))=exp(r)cos(Θ)+iexp(r)sin(Θ)

Θ Θ Θ是相位谱。其实 Θ Θ Θ 的正余弦也可由傅里叶谱的实部和虚部求出: s i n ( Θ ) = I m a g e I m / A m p l i t u d e \rm sin(Θ) = ImageIm/Amplitude sin(Θ)=ImageIm/Amplitude; c o s ( Θ ) = I m a g e R e / A m p l i t u d e \rm cos(Θ) = ImageRe/Amplitude cos(Θ)=ImageRe/Amplitude。然后对其,傅里叶反变换,在进行一个高斯模糊滤波就得到了所谓的显著性区域。效果如下:
在这里插入图片描述
演示代码:查看matlab以及C++代码请点击

以下代码有点问题。

import cv2
import numpy as np


def visual_saliency_detection(mat):
    # 傅里叶变换 -> 拆分为实部,虚部 -> 振幅
    fourier = cv2.dft(np.float32(mat), flags=cv2.DFT_COMPLEX_OUTPUT)
    re = fourier[:, :, 0]
    im = fourier[:, :, 1]
    base = cv2.magnitude(re, im)

    # 对数谱 -> 平滑曲线 -> 显著性余谱
    LogAmplitude = cv2.log(base)
    blur = cv2.blur(LogAmplitude, (3, 3))
    residual = LogAmplitude - blur

    # 指数还原对数谱
    residual = cv2.exp(residual)

    # 求原频域上实虚的夹角, 利用夹角还原实虚
    Sine = im / base
    Cosine = re / base
    tmp1_re = residual * Cosine
    tmp2_im = residual * Sine

    # 傅里叶逆变换
    ifourier = cv2.merge((tmp1_re, tmp2_im))
    img_idf = cv2.idft(ifourier)
    img_idf = cv2.magnitude(img_idf[:, :, 0], img_idf[:, :, 1])
    img_idf = cv2.GaussianBlur(img_idf**2, (7, 7), 0)

    # 优化结果显示
    min_v, max_v, _, _ = cv2.minMaxLoc(img_idf**2)
    _, thre = cv2.threshold(img_idf, 0, 255, cv2.THRESH_TOZERO)
    img_idf = thre * (255 / max_v-min_v)
    return img_idf



if __name__ == '__main__':
    img = cv2.imread(r'C:\Users\xxx\Desktop\002.png',0)
    res = visual_saliency_detection(img)
    cv2.imshow('res',res)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

三、基于全局对比度图像显著性检测(LC)

计算某个像素在整个图像上的全局对比度,即该像素与图像中其他所有像素在颜色上的距离之和作为该像素的显著值。
图像 I I I 中某个像素 I k I_k Ik 的显著值计算如下:
S a l S ( I k ) = ∑ ∀ I i ∈ I ∣ ∣ I k − I i ∣ ∣ SalS(I_k) = \sum_{\forall I_i \in I} ||I_k - I_i|| SalS(Ik)=IiIIkIi
其中 I i I_i Ii的取值范围为 [ 0 , 255 ] [0, 255] [0,255], 即为灰度值。
给定一张图像,每个像素 I k I_k Ik的颜色值已知。假定 I k = a m I_k = a_m Ik=am,则上式可进一步重构:
S a l S ( I k ) = ∣ ∣ a m − a 0 ∣ ∣ + ∣ ∣ a m − a 1 ∣ ∣ + . . . + ∣ ∣ a m − a n ∣ ∣ S a l S ( I k ) = ∑ n = 0 255 f n ∣ ∣ a m − a n ∣ ∣ \begin{aligned} SalS(I_k) &= ||a_m - a_0||+||a_m - a_1|| +...+||a_m - a_n|| \\ SalS(I_k)&= \sum_{n=0} ^{255}f_n||a_m - a_n|| \end{aligned} SalS(Ik)SalS(Ik)=ama0+ama1+...+aman=n=0255fnaman
其中, f n f_n fn表示图像中第 n n n个像素的频数,以直方图的形式表示。

代码演示【参考原代码请点击】 ,我使用了numpy重写了原函数,优化了代码运行时间,图片分辨率越大越省时间

import numpy as np
import time
import cv2


def diag_sym_matrix(k=256):
    base_matrix = np.zeros((k,k))
    base_line = np.array(range(k))
    base_matrix[0] = base_line
    for i in range(1,k):
        base_matrix[i] = np.roll(base_line,i)
    base_matrix_triu = np.triu(base_matrix)
    return base_matrix_triu + base_matrix_triu.T

def cal_dist(hist):
    Diag_sym = diag_sym_matrix(k=256)
    hist_reshape = hist.reshape(1,-1)
    hist_reshape = np.tile(hist_reshape, (256, 1))
    return np.sum(Diag_sym*hist_reshape,axis=1)

def LC(image_gray):
    image_height,image_width = image_gray.shape[:2]
    hist_array = cv2.calcHist([image_gray], [0], None, [256], [0.0, 256.0])
    gray_dist = cal_dist(hist_array)

    image_gray_value = image_gray.reshape(1,-1)[0]
    image_gray_copy = [(lambda x: gray_dist[x]) (x)  for x in image_gray_value]
    image_gray_copy = np.array(image_gray_copy).reshape(image_height,image_width)
    image_gray_copy = (image_gray_copy-np.min(image_gray_copy))/(np.max(image_gray_copy)-np.min(image_gray_copy))
    return image_gray_copy


if __name__ == '__main__':
    file = r"C:\Users\xxx\Desktop\003.png"

    start = time.time()
    image_gray = cv2.imread(file, 0)
    saliency_image = LC(image_gray)
    cv2.imwrite(r"C:\Users\xxx\Desktop\006_1.png",saliency_image*255)
    end = time.time()

    print("Duration: %.2f seconds." % (end - start))
    cv2.imshow("gray saliency image", saliency_image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
'''
Duration: 0.08 seconds.
'''

在这里插入图片描述
在这里插入图片描述
上述代码中 diag_sym_matrix() 函数演示详情请点击。

diag_sym_matrix(k=5):
 [[0. 1. 2. 3. 4.]
  [1. 0. 1. 2. 3.]
  [2. 1. 0. 1. 2.]
  [3. 2. 1. 0. 1.]
  [4. 3. 2. 1. 0.]]
2.1 基于直方图对比度的显著性检测(HC)

HC的显著性图生成主要是基于输入图像的颜色值直方图分布,生成像素级别的显著性值,每个像素点的显著性值是它跟剩下全部图像像素点的对比度(色差)来定义的:
S ( I k ) = ∑ ∀ I k ∈ I D ( I k , I i ) (1) S(I_k) = \sum_{\forall I_k \in I}D(I_k,I_i) \tag{1} S(Ik)=IkID(Ik,Ii)(1)

其中 D ( I k , I i ) D(I_k,I_i) D(Ik,Ii)是空间 L*a*b 中两个像素的颜色距离度量,上式经过扩展像素等级变如下方程:
S ( I k ) = D ( I k , I 1 ) + D ( I k , I 2 ) + . . . + D ( I k , I N ) (2) S(I_k) =D(I_k,I_1) +D(I_k,I_2)+...+D(I_k,I_N) \tag{2} S(Ik)=D(Ik,I1)+D(Ik,I2)+...+D(Ik,IN)(2)
其中 N N N 为图像 I I I中的像素数量。
从上式中看出拥有相同像素的值,得到显著性值会相同,把相同的像素值都归为同一类别 C j C_j Cj,对每种颜色得到显著性值:
S ( I k ) = S ( c l ) = ∑ j = 1 n f i D ( c l , c j ) (3) S(I_k) = S(c_l) = \sum_{j=1}^n f_iD(c_l,c_j) \tag{3} S(Ik)=S(cl)=j=1nfiD(cl,cj)(3)
其中 c l c_l cl是像素 I k I_k Ik的颜色值, n n n 是不同像素颜色的数量, f i f_i fi是图像I中像素值 C j C_j Cj出现的频率。这样把上面的像素计算转换为基于直方图的颜色值查找计算。

  1. 基于直方图的加速
    把对每个像素点的全图查找 O ( N 2 ) O(N^2) O(N2) 变换为 O ( N ) + O ( n 2 ) O(N)+O(n^2) O(N)+O(n2),正常情况直方图的BIN(N)为256,通过对颜色进行量化,每个颜色通道量化为12个不同值。考虑到自然图像中的颜色仅仅包含了全颜色空间中很小的一部分,通过忽略出现频率较低的颜色来进一步减少颜色数量。通过选择高频颜色并且保证这些颜色覆盖图像像素不低于95%的颜色,最终达到了n=85个颜色。剩下的像素颜色,包含不高于5%的图像像素,这部分颜色被直方图中最邻近的颜色替代。

    Lab 色彩空间只在L上计算,但是这种做法有很大的弊端,就是颜色的区分度下降,色彩空间多维度信息没有有效利用,所以一般会对Lab色彩空间的三个维度同时量化生成 颜色值,然后再根据频次优化出现的颜色值范围。确保这些颜色值可以覆盖95%以上的像素点。

  2. 颜色空间平滑
    以通过建立直方图使用色彩空间量化的方法加速全局对比度的计算,但是量化色彩空间本身就是人为的,有可能把相似的颜色量化成不同的值,为了减少这种现象导致显著性噪声出现,所以对得到显著性值最后完成一个模糊操作,采取一套平滑程序来改善每个颜色的显著值。用相似颜色的显著值加权平均来代替每个颜色(以 L*a*b* 距离测量)的显著值。选择m=n/4。个最近的颜色作为代表来改善颜色c的显著值:
    S ′ ( c ) = 1 ( m − 1 ) T ∑ i = 1 n ( T − D ( c , c i ) ) S ( c i ) (4) S'(c) = \frac{1}{(m -1)T} \sum_{i=1}^n(T-D(c,c_i))S(c_i) \tag{4} S(c)=(m1)T1i=1n(TD(c,ci))S(ci)(4)

    其中, T = ∑ i = 1 m D ( c , c i ) T = \sum_{i=1}^mD(c,c_i) T=i=1mD(c,ci)是颜色c和它的m个最近的颜色 C i C_i Ci之间的距离之和,归一化因数来自公式: ∑ i = 1 m ( T − D ( c , c i ) ) = ( m − 1 ) T \sum_{i=1}^m(T-D(c,c_i)) = (m-1)T i=1m(TD(c,ci))=(m1)T
    在最后的实现中,在RGB颜色空间中进行颜色量化,每个色彩空间均匀量化为12等分,共 1 2 3 12^3 123色彩种类。再在Lab颜色空间中进行距离度量。

算法实现流程:
1、量化颜色通道。找出图像中一共有多少种颜色以及对应的像素总数。
2、按照像素总数从大到小排序,并同时记录相应颜色。
3、找出像素数目覆盖图像不小于95%的高频颜色,以及其他的不高于5%的颜色种类,假设高频颜色共有maxnum种。
4、把低频颜色的像素归类到与它lab颜色距离相距最近的高频颜色中。
5、在maxnum种颜色中,计算颜色i到所有其他颜色j的颜色距离。并按照距离从小到大排序,记录相应j的颜色种类。
6、按照方程(3)计算每一种颜色的显著值。根据第5步,可以找到距离颜色i相距最近的m种颜色,从而可以根据方程(4)计算每种颜色显著值,即最终的显著值。
7、为图像中每一个像素分配显著值。像素(i,j)是什么颜色,就赋予它相应颜色的显著值。
8、至此,显著图生成。进行归一化、线性空间滤波。

关于色彩量化:理论请点击github代码请点击
中位颜色切割:github代码请点击
通过随机选择调色板或使用K均值来执行颜色量化:github代码请点击

演示代码:各位老铁这个代码复现断断续续花了我2周,工作忙。我这里放出HC核心代码,特别鸣谢https://mmcheng.net/salobj/。
以下代码使用的颜色量化代码Quantize()请点击。
测试了一张1920*1080分辨率1.1M的图片,颜色量化耗时1.20s,总耗时:1.35s。待优化。

import cv2, time
import numpy as np
from scipy.spatial.distance import pdist, squareform
from temp_003 import Quantize



def GetHC(img_float,delta=0.25):
    t1 = time.time()
    binN, idx1i, binColor3f, colorNums1i = Quantize(img_float)                 # 颜色量化
    t2 = time.time()
    print("Quantize time is :", t2 - t1, 'seconds')
    binColor3f = cv2.cvtColor(binColor3f, cv2.COLOR_BGR2Lab)                   # 颜色空间:BGR2Lab
    weight1f = np.zeros(colorNums1i.shape, np.float32)
    cv2.normalize(colorNums1i.astype(np.float32), weight1f, 1, 0, cv2.NORM_L1) # 相邻色彩相关权重

    binColor3f_reshape = binColor3f.reshape(-1, 3)[:binN]
    similar_dist = squareform(pdist(binColor3f_reshape))
    similar_dist_sort = np.sort(similar_dist)
    similar_dist_argsort = np.argsort(similar_dist)

    weight1f = np.tile(weight1f, (binN, 1))
    color_weight_dist = np.sum(np.multiply(weight1f, similar_dist), axis=1)    # 颜色距离的权重分配

    colorSal = np.zeros((1, binN), np.float64)
    if colorSal.shape[1] < 2:
        return
    tmpNum = int(np.round(binN * delta))                                       # tmpNum 占比0.25的变化的颜色值数量
    n = tmpNum if tmpNum > 2 else 2

    similar_nVal = similar_dist_sort[:, :n]
    totalDist_similar = np.sum(similar_nVal, axis=1)
    every_Dist = np.tile(totalDist_similar[:, np.newaxis], (1, n)) - similar_nVal

    idx = similar_dist_argsort[:, :n]
    val_n = np.take(color_weight_dist,idx)                                    # 获取占比前0.25的颜色权重距离

    valCrnt = np.sum(val_n[:, :n] * every_Dist, axis=1)
    newSal_img = valCrnt / (totalDist_similar * n)
    cv2.normalize(newSal_img, newSal_img, 0, 1, cv2.NORM_MINMAX)              # 归一化
    salHC_img = np.take(newSal_img,idx1i)
    cv2.GaussianBlur(salHC_img, (3, 3), 0, salHC_img)
    cv2.normalize(salHC_img, salHC_img, 0, 1, cv2.NORM_MINMAX)
    return salHC_img


if __name__ == "__main__":
    img3_int = cv2.imread(r"C:\Users\xxx\Desktop\112.png")
    img3_float = img3i.astype(np.float32)
    img3_float = img3_float / 255.0
    t1 = time.time()
    sal = HC(img3_float)
    t2 = time.time()
    print("Total time is :",t2-t1,'seconds')
    cv2.imwrite(r"C:\Users\xxx\Desktop\1121.png",(sal*255).astype(np.int32))
    cv2.imshow('sal_', sal)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
'''
Total time is : 0.2723052501678467 seconds
'''

在这里插入图片描述
在这里插入图片描述

2.2 基于区域的对比度方法(region-based contrast 简称RC)

上面讲了HC直方图的对比度方法,然而 区域与空间关系在显著性检测中也扮演重要作用,高对比邻近周围通常是显著性区域一个很强的证据,HC是计算像素级别的显著性值,计算开销比较大,基于区域对比度分析的显著性检测通过定义每个区域与其他区域的相似度权重得到区域显著性值,完成显著性检测。RC做法需要首先生成区域,通过基于图的图像分割得到很多图像区域,对一个区域计算显著性值:
S ( r k ) = ∑ r k ≠ r i w ( r i ) D ( r k , r i ) (5) S(r_k) = \sum_{r_k \neq r_i}^{}w(r_i)D(r_k,r_i) \tag{5} S(rk)=rk=riw(ri)D(rk,ri)(5)
其中 w ( r i ) w(r_i) w(ri) 表示区域 r i r_i ri 的权重, D ( , ) D(,) D(,)表示两个区域之间的颜色距离,其中颜色距离定义如下:
D r ( r 1 , r 2 ) = ∑ i = 1 n 1 ∑ j = 1 n 2 f ( c 1 , i ) f ( c 2 , i ) D r ( c 1 , i , c 2 , j ) (6) D_r(r_1,r_2) = \sum_{i=1}^{n1} \sum_{j=1}^{n2}f(c_1,i)f(c_2,i)D_r(c_{1,i},c_{2,j}) \tag{6} Dr(r1,r2)=i=1n1j=1n2f(c1,i)f(c2,i)Dr(c1,i,c2,j)(6)
使用稀疏直方图可以加速上述计算。
考虑到不同距离远近对当前区域的影响,基于高斯核函数权重生成,进行适当的权重区域合并得到改进的显著性值计算:
S ( r k ) = ∑ r k ≠ r i exp ⁡ ( − D s ( r k , r i ) σ s 2 ) w ( r i ) D r ( r k , r i ) (7) S(r_k) = \sum_{r_k \neq r_i} \exp \left ( -\frac{D_s(r_k,r_i)}{\sigma_s^2} \right )w(r_i)D_r(r_k,r_i) \tag{7} S(rk)=rk=riexp(σs2Ds(rk,ri))w(ri)Dr(rk,ri)(7)
其中: σ s \sigma_s σs 控制空间权重影响, D s D_s Ds表示两个区域中心之间的欧氏距离。作者论文采用 σ s = 0.4 \sigma_s = 0.4 σs=0.4,像素坐标归一化到0~1之间。
演示代码【请点击】

2.3 显著性检测 FT

图像在频率域可以分成低频部分和高频部分。低频部分反映了图像的整体信息,如物体的轮廓,基本的组成区域。高频部分反映了图像的细节信息,如物体的纹理。显著性区域检测用到的更多的是低频部分的信息。在实际进行计算时,FT方法使用窗口5*5的高斯平滑来实现对最高频的舍去。
论文请点击
像素的显著性可以用下面公式计算:
S ( p ) = ∣ ∣ I μ − I w h c ( p ) ∣ ∣ S(p) = ||I_{\mu} - I_{w_{hc}}(p)|| S(p)=IμIwhc(p)

其中, I μ I_{\mu} Iμ为图像的平均特征,使用 Lab 颜色特征,后一项为像素p在高斯平滑后的Lab颜色特征,||.||为L2范式,即计算前一项和后一项在了Lab颜色空间的欧氏距离。

FT算法过程
1、对图像进行 5*5 的高斯平滑。
2、转换颜色空间。RGB颜色空间转换为CIELAB颜色空间。
3、计算整幅图片的 l、a、b的平均值。
4、按照算法中的公式,计算每个像素l、a、b值同图像三个l、a、b均值的欧氏距离。得到显著图
5、归一化。图像中每个像素的显著值除以最大的那个显著值。得到最终的显著图。
import cv2
import matplotlib.pyplot as plt
import numpy as np

img = cv2.imread(r"C:\Users\xxx\Desktop\002.png")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = cv2.GaussianBlur(img,(5,5), 0)
gray_lab = cv2.cvtColor(img, cv2.COLOR_RGB2LAB)

l_mean = np.mean(gray_lab[:,:,0])
a_mean = np.mean(gray_lab[:,:,1])
b_mean = np.mean(gray_lab[:,:,2])
lab = np.square(gray_lab- np.array([l_mean, a_mean, b_mean]))
lab = np.sum(lab,axis=2)
lab = lab/np.max(lab)

plt.imshow(lab, cmap='gray')
plt.show()

在这里插入图片描述

2.4 显著性检测 AC

论文地址:http://www.cs.toronto.edu/~strider/publications/AES_ICVS08.pdf
AC算法也是Achanta等提出的,与FT算法类似,只是在求欧式距离时使用的均值不再是整幅图像的均值,而是通过计算一个感知单元在不同邻域上的局部对比度来实现多尺度显著性计算。内部区域R1,外部区域R2,计算R1和R2的局部对比度时,通过改变R2的大小实现多尺度显著性计算。即:选取不同大小邻域内的均值(三种大小)分别求取欧式距离,再相加得到
该方法是基于局部对比度的。采用Lab颜色空间计算距离。
在这里插入图片描述
感知单元R1可以是一个像素或一个像素块,其邻域为R2,(R1)R2所包含的所有像素的特征值的平均值作为(R1)R2的特征值。设像素p为R1和R2的中心,p所在位置局部对比度为:
c i , j = D [ ( 1 N 1 ∑ p = 1 N 1 v p ) , ( 1 N 2 ∑ p = 1 N 2 v q ) ] c_{i,j} = D\left [ \left ( \frac{1}{N_1}\sum_{p=1}^{N_1} \mathbf{v}_p \right ) ,\left ( \frac{1}{N_2}\sum_{p=1}^{N_2}\mathbf{v}_q \right ) \right ] ci,j=D[(N11p=1N1vp),(N21p=1N2vq)]

算法实现过程如下:
1.读取图像,进行高斯滤波,并转换到lab空间
2.分别求取该点附近h/8邻域lab空间的均值L1、A1、B1。以及h/4邻域lab空间的均值L2、A2、B2和h/2邻域lab空间的均值L3、A3、B3。
3.数据融合:
S 1 = ( l − L 1 ) 2 + ( a − A 1 ) 2 + ( b − B 1 ) 2 S1=(\mathrm{l}-L1)^2 + (a-A1)^2 + (b-B1)^2 S1=(lL1)2+(aA1)2+(bB1)2
S 2 = ( l − L 2 ) 2 + ( a − A 2 ) 2 + ( b − B 2 ) 2 S2=(l-L2)^2 + (a-A2)^2+(b-B2)^2 S2=(lL2)2+(aA2)2+(bB2)2
S 3 = ( l − L 3 ) 2 + ( a − A 3 ) 2 + ( b − B 3 ) 2 S3=(l-L3)^2+(a-A3)^2+(b-B3)^2 S3=(lL3)2+(aA3)2+(bB3)2
4.显著图: S = S 1 + S 2 + S 3 S=S1+S2+S3 S=S1+S2+S3

代码有点问题,待修改

import numpy as np
import time
import cv2


def AC(imagelab):
    height, width = imagelab.shape[:2]
    medical = min(height, width)
    offset1 = int(medical / 2)
    offset2 = int(medical / 4)
    offset3 = int(medical / 8)
    l = imagelab[:, :, 0]
    a = imagelab[:, :, 1]
    b = imagelab[:, :, 2]

    sm = np.zeros((height, width),dtype=np.float32)

    for j in range(height):
        y11 = max(1, j - offset1)
        y12 = min(j + offset1,height)

        y21 = max(1, j - offset2)
        y22 = min(j + offset2, height)

        y31 = max(1, j - offset3)
        y32 = min(j + offset3, height)
        for k in range(width):
            x11 = max(1, k - offset1)
            x12 = min(k + offset1, width)
            x21 = max(1, k - offset2)
            x22 = min(k + offset2, width)
            x31 = max(1, k - offset3)
            x32 = min(k + offset3, width)
            lm1 = np.mean(l[y11:y12, x11: x12])
            am1 = np.mean(a[y11:y12, x11: x12])
            bm1 = np.mean(b[y11:y12, x11: x12])

            lm2 = np.mean(l[y21:y22, x21: x22])
            am2 = np.mean(a[y21:y22, x21: x22])
            bm2 = np.mean(b[y21:y22, x21: x22])
            lm3 = np.mean(l[y31:y32, x31: x32])
            am3 = np.mean(a[y31:y32, x31: x32])
            bm3 = np.mean(b[y31:y32, x31: x32])

            cv1 = (l[j, k] - lm1)**2 + (a[j, k] - am1)**2 + (b[j, k] - bm1)**2
            cv2 = (l[j, k] - lm2)**2 + (a[j, k] - am2)**2 + (b[j, k] - bm2)**2
            cv3 = (l[j, k] - lm3)**2 + (a[j, k] - am3)**2 + (b[j, k] - bm3)**2
            sm[j, k] = cv1 + cv2 + cv3
    return sm


if __name__ == '__main__':
    file = r"C:\Users\xxx\Desktop\006.png"

    start = time.time()
    image_gray = cv2.imread(file)
    imagelab = cv2.cvtColor(image_gray,cv2.COLOR_RGB2Lab)

    t1 = time.time()
    result = AC(imagelab)
    t2 = time.time()
    print('cost time:',t2-t1)
    cv2.imshow('result',result)
    cv2.waitKey()
    cv2.destroyAllWindows()

至此:欢迎点击我的github项目

参考与鸣谢
https://mmcheng.net/salobj/

AC算法:
http://blog.sina.com.cn/s/blog_c303278b0101aism.html
https://blog.csdn.net/qq_22238021/article/details/72876410

鲁棒背景检测的显著性优化
https://blog.csdn.net/ZHANGWENJUAN1995/article/details/95043177
https://blog.csdn.net/dayenglish/article/details/51275128#commentsedit

图像显著性检测论文及代码汇总
https://github.com/mhaut/pResNet-HSI

FT算法:
https://blog.csdn.net/weixin_33836874/article/details/86130758
全局对比对:https://mmcheng.net/salobj/
基于深度学习的显著性检测:https://blog.csdn.net/u010736662/article/details/88930849
Matlab中angle函数内容详解:https://blog.csdn.net/cao_jie_xin/article/details/91128887

综述:https://blog.csdn.net/xioamoon/article/details/80817236
HC:https://blog.csdn.net/weixin_34185512/article/details/86197786
FT https://blog.csdn.net/qq_22238021/article/details/72884492
参考文献
[1] Itti L, Koch C, Niebur E. A model ofsaliency-based visual attention for rapid scene analysis[M]. IEEE ComputerSociety, 1998.
[2] Hou X, Zhang L. Saliency Detection: ASpectral Residual Approach[C]// Computer Vision and Pattern Recognition, 2007.CVPR '07. IEEE Conference on. IEEE, 2007:1-8.
[3] Liu T,Zheng N, Wei, et al. Video attention: Learning to detect a salient objectsequence[C]// International Conference on Pattern Recognition. IEEE, 2009:1-4.
[4] AchantaR, Hemami S, Estrada F, et al. Frequency-tuned salient region detection[J].2009, 22(9-10):1597-1604.
[5] Cheng MM, Zhang G X, Mitra N J, et al. Global Contrast Based Salient RegionDetection[C]. Computer Vision and Pattern Recognition. IEEE, 2011:409-416.
[6] PerazziF, Krähenbühl P, Pritch Y, et al. Saliency filters: Contrast based filteringfor salient region detection[C]// Computer Vision and Pattern Recognition.IEEE, 2012:733-740.
[7] He S,Lau R W, Liu W, et al. SuperCNN: A Superpixelwise Convolutional Neural Networkfor Salient Object Detection[J]. International Journal of Computer Vision,2015, 115(3):330-344.
[8] Hou Q,Cheng M M, Hu X, et al. Deeply Supervised Salient Object Detection with ShortConnections[J]. IEEE Transactions on Pattern Analysis & MachineIntelligence, 2016, PP(99):1-1.
基于谱残差的显著性检测:Saliency Detection: A Spectral Residual Approach

评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SongpingWang

你的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值