先看几张效果图吧

效果图:

可以直接测试的代码:

头文件:

// Saliency.h: interface for the Saliency class.
//
//////////////////////////////////////////////////////////////////////
//===========================================================================
// Copyright (c) 2009 Radhakrishna Achanta [EPFL]
//===========================================================================

#if !defined(_SALIENCY_H_INCLUDED_)
#define _SALIENCY_H_INCLUDED_

#include <vector>
#include <cfloat>
using namespace std;

class Saliency
{
public:
Saliency();
virtual ~Saliency();

public:

void GetSaliencyMap(
const vector<unsigned int>& inputimg,//INPUT: ARGB buffer in row-major order
const int& width,
const int& height,
vector<double>& salmap,//OUTPUT: Floating point buffer in row-major order
const bool& normalizeflag = true);//false if normalization is not needed

private:

void RGB2LAB(
const vector<unsigned int>& ubuff,
vector<double>& lvec,
vector<double>& avec,
vector<double>& bvec);

void GaussianSmooth(
const vector<double>& inputImg,
const int& width,
const int& height,
const vector<double>& kernel,
vector<double>& smoothImg);

//==============================================================================
/// Normalize
//==============================================================================
void Normalize(
const vector<double>& input,
const int& width,
const int& height,
vector<double>& output,
const int& normrange = 255)
{
double maxval(0);
double minval(DBL_MAX);
{int i(0);
for( int y = 0; y < height; y++ )
{
for( int x = 0; x < width; x++ )
{
if( maxval < input[i] ) maxval = input[i];
if( minval > input[i] ) minval = input[i];
i++;
}
}}
double range = maxval-minval;
if( 0 == range ) range = 1;
int i(0);
output.clear();
output.resize(width*height);
for( int y = 0; y < height; y++ )
{
for( int x = 0; x < width; x++ )
{
output[i] = ((normrange*(input[i]-minval))/range);
i++;
}
}
}

};

#endif // !defined(_SALIENCY_H_INCLUDED_)

cpp:

// Saliency.cpp: implementation of the Saliency class.
//
//////////////////////////////////////////////////////////////////////
//===========================================================================
// Copyright (c) 2009 Radhakrishna Achanta [EPFL]
//===========================================================================

#include "Saliency.h"
#include <cmath>

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Saliency::Saliency()
{

}

Saliency::~Saliency()
{

}

//===========================================================================
/// RGB2LAB
//===========================================================================
void Saliency::RGB2LAB(
const vector<unsigned int>& ubuff,
vector<double>& lvec,
vector<double>& avec,
vector<double>& bvec)
{
int sz = int(ubuff.size());
lvec.resize(sz);
avec.resize(sz);
bvec.resize(sz);

for( int j = 0; j < sz; j++ )
{
int r = (ubuff[j] >> 16) & 0xFF;
int g = (ubuff[j] >> 8) & 0xFF;
int b = (ubuff[j] ) & 0xFF;

double xval = 0.412453 * r + 0.357580 * g + 0.180423 * b;
double yval = 0.212671 * r + 0.715160 * g + 0.072169 * b;
double zVal = 0.019334 * r + 0.119193 * g + 0.950227 * b;

xval /= (255.0 * 0.950456);
yval /= 255.0;
zVal /= (255.0 * 1.088754);

double fX, fY, fZ;
double lval, aval, bval;

if (yval > 0.008856)
{
fY = pow(yval, 1.0 / 3.0);
lval = 116.0 * fY - 16.0;
}
else
{
fY = 7.787 * yval + 16.0 / 116.0;
lval = 903.3 * yval;
}

if (xval > 0.008856)
fX = pow(xval, 1.0 / 3.0);
else
fX = 7.787 * xval + 16.0 / 116.0;

if (zVal > 0.008856)
fZ = pow(zVal, 1.0 / 3.0);
else
fZ = 7.787 * zVal + 16.0 / 116.0;

aval = 500.0 * (fX - fY)+128.0;
bval = 200.0 * (fY - fZ)+128.0;

lvec[j] = lval;
avec[j] = aval;
bvec[j] = bval;
}
}

