小言_互联网的博客

在OpenCV里实现谱残差的显著性检测

708人阅读  评论(0)

大家看到这个题目时,也许不知道这个东西有什么用,为什么要研究这个东西。其实显著性检测是比较有用的东西,因为它可以解决这三方面问题:一是快速的对象检测;二是广告市场,每个广告图片或视频做出来之后是否能突出相应的产品,就可以通过这个方法来检测制作广告是否成功;三是人工智能,要让机器人模拟人去看所有东西,这样才会感觉到人的注意力思维。其实应用的领域还有很多,比如用手机照相时,就可以动态地提示当前照片最显著性的突出部分,以便让人做不同的姿势调整,拍出更好的照片。

 

《Saliency Detection: A Spectral Residual Approach》是上交高材生侯晓迪在07年的CVPR上发表的一篇论文。这篇文章提出了一个图像视觉显著性的简单计算模型。这篇论文的核心思想如下:

从信息理论角度:信息可分为冗余部分和变化部分。人们的视觉对变化部分更敏感。视觉系统的一个基本原则就是抑制对频繁出现的特征的响应,同时对非常规的特征保持敏感。

 

作者对图像的log频谱进行了大量研究,发现大量图像的log频谱的平均值是和频率呈现正比关系的,如果再对log频谱进行一次log对数化,发现log-log曲线趋向直线化,其中不能直线部分正好就是一幅图像的显著性特点。因此只需要把log频谱进行局部平滑,然后与平滑前log频谱进行相减,就可以求出差异部分,这就是谱残差的基本原理。它采用下面的算法:

第一步对图像进行傅里叶变换,然后求振幅A(f);第二步对图像进行傅里叶变换,然后求相位P(f);第三步对振幅A(f)取对数,求出振幅对数L(f);第四步振幅对数L(f)平滑,并且求差R(f);第五步对谱残差R(f)求指数(逆运算),然后与相位P(f)重构显著性频域图像(注意:由欧拉公式可知,exp(r+i*Θ) = exp(r)*(cos(Θ) + i*sin(Θ)) = exp(r)*cos(Θ) + i*exp(r)*sin(Θ),Θ是相位谱),接着进行傅里叶逆变换,最后求出显著性振幅。要显示图像出来还需要进行高斯平滑、对比度提升、伽玛变换等处理。

 

下面采用OpenCV来实现这个过程:

#python 3.7.4,opencv4.1
#蔡军生 https://blog.csdn.net/caimouse/article/details/51749579
#
import numpy as np
import cv2
from matplotlib import pyplot as plt

def fftImg(src): #快速傅里叶变换
    h, w = src.shape[:2]
    # 获取优化的大小
    dft_M = cv2.getOptimalDFTSize(w)
    dft_N = cv2.getOptimalDFTSize(h)
    #拷贝到补充的数组
    dft_A = np.zeros((dft_N, dft_M, 2), dtype=np.float64)
    dft_A[:h, :w, 0] = src
    dft_A=cv2.dft(dft_A, flags = cv2.DFT_COMPLEX_OUTPUT, nonzeroRows=h)
    return dft_A

def mat2gray(saliencymap): #提高对比度,进行伽马变换
    saliencymap = np.round(np.power(saliencymap/np.max(saliencymap),0.5)*255)
    saliencymap = saliencymap.astype(np.uint8)
    return saliencymap
#主函数
image = cv2.imread('dft6.jpg',cv2.IMREAD_GRAYSCALE)

#计算图像的快速傅里叶变换
fft2 = fftImg(image)

#计算相位
phase = cv2.phase(fft2[:,:,0],fft2[:,:,1])

#计算傅里叶幅度谱的灰度级
logAmplitude = np.log(1.0 + cv2.magnitude(fft2[:,:,0],fft2[:,:,1]))
#对幅度谱的灰度级进行均值平滑
mySmooth = cv2.blur(logAmplitude,(3,3))
#残差的指数
esr = np.exp(logAmplitude - mySmooth)
#计算实部和虚部
newfft = cv2.merge([esr*np.cos(phase),esr*np.sin(phase)])
#逆变换
ifft2 = cv2.idft(newfft, flags=cv2.DFT_COMPLEX_OUTPUT)

#显著性
saliencyMap = np.power(cv2.magnitude(ifft2[:,:,0],ifft2[:,:,1]),2)

#对显著性进行高斯平滑,提高对比度,进行伽马变换
saliencyMap = mat2gray(cv2.GaussianBlur(saliencyMap,(3,3),2.5,2.5))

# 进行画图操作
plt.subplot(121),plt.imshow(image, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])

plt.subplot(122),plt.imshow(saliencyMap, cmap = 'gray')
plt.title('saliencyMap'), plt.xticks([]), plt.yticks([])
plt.show()

结果输出如下:

斑马照片结果

 

深圳地王大厦的结果

https://blog.csdn.net/caimouse/article/details/51749579

参考文件:https://blog.csdn.net/chenjiazhou12/article/details/39522467


转载:https://blog.csdn.net/caimouse/article/details/102473885
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场