我正在尝试实现光谱残差方法以进行显着性检测,如本文所述:
http://www.klab.caltech.edu/~xhou/papers/cvpr07.pdf

Matlab代码中有一个参考实现,取自他们的网站:
http://www.klab.caltech.edu/~xhou/projects/spectralResidual/spectralresidual.html

clear
clc
%% Read image from file
inImg = im2double(rgb2gray(imread('yourImage.jpg')));
inImg = imresize(inImg, 64/size(inImg, 2));
%% Spectral Residual
myFFT = fft2(inImg);
myLogAmplitude = log(abs(myFFT));
myPhase = angle(myFFT);
mySpectralResidual = myLogAmplitude - imfilter(myLogAmplitude, fspecial('average', 3),'replicate');
saliencyMap = abs(ifft2(exp(mySpectralResidual + i*myPhase))).^2;
%% After Effect
saliencyMap = mat2gray(imfilter(saliencyMap, fspecial('gaussian', [10, 10], 2.5)));
imshow(saliencyMap);


我尝试使用CImg将其转换为C ++。
我失败的地方在这里:

myPhase = angle(myFFT);


和这里

saliencyMap = abs(ifft2(exp(mySpectralResidual + i*myPhase))).^2;


这是我的代码:

#include <CImg.h>
#include <iostream>
using namespace cimg_library;

int main() {

  CImg<unsigned char> image("img2.jpg");

  CImg<float> mask(3,3,1,1,1.0/9.0);

  image.resize(64,64);

  CImgList<float> myFFT = image.get_FFT();

  const CImg<float> MyLogAmplitude = ((myFFT[0].get_pow(2) +  myFFT[1].get_pow(2)).get_sqrt()).get_log(); //Magnitude

  const CImg<float> MyPhase = myFFT[0].get_atan2(myFFT[1]);

  const CImg<float> A = MyLogAmplitude.get_convolve(mask);

  const CImg<float> MySpectralResidual = MyLogAmplitude-A;

  CImgList<float> tmp = CImgList<float>(MyResidual.get_exp(),MyPhase);

  CImgList<float> MySaliencyMap = tmp.get_FFT(true);

  CImgDisplay  draw_disp0(MySaliencyMap,"Image");


  while (!draw_disp0.is_closed()) {

    draw_disp0.wait();

  }
  return 0;
}


有人看到明显的错误吗?

最佳答案

我想我可以在您的代码中看到两个错误:


首先,对MyPhase的atan2()调用将参数取反。应该写成

const CImg MyPhase = myFFT [1] .get_atan2(myFFT [0]);


(但这在这里可能不是什么大问题)。


其次,更严重的是,您正在对编码为(振幅,相位)的一对复数值进行逆FFT,这不是CImg期望的,因为FFT()函数假定您输入了(实,虚)对图片。这可能会对结果产生巨大的影响。

关于c++ - 使用CImg的C++中的光谱残留显着性检测,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15548906/

10-11 22:46