//==============================================================================
/// GaussianSmooth
///
/// Blur an image with a separable binomial kernel passed in.
//==============================================================================
void Saliency::GaussianSmooth(
const vector<double>& inputImg,
const int& width,
const int& height,
const vector<double>& kernel,
vector<double>& smoothImg)
{
int center = int(kernel.size())/2;

int sz = width*height;
smoothImg.clear();
smoothImg.resize(sz);
vector<double> tempim(sz);
int rows = height;
int cols = width;
//--------------------------------------------------------------------------
// Blur in the x direction.
//---------------------------------------------------------------------------
{int index(0);
for( int r = 0; r < rows; r++ )
{
for( int c = 0; c < cols; c++ )
{
double kernelsum(0);
double sum(0);
for( int cc = (-center); cc <= center; cc++ )
{
if(((c+cc) >= 0) && ((c+cc) < cols))
{
sum += inputImg[r*cols+(c+cc)] * kernel[center+cc];
kernelsum += kernel[center+cc];
}
}
tempim[index] = sum/kernelsum;
index++;
}
}}

//--------------------------------------------------------------------------
// Blur in the y direction.
//---------------------------------------------------------------------------
{int index = 0;
for( int r = 0; r < rows; r++ )
{
for( int c = 0; c < cols; c++ )
{
double kernelsum(0);
double sum(0);
for( int rr = (-center); rr <= center; rr++ )
{
if(((r+rr) >= 0) && ((r+rr) < rows))
{
sum += tempim[(r+rr)*cols+c] * kernel[center+rr];
kernelsum += kernel[center+rr];
}
}
smoothImg[index] = sum/kernelsum;
index++;
}
}}
}

//===========================================================================
/// GetSaliencyMap
///
/// Outputs a saliency map with a value assigned per pixel. The values are
/// normalized in the interval [0,255] if normflag is set true (default value).
//===========================================================================
void Saliency::GetSaliencyMap(
const vector<unsigned int>& inputimg,
const int& width,
const int& height,
vector<double>& salmap,
const bool& normflag)
{
int sz = width*height;
salmap.clear();
salmap.resize(sz);

vector<double> lvec(0), avec(0), bvec(0);
RGB2LAB(inputimg, lvec, avec, bvec);
//--------------------------
// Obtain Lab average values
//--------------------------
double avgl(0), avga(0), avgb(0);
{for( int i = 0; i < sz; i++ )
{
avgl += lvec[i];
avga += avec[i];
avgb += bvec[i];
}}
avgl /= sz;
avga /= sz;
avgb /= sz;

vector<double> slvec(0), savec(0), sbvec(0);

//----------------------------------------------------
// The kernel can be [1 2 1] or [1 4 6 4 1] as needed.
// The code below show usage of [1 2 1] kernel.
//----------------------------------------------------
vector<double> kernel(0);
kernel.push_back(1.0);
kernel.push_back(2.0);
kernel.push_back(1.0);

GaussianSmooth(lvec, width, height, kernel, slvec);
GaussianSmooth(avec, width, height, kernel, savec);
GaussianSmooth(bvec, width, height, kernel, sbvec);

{for( int i = 0; i < sz; i++ )
{
salmap[i] = (slvec[i]-avgl)*(slvec[i]-avgl) +
(savec[i]-avga)*(savec[i]-avga) +
(sbvec[i]-avgb)*(sbvec[i]-avgb);
}}

if( true == normflag )
{
vector<double> normalized(0);
Normalize(salmap, width, height, normalized);
swap(salmap, normalized);
}
}

关于代码的使用说明:

This file explains the usage of Saliency.h and Saliency.cpp files. The former contains the declaration of the Saliency class and its member functions and the later contains the respective definitions.

