图像显著性检测-谱残差方法 c++ opencv实现
2016-10-25 17:19
1136 查看
谱残差方法只对背景单一,目标突出的图像效果好。不适用于复杂纹理背景的图像。下面是c++结合opencv库实现的代码:
#include "stdafx.h"
#include <opencv2\opencv.hpp>
#include <cv.h>
#include <highgui.h>
using namespace cv;
using namespace std;
int _tmain(int argc,char** argv)
{
//读取图片
const char *filename = (argc >=2 ? argv[1]:"1.jpg" );
Mat I = imread(filename);
if (I.empty())
{
return -1;
}
//彩色图转成灰色图
if (I.channels()==3)
{
cvtColor(I,I,CV_RGB2GRAY);
}
Mat planes[] = { Mat_<float>(I), Mat::zeros(I.size(), CV_32F) };
Mat complexI;
//构造复数双通道矩阵
merge(planes,2,complexI);
//快速傅里叶变换
dft(complexI,complexI);
Mat mag, pha, mag_mean;
Mat Re, Im;
//分离复数到实部和虚部
Re = planes[0]; //实部
split(complexI, planes);
Re = planes[0]; //实部
Im = planes[1]; //虚部
//计算幅值
magnitude(Re, Im, mag);
//计算相角
phase(Re, Im, pha);
float *pre, *pim, *pm, *pp;
//对幅值进行对数化
for (int i = 0; i<mag.rows; i++)
{
pm = mag.ptr<float>(i);
for (int j = 0; j<mag.cols; j++)
{
*pm = log(*pm);
pm++;
}
}
//对数谱的均值滤波
blur(mag, mag_mean, Size(5, 5));
//求取对数频谱残差
mag = mag - mag_mean;
for (int i = 0; i<mag.rows; i++)
{
pre = Re.ptr<float>(i);
pim = Im.ptr<float>(i);
pm = mag.ptr<float>(i);
pp = pha.ptr<float>(i);
for (int j = 0; j<mag.cols; j++)
{
*pm = exp(*pm);
*pre = *pm * cos(*pp);
*pim = *pm * sin(*pp);
pre++;
pim++;
pm++;
pp++;
}
}
Mat planes1[] = { Mat_<float>(Re), Mat_<float>(Im) };
//重新整合实部和虚部组成双通道形式的复数矩阵
merge(planes1, 2, complexI);
// 傅立叶反变换
idft(complexI, complexI, DFT_SCALE);
//分离复数到实部和虚部
split(complexI, planes);
Re = planes[0];
Im = planes[1];
//计算幅值和相角
magnitude(Re, Im, mag);
for (int i = 0; i<mag.rows; i++)
{
pm = mag.ptr<float>(i);
for (int j = 0; j<mag.cols; j++)
{
*pm = (*pm) * (*pm);
pm++;
}
}
GaussianBlur(mag, mag, Size(7, 7), 2.5, 2.5);
Mat invDFT, invDFTcvt;
//归一化到[0,255]供显示
normalize(mag, invDFT, 0, 255, NORM_MINMAX);
//转化成CV_8U型
invDFT.convertTo(invDFTcvt, CV_8U);
imshow("SpectualResidual", invDFTcvt);
imshow("Original Image", I);
waitKey(0);
return 0;
}
相关文章推荐
- 基于C++和OpenCv的SIFT_图像局部特征检测算法代码的实现
- 简单的图像显著性区域特征提取方法-----opencv实现LC,AC,FT
- Android(安卓)开发通过NDK调用JNI,使用opencv做本地c++代码开发配置方法实现边缘检测代码(2)
- 图像灰度化的三种方法及matlab,c++,python实现
- 图像相似度计算之哈希值方法OpenCV实现
- OpenCV之imgproc 模块. 图像处理(2)实现自己的线性滤波器 给图像添加边界 Sobel 导数 Laplace 算子 Canny 边缘检测
- OpenCV实现显著性检测中的谱残差法(Spectral Residual Method)涉及到了傅立叶正反变换
- 图像特征检测描述(一):SIFT、SURF、ORB、HOG、LBP特征的原理概述及OpenCV代码实现
- Android(安卓)开发通过NDK调用JNI,使用opencv做本地c++代码开发配置方法 边缘检测 范例代码
- opencv下haar方法实现对视频文件的人脸检测、跟踪
- 四种比较简单的图像显著性区域特征提取方法原理及实现
- 图像显著性检测的方法总结
- OpenCV使用Sobel滤波器实现图像边缘检测
- 图像相似度计算之直方图方法OpenCV实现
- 用形态学的方法实现图像的角点检测
- 《算法设计与分析基础》三种求最大公约数的方法C++实现--欧几里德辗转相除、连续整数检测、质因数相乘
- 图像相似度计算之哈希值方法OpenCV实现
- Android(安卓)开发通过NDK调用JNI,使用opencv做本地c++代码开发配置方法 边缘检测 范例代码
- OpenCV图像识别、移动侦测、边缘检测实现及 cvCopy()和cvCloneImage()的区别
- 运用特征脸方法的基于Opencv的猫脸检测实现