视觉显著性python_OpenCV—python图像显著性检测算法—
HCRCLCFT
⽂章⽬录
⼀、显著性检测研究现状
⼆、基于谱残差法的显著性检测
三、基于全局对⽐度图像显著性检测(LC)
2.1 基于直⽅图对⽐度的显著性检测(HC)
2.2 基于区域的对⽐度⽅法(region-bad contrast 简称RC)
2.3 显著性检测 FT
2.4 显著性检测 AC
⼀、显著性检测研究现状
建⽴计算模型进⾏显著性检测。
思想是:对输⼊图像⾸先进⾏多个特征通道和多尺度分解,再进⾏滤波得到特征图,再对特征图融合得到最终显著图。
2007年,Hou X等⼈提出SR⽅法[2],该⽅法利⽤谱残差模型进⾏显著性检测,该⽅法认为图像的信息都包含在图像的幅度谱信息中,因此从图像的幅度谱中减去先验知识的幅度谱,剩下的就是显著部分的幅度谱,进⽽得到显著区域。
⼀些经典算法,如Itti,SR,FT,GBVS的代码和显著性检测的数据集整理
相位谱法。
将显著性检测定义为⼆元分割问题来处理
2007年,T.Liu等⼈提出⼀种将显著性检测作为图像分割问题来处理的思路[3],⾃此出现了⼤量的显著性检测模型,掀起了显著性检测的第⼆波热潮。
2009年,Achanta R等⼈提出FT模型来进⾏显著性检测[4],此模型可以输出具有明确定义的边界的全分辨率显著图,通过保留来⾃原始图像的更多频率内容来保留这些边界。此⽅法利⽤颜⾊和亮度特征的中央周边算⼦来得到显著图,实施简单,计算效率⾼
2011年,Cheng M M等⼈提出了⼀种基于区域对⽐度的显著对象提取算法[5]。该算法同时评估全局对⽐度差异和空间加权相⼲性得分来确定显著性区域,此算法是简单,⾼效,多尺度的,并且可以⽣成全分辨率,⾼质量的显著图。这些显著图被进⼀步⽤于初始化GrabCut的新颖迭代版本,以进⾏⾼质量的显著对象分割。
2012年,Perazzi F等⼈重新考虑了之前⽅法的⼀些设计选择,并提出了基于对⽐度的显著性检测的概念清晰且直观的算法[6]。此算法由四个基本步骤组成:(1)将给定的图像分解为紧凑且感知均匀的元素,以抽象不必要的细节;(2)基于这种抽象,计算两个对⽐度度量,评估这些元素的独特性和空间分布;(3)从元素对⽐度中推导出显著性度的度量,该度量⽣成⼀个像素精确的显著图,它统⼀覆盖感兴趣的对象并始终分离前景和背景;(4)⽂章表明,完整的对⽐度和显著性估计可以使⽤⾼维⾼斯滤波器统⼀制定,这有助于此⽅法的概念简单性,并使其具有线性复杂性的⾼效实施。
基于深度学习进⾏显著性检测
2015年,开始引⼊CNN进⾏显著性检测,与基于对⽐线索的⼤多数经典⽅法不同,基于CNN的⽅法消除了对⼿⼯特征的需求减轻了对中⼼偏见知识的依赖,因此被许多科研⼈员所采⽤。基于CNN的模型通常包含数⼗万个可调参数和具有可变接受字段⼤⼩的神经元。神经元具有较⼤的接受范围提供全局信息,可以帮助更好地识别图像中最显著的区域。CNN所能实现前所未有的性能使其逐渐成为显著性物体检测的主流⽅向。
2015年,He S等⼈提出了⼀种新的超像素卷积神经⽹络⽅法,称为SuperCNN,可以有效地学习显著性的内部表⽰[7]。与传统的卷积⽹络相⽐,SuperCNN有四个主要特性:⾸先,能够学习分层对⽐度特征;第⼆,恢复了超级像素之间的上下⽂信息;第三,受益于超像素机制,对密集标记的图像所需的预测数量⼤⼤减少;第四,通过利⽤多尺度⽹络结构检测显著性区域可以不受区域⼤⼩的约束。
2017年,Hou Q等⼈提出了⼀种新的显著性检测⽅法,在HED(Holistically-Nested EdgeDetection)的基础上,增加了⼀种⾼层信息指导低层信息的Skip Layer结构,从⽽构建了⼀种简单,有效,快速的端对端的显著性物体检测⽹络结构[8]。此⽅法注意到了边缘检测、语义分割和显著性检测⼏个领域的⼀些共性和最新的趋势:
从局部分析逐渐过渡到的全局分析,
HED中的Skip layer结构对⾼质量的输出很有帮助,
显式的让⾼层语义信息去指导和帮助低层语义信息更好的定位显著性物体位置的同时精确的确定其范围很有帮助。
总⽽⾔之:
显著性就是可以快速引起你注意的对象或者物体,在图像或者视频中显著性检测的结果往往是图像或
者视频中对象,在神经学科中显著性检测被描述为注意⼒机制,⽬的是聚焦或者缩⼩看到的对象场景重要部分,显著性检测可以⾃动处理图像中对象表⽰。
⽣物⽪层对图像对⽐度⽐较敏感,通过图像对⽐度可以实现图像显著性特征提取。
⼆、基于谱残差法的显著性检测
从信息理论⾓度:信息可分为冗余部分和变化部分。⼈们的视觉对变化部分更敏感。视觉系统的⼀个基本原则就是抑制对频繁出现的特征的响应,同时对⾮常规的特征保持敏感。那么就将图像分为如下两部分:
作者对图像的 log \loglog 频谱发下了如下规律(log是⾃然对数): E { A ( f ) } ∝ 1 / f E\{ \mathcal{A}(f) \} \propto 1/fE{A(f)}∝1/f ⼤量图像的 log \loglog 频谱的平均值是和频率呈现正⽐关系的。(左下图)
如图可知⼤量图像的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 \loglog 曲线满⾜局部线性条件,所以⽤局部平均滤波器 h n ( f ) h_n(f)hn(f)对其进⾏平滑,获得log
\loglog谱的⼤致形状。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)∗{F−1[exp(R(f)+iP(f))]2}
参数说明:
F FF 代表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(Θ) \en
荠菜饺子怎么做d{aligned}exp(r+i∗Θ)
=exp(r)∗(cos(Θ)+i∗sin(Θ))=exp(r)∗cos(Θ)+i∗exp(r)∗sin(Θ)
Θ ΘΘ是相位谱。其实 Θ ΘΘ 的正余弦也可由傅⾥叶谱的实部和虚部求出:s i n ( Θ ) = I m a g e I m / A m p l i t u d e \rm sin(Θ) = ImageIm/Amplitudesin(Θ)=ImageIm/Amplitude; c o s ( Θ ) = I m a g e R e / A m p l i t u d e \rm cos(Θ) =
ImageRe/Amplitudecos(Θ)=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]
ba = cv2.magnitude(re, im)
# 对数谱 -> 平滑曲线 -> 显著性余谱
LogAmplitude = cv2.log(ba)
blur = cv2.blur(LogAmplitude, (3, 3))
residual = LogAmplitude - blur
# 指数还原对数谱
residual = p(residual)
# 求原频域上实虚的夹⾓, 利⽤夹⾓还原实虚
Sine = im / ba
Cosine = re / ba
tmp1_re = residual * Cosine
tmp2_im = residual * Sine
# 傅⾥叶逆变换
ifourier = ((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:\Urs\xxx\Desktop\002.png',0)快乐你懂的
res = visual_saliency_detection(img)
cv2.imshow('res',res)
cv2.waitKey(0)
cv2.destroyAllWindows()
三、基于全局对⽐度图像显著性检测(LC)
计算某个像素在整个图像上的全局对⽐度,即该像素与图像中其他所有像素在颜⾊上的距离之和作为该像素的显著值。
图像 I II 中某个像素 I k I_kIk的显著值计算如下:
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)=∀Ii∈I∑∣∣Ik−Ii∣∣
其中I i I_iIi的取值范围为 [ 0 , 255 ] [0, 255][0,255], 即为灰度值。
给定⼀张图像,每个像素I k I_kIk的颜⾊值已知。假定I k = a m I_k = a_mIk=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)=∣∣am−a0∣∣+∣∣am−a1∣∣+...+∣∣am−an∣∣=n=0∑255f n
∣∣am−an∣∣
其中,f n f_nfn表⽰图像中第n nn个像素的频数,以直⽅图的形式表⽰。
代码演⽰,【参考原代码请点击】 ,我使⽤了numpy重写了原函数,优化了代码运⾏时间,图⽚分辨率越⼤越省时间
梦见去考试
import numpy as np
import time
import cv2
def diag_sym_matrix(k=256):
ba_matrix = np.zeros((k,k))
ba_line = np.array(range(k))
ba_matrix[0] = ba_line
for i in range(1,k):
ba_matrix[i] = np.roll(ba_line,i)
ba_matrix_triu = np.triu(ba_matrix)
return ba_matrix_triu + ba_matrix_triu.T
def cal_dist(hist):
Diag_sym = diag_sym_matrix(k=256)
hist_reshape = shape(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 = shape(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
nfc是什么功能
if __name__ == '__main__':
file = r"C:\Urs\xxx\Desktop\003.png"
start = time.time()
image_gray = cv2.imread(file, 0)
saliency_image = LC(image_gray)
cv2.imwrite(r"C:\Urs\xxx\Desktop\006_1.png",saliency_image*255)
end = time.time()
print("Duration: %.2f conds." % (end - start))
cv2.imshow("gray saliency image", saliency_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
'''
Duration: 0.08 conds.
'''
上述代码中 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)=∀Ik∈I∑D(Ik,Ii)(1)
其中D ( I k , I i ) D(I_k,I_i)D(Ik,Ii)是空间 L*a*b 中两个像素的颜⾊距离度量,上式经过扩展像素等级变如下⽅程:表格斜线怎么画