Sample usage:

#include "Saliency.h"

void main()
{
// Assume we already have an unsigned integer buffer inputImg of
// inputWidth and inputHeight (in row-major order).
// Each unsigned integer has 32 bits and contains pixel data in ARGB
// format. I.e. From left to right, the first 8 bits contain alpha
// channel value and are not used in our case. The next 8 bits
// contain R channel value; the next 8 bits contain G channel value;
// the last 8 bits contain the B channel value.
//
// Now create a Saliency object and call the GetSaliencyMap function on it.

Saliency sal;
vector<double> salmap(0);
sal.GetSaliencyMap(inputImg, inputWidth, inputHeight, salmap);

// salmap is a floating point output (in row major order)
}

我自己写的测试主程序:

可以指定一个文件夹,程序保存该文件夹下所有jpg文件的处理结果

#include "Saliency.h"

#include <cv.h>
#include <cxcore.h>
#include <highgui.h>

#include "windows.h"

#include <iostream>
#include <cassert>
using namespace std;

int main(int argc,char** argv)
{
WIN32_FIND_DATAA FileData;
HANDLE hFind;

hFind = FindFirstFileA((LPCSTR)"Imgs/*.jpg",&FileData);
if (hFind == INVALID_HANDLE_VALUE) {
printf ("Invalid File Handle. GetLastError reports %d/n",
GetLastError ());
return (0);
}

Saliency sal;
vector<double> salmap(0);
while (FindNextFileA(hFind, &FileData)) {
cout<<FileData.cFileName<<endl;
string name("Imgs/");
name.append(FileData.cFileName);
IplImage* img=cvLoadImage(name.c_str());
if (!img) {
cout<<"failed to load image"<<endl;
break;
}
assert(img->nChannels==3);

vector<unsigned int >imgInput;
vector<double> imgSal;
//IplImage to vector
for (int h=0;h<img->height;h++) {
unsigned char*p=(unsigned char*)img->imageData+h*img->widthStep;
for (int w=0;w<img->width;w++) {
unsigned int t=0;
t+=*p++;
t<<=8;
t+=*p++;
t<<=8;
t+=*p++;
imgInput.push_back(t);
}
}
sal.GetSaliencyMap(imgInput, img->width, img->height, imgSal);
//vector to IplImage
int index=0;
IplImage* imgout=cvCreateImage(cvGetSize(img),IPL_DEPTH_64F ,1);
for (int h=0;h<imgout->height;h++) {
double*p=(double*)(imgout->imageData+h*imgout->widthStep);
for (int w=0;w<imgout->width;w++) {
*p++=imgSal[index++];
}
}

name.append(".saliency.jpg");

cvSaveImage(name.c_str(),imgout);
cvReleaseImage(&img);
cvReleaseImage(&imgout);
}

FindClose(&hFind);
return 0;
}

该代码的主页:http://ivrg.epfl.ch/supplementary_material/RK_ICIP2010/index.html

清华的最新研究:http://cg.cs.tsinghua.edu.cn/people/~cmm/saliency/

http://blog.csdn.net/onezeros/article/details/6299745#comments

