图像显著区域检测代码及其效果图 saliency region detection

from:http://blog.csdn.net/onezeros/article/details/6299745

先看几张效果图吧

 

效果图:

 

 

可以直接测试的代码:

头文件:

[cpp]  view plain  copy
  1. // Saliency.h: interface for the Saliency class.  
  2. //  
  3. //  
  4. //===========================================================================  
  5. //  Copyright (c) 2009 Radhakrishna Achanta [EPFL]   
  6. //===========================================================================  
  7.   
  8. #if !defined(_SALIENCY_H_INCLUDED_)  
  9. #define _SALIENCY_H_INCLUDED_  
  10.   
  11. #include <vector>  
  12. #include <cfloat>  
  13. using namespace std;  
  14.   
  15.   
  16. class Saliency    
  17. {  
  18. public:  
  19.     Saliency();  
  20.     virtual ~Saliency();  
  21.   
  22. public:  
  23.   
  24.     void GetSaliencyMap(  
  25.         const vector<unsigned int>&               inputimg,//INPUT: ARGB buffer in row-major order  
  26.         const int&                      width,  
  27.         const int&                      height,  
  28.         vector<double>&                   salmap,//OUTPUT: Floating point buffer in row-major order  
  29.         const bool&                     normalizeflag = true);//false if normalization is not needed  
  30.   
  31.   
  32. private:  
  33.   
  34.     void RGB2LAB(  
  35.         const vector<unsigned int>&               ubuff,  
  36.         vector<double>&                   lvec,  
  37.         vector<double>&                   avec,  
  38.         vector<double>&                   bvec);  
  39.   
  40.     void GaussianSmooth(  
  41.         const vector<double>&         inputImg,  
  42.         const int&                      width,  
  43.         const int&                      height,  
  44.         const vector<double>&         kernel,  
  45.         vector<double>&                   smoothImg);  
  46.   
  47.     //==============================================================================  
  48.     /// Normalize  
  49.     //==============================================================================  
  50.     void Normalize(  
  51.         const vector<double>&         input,  
  52.         const int&                      width,  
  53.         const int&                      height,  
  54.         vector<double>&                   output,  
  55.         const int&                      normrange = 255)  
  56.     {  
  57.         double maxval(0);  
  58.         double minval(DBL_MAX);  
  59.         {int i(0);  
  60.         forint y = 0; y < height; y++ )  
  61.         {  
  62.             forint x = 0; x < width; x++ )  
  63.             {  
  64.                 if( maxval < input[i] ) maxval = input[i];  
  65.                 if( minval > input[i] ) minval = input[i];  
  66.                 i++;  
  67.             }  
  68.         }}  
  69.         double range = maxval-minval;  
  70.         if( 0 == range ) range = 1;  
  71.         int i(0);  
  72.         output.clear();  
  73.         output.resize(width*height);  
  74.         forint y = 0; y < height; y++ )  
  75.         {  
  76.             forint x = 0; x < width; x++ )  
  77.             {  
  78.                 output[i] = ((normrange*(input[i]-minval))/range);  
  79.                 i++;  
  80.             }  
  81.         }  
  82.     }  
  83.   
  84. };  
  85.   
  86. #endif // !defined(_SALIENCY_H_INCLUDED_)  

cpp:

