我正在尝试实现光谱残差方法以进行显着性检测,如本文所述:
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/