目标检测之显著区域检测---国外的一个图像显著区域检测代码及其效果图 saliency region detection的更多相关文章

  1. Halcon从某一个图片以指定区域绘制到另一个图像

    ************************************************************* * Halcon从某一个图片以指定区域绘制到另一个图像 * Author: ...

  2. OPENCV图像特征点检测与FAST检测算法

    前面描述角点检测的时候说到,角点其实也是一种图像特征点,对于一张图像来说,特征点分为三种形式包括边缘,焦点和斑点,在OPENCV中,加上角点检测,总共提供了以下的图像特征点检测方法 FAST SURF ...

  3. OpenCV计算机视觉学习(13)——图像特征点检测(Harris角点检测,sift算法)

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 前言 ...

  4. Atitit 图像清晰度 模糊度 检测 识别 评价算法 源码实现attilax总结

    Atitit 图像清晰度 模糊度 检测 识别 评价算法 源码实现attilax总结 1.1. 原理,主要使用像素模糊后的差别会变小1 1.2. 具体流程1 1.3. 提升性能 可以使用采样法即可..1 ...

  5. Atitit 图像清晰度 模糊度 检测 识别 评价算法 原理

    Atitit 图像清晰度 模糊度 检测 识别 评价算法 原理 1.1. 图像边缘一般都是通过对图像进行梯度运算来实现的1 1.2. Remark: 1 1.3.  1.失焦检测. 衡量画面模糊的主要方 ...

  6. paper 27 :图像/视觉显著性检测技术发展情况梳理(Saliency Detection、Visual Attention)

    1. 早期C. Koch与S. Ullman的研究工作. 他们提出了非常有影响力的生物启发模型. C. Koch and S. Ullman . Shifts in selective visual ...

  7. [开发技巧]·HTML检测输入已完成自动填写下一个内容

    [开发技巧]·HTML检测输入已完成自动填写下一个内容 个人网站 --> http://www.yansongsong.cn 在上一个博客中简易实现检测输入已完成,我们实现了检测输入已完成,现在 ...

  8. 根据序列图像聚焦区域获取深度 Shape From Focus

    最为超新新新新鸟...我也不知道第一篇文章应该写什么..所以,把自己最近正在研究的东西报一下吧, 研究的东西其实也不算深奥,就是对一个图像序列中的每张图像进行检测,发现每张图片的聚焦清晰区域,找到这个 ...

  9. 四种简单的图像显著性区域特征提取方法-----AC/HC/LC/FT。

    四种简单的图像显著性区域特征提取方法-----> AC/HC/LC/FT. 分类: 图像处理 2014-08-03 12:40 4088人阅读 评论(4) 收藏 举报 salient regio ...

随机推荐

  1. Failed to apply plugin [id 'com.gradle.build-scan']

    把spring源码clone下来之后,使用gradle编译不通过,异常日志如下: FAILURE: Build failed with an exception. * Where: Build fil ...

  2. Linux 下查找并删除文件命令

    以查找和删除mp3为扩展的文件为例: find . -name "*.mp3" |xargs rm -rf   (.表示在当前目录下执行)

  3. CSS实现Footer固定底部,超过一屏自动撑开

    方法一:给html.body都设置100%的高度,确定body下内容设置min-height有效,然后设置主体部分min-height为100%,此时若没有header.footer则刚好完美占满全屏 ...

  4. LeetCode OJ-- Trapping Rain Water*

    https://oj.leetcode.com/problems/trapping-rain-water/ 模拟题,计算出在凹凸处存水量. 对于一个位置 i ,分别计算出它左边的最大值 left (从 ...

  5. python re的findall和finditer

    记录一个现象: 今天在写程序的时候,发现finditer和findall返回的结果不同.一个为list,一个为iterator. 红色箭头的地方,用finditer写的时候,print(item.gr ...

  6. http错误种类及原因

    http://blog.csdn.net/dxykevin/article/details/50950878 [摘要]HTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应 ...

  7. codeforces A. In Search of an Easy Problem

    A. In Search of an Easy Problem time limit per test 1 second memory limit per test 256 megabytes inp ...

  8. es6系列-变量声明

    es6系列所有文章都是阅读阮一峰老师的<ES6标准入门>(第2版)所做的读书笔记.方便日后查阅相关基础知识. git地址: https://github.com/rainnaZR/es6- ...

  9. TSimpleMsgPack的样例代码

    TSimpleMsgPack的样例代码 unit uMain; interface uses SimpleMsgPack, Windows, Messages, SysUtils, Variants, ...

  10. andriod打开摄像头和打开相册

    package com.example.yanlei.picture; import android.support.v7.app.AppCompatActivity; import android. ...