国外的一个图像显著区域检测代码及其效果图saliency region detection

来源:互联网 发布:淘宝评价记录能删除吗 编辑:程序博客网 时间:2024/05/19 20:47
国外的一个图像显著区域检测代码及其效果图saliency region detection
原文地址:http://blog.csdn.net/onezeros/article/details/6299745
 

先看几张效果图吧

 

效果图:

 

 

可以直接测试的代码:

头文件:

 // 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:

 voidGetSaliencyMap(
  constvector<unsignedint>&    inputimg,//INPUT:ARGB buffer in row-major order
  constint&      width,
  constint&      height,
  vector<double>&     salmap,//OUTPUT:Floating point buffer in row-major order
  constbool&      normalizeflag= true);//false if normalization is not needed


private:

 void RGB2LAB(
  constvector<unsignedint>&    ubuff,
  vector<double>&     lvec,
  vector<double>&     avec,
  vector<double>&     bvec);

 voidGaussianSmooth(
  constvector<double>&   inputImg,
  constint&      width,
  constint&      height,
  constvector<double>&   kernel,
  vector<double>&     smoothImg);

 //==============================================================================
 /// Normalize
 //==============================================================================
 void Normalize(
  constvector<double>&   input,
  constint&      width,
  constint&      height,
  vector<double>&     output,
  constint&      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 theSaliency class.
//
//////////////////////////////////////////////////////////////////////
//===========================================================================
// Copyright (c) 2009 Radhakrishna Achanta[EPFL]
//===========================================================================

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


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

Saliency::Saliency()
{

}

Saliency::~Saliency()
{

}

//===========================================================================
/// RGB2LAB
//===========================================================================
void Saliency::RGB2LAB(
 const vector<unsignedint>&    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 kernelpassed in.
//==============================================================================
void Saliency::GaussianSmooth(
 constvector<double>&   inputImg,
 constint&      width,
 constint&      height,
 constvector<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 xdirection.
  //---------------------------------------------------------------------------
 {int index(0);
 for( int r = 0; r < rows; r++)
 {
  for( int c = 0; c< cols; c++ )
  {
   doublekernelsum(0);
   doublesum(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++ )
  {
   doublekernelsum(0);
   doublesum(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. Thevalues are
/// normalized in the interval [0,255] if normflag is set true(default value).
//===========================================================================
void Saliency::GetSaliencyMap(
 const vector<unsignedint>&  inputimg,
 constint&      width,
 constint&      height,
 vector<double>&     salmap,
 constbool&      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] asneeded.
 // 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 ofSaliency.h and Saliency.cpp files. The former contains thedeclaration of the Saliency class and its member functions and thelater contains the respective definitions.

Sample usage:

#include "Saliency.h"

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

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

 // salmap is afloating 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<<"failedto load image"<<endl;
   break;
  }
  assert(img->nChannels==3);
  
  vector<unsignedint >imgInput;
  vector<double>imgSal;
  //IplImage to vector
  for (inth=0;h<img->height;h++) {
   unsignedchar*p=(unsignedchar*)img->imageData+h*img->widthStep;
   for (intw=0;w<img->width;w++) {
    unsignedint 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 (inth=0;h<imgout->height;h++) {
   double*p=(double*)(imgout->imageData+h*imgout->widthStep);
   for (intw=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/

原创粉丝点击