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

先看几张效果图吧

效果图:

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

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

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

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

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

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

可以直接测试的代码:

添加头文件:

// 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_)

函数文件:

// 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)
}

测试程序:需在程序目录下新建一个名为Imgs的文件夹,放入测试图片即可,运行结果会存入该文件夹。

#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://cg.cs.tsinghua.edu.cn/people/~cmm/saliency/

转自http://blog.csdn.net/onezeros/article/details/6299745

原文链接: https://www.cnblogs.com/yingying0907/archive/2012/07/24/2607040.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/56579

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 上午7:26
下一篇 2023年2月9日 上午7:27

相关推荐