当前位置: 代码迷 >> 综合 >> 图像显著区域检测代码及其效果图 saliency region detection
  详细解决方案

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

热度:69   发布时间:2023-12-12 09:45:14.0

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/

  相关解决方案