Let's see some.
:
Code that can be directly tested:
Header file:
Saliency.h:interface for the Saliency class.
//
//////////////////////////////////////////////////////////////////////
//===========================================================================
Copyright (c) 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; × < 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; × < 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) 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] >>) & 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)
{
Su M + = 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)
{
S Um + = 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);
}
}
Instructions on how to use the code:
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 D Efinitions.
Sample usage:
#include "Saliency.h"
void Main ()
{
Assume we already has an unsigned integer buffer inputimg of
Inputwidth and Inputheight (in Row-major order).
Each unsigned integer has a. Bits and contains pixel data in ARGB
Format. i.e. from left to right, the first 8 bits contain alpha
Channel value and is not used. 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)
}
I wrote the test main program myself:
You can specify a folder in which the program saves the processing results of all JPG files under that folder
#include "Saliency.h"
#include <cv.h>
#include <cxcore.h>
#include
#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;hheight;h++) {
unsigned char*p= (unsigned char*) img->imagedata+h*img->widthstep;
for (int w=0;wwidth;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;hheight;h++) {
Double*p= (double*) (imgout->imagedata+h*imgout->widthstep);
for (int w=0;wwidth;w++) {
*p++=imgsal[index++];
}
}
Name.append (". saliency.jpg");
Cvsaveimage (Name.c_str (), imgout);
Cvreleaseimage (&IMG);
Cvreleaseimage (&imgout);
}
FindClose (&hfind);
return 0;
}
Home page of the code: http://ivrg.epfl.ch/supplementary_material/RK_ICIP2010/index.html
Tsinghua's latest research: http://cg.cs.tsinghua.edu.cn/people/~cmm/saliency/
Http://blog.csdn.net/onezeros/article/details/6299745#comments
Significant regional detection of target detection---a significant regional detection code for an image and its saliency region detection