[cpp]  view plain  copy
  1. // Saliency.cpp: implementation of the Saliency class.  
  2. //  
  3. //  
  4. //===========================================================================  
  5. //  Copyright (c) 2009 Radhakrishna Achanta [EPFL]   
  6. //===========================================================================  
  7.   
  8. #include "Saliency.h"  
  9. #include <cmath>  
  10.   
  11.   
  12. //  
  13. // Construction/Destruction  
  14. //  
  15.   
  16. Saliency::Saliency()  
  17. {  
  18.   
  19. }  
  20.   
  21. Saliency::~Saliency()  
  22. {  
  23.   
  24. }  
  25.   
  26. //===========================================================================  
  27. /// RGB2LAB  
  28. //===========================================================================  
  29. void Saliency::RGB2LAB(  
  30.     const vector<unsigned int>&               ubuff,  
  31.     vector<double>&                   lvec,  
  32.     vector<double>&                   avec,  
  33.     vector<double>&                   bvec)  
  34. {  
  35.     int sz = int(ubuff.size());  
  36.     lvec.resize(sz);  
  37.     avec.resize(sz);  
  38.     bvec.resize(sz);  
  39.   
  40.     forint j = 0; j < sz; j++ )  
  41.     {  
  42.         int r = (ubuff[j] >> 16) & 0xFF;  
  43.         int g = (ubuff[j] >>  8) & 0xFF;  
  44.         int b = (ubuff[j]      ) & 0xFF;  
  45.   
  46.         double xval = 0.412453 * r + 0.357580 * g + 0.180423 * b;  
  47.         double yval = 0.212671 * r + 0.715160 * g + 0.072169 * b;  
  48.         double zVal = 0.019334 * r + 0.119193 * g + 0.950227 * b;  
  49.   
  50.         xval /= (255.0 * 0.950456);  
  51.         yval /=  255.0;  
  52.         zVal /= (255.0 * 1.088754);  
  53.   
  54.         double fX, fY, fZ;  
  55.         double lval, aval, bval;  
  56.   
  57.         if (yval > 0.008856)  
  58.         {  
  59.             fY = pow(yval, 1.0 / 3.0);  
  60.             lval = 116.0 * fY - 16.0;  
  61.         }  
  62.         else  
  63.         {  
  64.             fY = 7.787 * yval + 16.0 / 116.0;  
  65.             lval = 903.3 * yval;  
  66.         }  
  67.   
  68.         if (xval > 0.008856)  
  69.             fX = pow(xval, 1.0 / 3.0);  
  70.         else  
  71.             fX = 7.787 * xval + 16.0 / 116.0;  
  72.   
  73.         if (zVal > 0.008856)  
  74.             fZ = pow(zVal, 1.0 / 3.0);  
  75.         else  
  76.             fZ = 7.787 * zVal + 16.0 / 116.0;  
  77.   
  78.         aval = 500.0 * (fX - fY)+128.0;  
  79.         bval = 200.0 * (fY - fZ)+128.0;  
  80.   
  81.         lvec[j] = lval;  
  82.         avec[j] = aval;  
  83.         bvec[j] = bval;  
  84.     }  
  85. }  
  86.   
  87. //==============================================================================  
  88. /// GaussianSmooth  
  89. ///  
  90. /// Blur an image with a separable binomial kernel passed in.  
  91. //==============================================================================  
  92. void Saliency::GaussianSmooth(  
  93.     const vector<double>&         inputImg,  
  94.     const int&                      width,  
  95.     const int&                      height,  
  96.     const vector<double>&         kernel,  
  97.     vector<double>&                   smoothImg)  
  98. {  
  99.     int center = int(kernel.size())/2;  
  100.   
  101.     int sz = width*height;  
  102.     smoothImg.clear();  
  103.     smoothImg.resize(sz);  
  104.     vector<double> tempim(sz);  
  105.     int rows = height;  
  106.     int cols = width;  
  107.    //--------------------------------------------------------------------------  
  108.    // Blur in the x direction.  
  109.    //---------------------------------------------------------------------------  
  110.     {int index(0);  
  111.     forint r = 0; r < rows; r++ )  
  112.     {  
  113.         forint c = 0; c < cols; c++ )  
  114.         {  
  115.             double kernelsum(0);  
  116.             double sum(0);  
  117.             forint cc = (-center); cc <= center; cc++ )  
  118.             {  
  119.                 if(((c+cc) >= 0) && ((c+cc) < cols))  
  120.                 {  
  121.                     sum += inputImg[r*cols+(c+cc)] * kernel[center+cc];  
  122.                     kernelsum += kernel[center+cc];  
  123.                 }  
  124.             }  
  125.             tempim[index] = sum/kernelsum;  
  126.             index++;  
  127.         }  
  128.     }}  
  129.   
  130.     //--------------------------------------------------------------------------  
  131.     // Blur in the y direction.  
  132.     //---------------------------------------------------------------------------  
  133.     {int index = 0;  
  134.     forint r = 0; r < rows; r++ )  
  135.     {  
  136.         forint c = 0; c < cols; c++ )  
  137.         {  
  138.             double kernelsum(0);  
  139.             double sum(0);  
  140.             forint rr = (-center); rr <= center; rr++ )  
  141.             {  
  142.                 if(((r+rr) >= 0) && ((r+rr) < rows))  
  143.                 {  
  144.                    sum += tempim[(r+rr)*cols+c] * kernel[center+rr];  
  145.                    kernelsum += kernel[center+rr];  
  146.                 }  
  147.             }  
  148.             smoothImg[index] = sum/kernelsum;  
  149.             index++;  
  150.         }  
  151.     }}  
  152. }  
  153.   
  154. //===========================================================================  
  155. /// GetSaliencyMap  
  156. ///  
  157. /// Outputs a saliency map with a value assigned per pixel. The values are  
  158. /// normalized in the interval [0,255] if normflag is set true (default value).  
  159. //===========================================================================  
  160. void Saliency::GetSaliencyMap(  
  161.     const vector<unsigned int>&       inputimg,  
  162.     const int&                      width,  
  163.     const int&                      height,  
  164.     vector<double>&                   salmap,  
  165.     const bool&                     normflag)   
  166. {  
  167.     int sz = width*height;  
  168.     salmap.clear();  
  169.     salmap.resize(sz);  
  170.   
  171.     vector<double> lvec(0), avec(0), bvec(0);  
  172.     RGB2LAB(inputimg, lvec, avec, bvec);  
  173.     //--------------------------  
  174.     // Obtain Lab average values  
  175.     //--------------------------  
  176.     double avgl(0), avga(0), avgb(0);  
  177.     {forint i = 0; i < sz; i++ )  
  178.     {  
  179.         avgl += lvec[i];  
  180.         avga += avec[i];  
  181.         avgb += bvec[i];  
  182.     }}  
  183.     avgl /= sz;  
  184.     avga /= sz;  
  185.     avgb /= sz;  
  186.   
  187.     vector<double> slvec(0), savec(0), sbvec(0);  
  188.   
  189.     //----------------------------------------------------  
  190.     // The kernel can be [1 2 1] or [1 4 6 4 1] as needed.  
  191.     // The code below show usage of [1 2 1] kernel.  
  192.     //----------------------------------------------------  
  193.     vector<double> kernel(0);  
  194.     kernel.push_back(1.0);  
  195.     kernel.push_back(2.0);  
  196.     kernel.push_back(1.0);  
  197.   
  198.     GaussianSmooth(lvec, width, height, kernel, slvec);  
  199.     GaussianSmooth(avec, width, height, kernel, savec);  
  200.     GaussianSmooth(bvec, width, height, kernel, sbvec);  
  201.   
  202.     {forint i = 0; i < sz; i++ )  
  203.     {  
  204.         salmap[i] = (slvec[i]-avgl)*(slvec[i]-avgl) +  
  205.                     (savec[i]-avga)*(savec[i]-avga) +  
  206.                     (sbvec[i]-avgb)*(sbvec[i]-avgb);  
  207.     }}  
  208.   
  209.     iftrue == normflag )  
  210.     {  
  211.         vector<double> normalized(0);  
  212.         Normalize(salmap, width, height, normalized);  
  213.         swap(salmap, normalized);  
  214.     }  
  215. }  

关于代码的使用说明:

[cpp]  view plain  copy
  1. 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.  
  2.   
  3. Sample usage:  
  4.   
  5. #include "Saliency.h"  
  6.   
  7. void main()  
  8. {  
  9.     // Assume we already have an unsigned integer buffer inputImg of  
  10.     // inputWidth and inputHeight (in row-major order).  
  11.     // Each unsigned integer has 32 bits and contains pixel data in ARGB  
  12.     // format. I.e. From left to right, the first 8 bits contain alpha  
  13.     // channel value and are not used in our case. The next 8 bits  
  14.     // contain R channel value; the next 8 bits contain G channel value;  
  15.     // the last 8 bits contain the B channel value.  
  16.     //  
  17.     // Now create a Saliency object and call the GetSaliencyMap function on it.  
  18.   
  19.     Saliency sal;  
  20.     vector<double> salmap(0);  
  21.     sal.GetSaliencyMap(inputImg, inputWidth, inputHeight, salmap);  
  22.   
  23.     // salmap is a floating point output (in row major order)  
  24. }  

 

我自己写的测试主程序:

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

[cpp]  view plain  copy
  1. #include "Saliency.h"  
  2.   
  3. #include <cv.h>  
  4. #include <cxcore.h>  
  5. #include <highgui.h>  
  6.   
  7. #include "windows.h"  
  8.   
  9. #include <iostream>  
  10. #include <cassert>  
  11. using namespace std;  
  12.   
  13. int main(int argc,char** argv)  
  14. {  
  15.     WIN32_FIND_DATAA FileData;  
  16.     HANDLE hFind;  
  17.       
  18.     hFind = FindFirstFileA((LPCSTR)"Imgs/*.jpg",&FileData);  
  19.     if (hFind == INVALID_HANDLE_VALUE) {  
  20.         printf ("Invalid File Handle. GetLastError reports %d/n",   
  21.             GetLastError ());  
  22.         return (0);  
  23.     }   
  24.   
  25.     Saliency sal;  
  26.     vector<double> salmap(0);  
  27.     while (FindNextFileA(hFind, &FileData)) {  
  28.         cout<<FileData.cFileName<<endl;  
  29.         string name("Imgs/");  
  30.         name.append(FileData.cFileName);  
  31.         IplImage* img=cvLoadImage(name.c_str());  
  32.         if (!img) {  
  33.             cout<<"failed to load image"<<endl;  
  34.             break;  
  35.         }  
  36.         assert(img->nChannels==3);  
  37.           
  38.         vector<unsigned int >imgInput;  
  39.         vector<double> imgSal;  
  40.         //IplImage to vector  
  41.         for (int h=0;h<img->height;h++) {  
  42.             unsigned char*p=(unsigned char*)img->imageData+h*img->widthStep;  
  43.             for (int w=0;w<img->width;w++) {  
  44.                 unsigned int t=0;  
  45.                 t+=*p++;  
  46.                 t<<=8;  
  47.                 t+=*p++;  
  48.                 t<<=8;  
  49.                 t+=*p++;  
  50.                 imgInput.push_back(t);  
  51.             }  
  52.         }  
  53.         sal.GetSaliencyMap(imgInput, img->width, img->height, imgSal);  
  54.         //vector to IplImage  
  55.         int index=0;  
  56.         IplImage* imgout=cvCreateImage(cvGetSize(img),IPL_DEPTH_64F ,1);  
  57.         for (int h=0;h<imgout->height;h++) {  
  58.             double*p=(double*)(imgout->imageData+h*imgout->widthStep);  
  59.             for (int w=0;w<imgout->width;w++) {  
  60.                 *p++=imgSal[index++];  
  61.             }  
  62.         }  
  63.           
  64.         name.append(".saliency.jpg");  
  65.           
  66.   
  67.         cvSaveImage(name.c_str(),imgout);  
  68.         cvReleaseImage(&img);  
  69.         cvReleaseImage(&imgout);  
  70.     }  
  71.   
  72.     FindClose(&hFind);  
  73.     return 0;  
  74. }  

 

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

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

1. 显著点的检测 Itti的A Model of Saliency-Based Visual Attention for Rapid Scene Analysis (TPAMI 1999)论文是显著检测的鼻祖论文,检测出来的是用户关注的点。 2. 显著区域检测 侯晓迪同学在2007年发表的一篇CVPR的论文,用很简单的方法检测显著区域,那之后显著检测主要以区域检测为主:Saliency detection: A spectral residual approach (CVPR 2007),虽然之后有人诟病这篇论文有不足之处,但该想法简单,推动了显著性研究的普及。侯同学靠这一篇文章再加上投稿期间的趣事,就封神了。 3. 其他经典的显著检测方法 在那之后陆续又有一些经典的显著检测算法被提出:https://blog.csdn.net/touch_dream/article/details/78716507 可以看这个博文。 4. 基于深度学习的显著检测 再之后,显著检测领域就进入了Deep Learning时代, Deep Visual Attention Prediction TIP2018 (CODE)     https://github.com/wenguanwang/deepattention Predicting Human Eye Fixations via an LSTM-based Saliency Attentive Model (CODE)     https://github.com/marcellacornia/sam CVPR2016 Shallow and Deep Convolutional Networks for Saliency Prediction (CODE)     https://github.com/imatge-upc/saliency-2016-cvpr Saliency Detection with GAN (2017)     https://github.com/imatge-upc/saliency-salgan-2017  (CODE)     https://github.com/batsa003/salgan/ (PyTorch的版本) 5. 非自然图象的显著检测 例如,海报的显著检测,图表的显著检测,地理数据的显著检测等等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值