目标检测之显著区域检测---国外的一个图像显著区域检测代码及其效果图 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_)
cpp:
// 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)
}
我自己写的测试主程序:
可以指定一个文件夹,程序保存该文件夹下所有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<<"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://ivrg.epfl.ch/supplementary_material/RK_ICIP2010/index.html
清华的最新研究:http://cg.cs.tsinghua.edu.cn/people/~cmm/saliency/
http://blog.csdn.net/onezeros/article/details/6299745#comments
目标检测之显著区域检测---国外的一个图像显著区域检测代码及其效果图 saliency region detection的更多相关文章
- Halcon从某一个图片以指定区域绘制到另一个图像
************************************************************* * Halcon从某一个图片以指定区域绘制到另一个图像 * Author: ...
- OPENCV图像特征点检测与FAST检测算法
前面描述角点检测的时候说到,角点其实也是一种图像特征点,对于一张图像来说,特征点分为三种形式包括边缘,焦点和斑点,在OPENCV中,加上角点检测,总共提供了以下的图像特征点检测方法 FAST SURF ...
- OpenCV计算机视觉学习(13)——图像特征点检测(Harris角点检测,sift算法)
如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 前言 ...
- Atitit 图像清晰度 模糊度 检测 识别 评价算法 源码实现attilax总结
Atitit 图像清晰度 模糊度 检测 识别 评价算法 源码实现attilax总结 1.1. 原理,主要使用像素模糊后的差别会变小1 1.2. 具体流程1 1.3. 提升性能 可以使用采样法即可..1 ...
- Atitit 图像清晰度 模糊度 检测 识别 评价算法 原理
Atitit 图像清晰度 模糊度 检测 识别 评价算法 原理 1.1. 图像边缘一般都是通过对图像进行梯度运算来实现的1 1.2. Remark: 1 1.3. 1.失焦检测. 衡量画面模糊的主要方 ...
- paper 27 :图像/视觉显著性检测技术发展情况梳理(Saliency Detection、Visual Attention)
1. 早期C. Koch与S. Ullman的研究工作. 他们提出了非常有影响力的生物启发模型. C. Koch and S. Ullman . Shifts in selective visual ...
- [开发技巧]·HTML检测输入已完成自动填写下一个内容
[开发技巧]·HTML检测输入已完成自动填写下一个内容 个人网站 --> http://www.yansongsong.cn 在上一个博客中简易实现检测输入已完成,我们实现了检测输入已完成,现在 ...
- 根据序列图像聚焦区域获取深度 Shape From Focus
最为超新新新新鸟...我也不知道第一篇文章应该写什么..所以,把自己最近正在研究的东西报一下吧, 研究的东西其实也不算深奥,就是对一个图像序列中的每张图像进行检测,发现每张图片的聚焦清晰区域,找到这个 ...
- 四种简单的图像显著性区域特征提取方法-----AC/HC/LC/FT。
四种简单的图像显著性区域特征提取方法-----> AC/HC/LC/FT. 分类: 图像处理 2014-08-03 12:40 4088人阅读 评论(4) 收藏 举报 salient regio ...
随机推荐
- bzoj1306: [CQOI2009]match循环赛(模拟爆搜)
Input第一行包含一个正整数n,队伍的个数.第二行包含n个非负整数,即每支队伍的得分.Output输出仅一行,即可能的分数表数目.保证至少存在一个可能的分数表.Sample Input 6 5 6 ...
- hdu 1754 线段树(点修改)
I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- C#精髓第四讲 GridView 72般绝技
原文发布时间为:2008-08-03 -- 来源于本人的百度文章 [由搬家工具导入] 原文地址:http://blog.csdn.net/21aspnet/archive/2007/03/25/154 ...
- J2ME开发基本语法及小实例专题
原文发布时间为:2008-07-31 -- 来源于本人的百度文章 [由搬家工具导入] http://www.wcplym.com/sbjtClassArtl.asp?id=4 ·Canva专题:漂亮的 ...
- 【MFC】 点击不同的按钮后在界面同一位置显示不同的对话框内容(转)
原文转自 http://bbs.csdn.net/topics/391039432 如图类似Tab控件的功能 但Tab控件按钮是固定的上下左右 不方便 所以想自己重新做个这种 我M ...
- 42深入理解C指针之---指针与队列
一.借助第40指针与链表的相关内容,稍微修改即可: 1.定义头文件queue.h代码如下: #include <stdlib.h> #include <stdio.h> #if ...
- 递归,回溯,DFS,BFS的理解和模板
LeetCode 里面很大一部分题目都是属于这个范围,例如Path Sum用的就是递归+DFS,Path Sum2用的是递归+DFS+回溯 这里参考了一些网上写得很不错的文章,总结一下理解与模板 递归 ...
- delphiIDE 把 window 桌面改慢后的 还原方法
在开始搜索框中键入services.msc,然后按回车键,打开服务列表. 重启这个服务就可以了.
- hdu 1565&hdu 1569(网络流--最小点权值覆盖)
方格取数(1) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- LeetCode OJ——Two Sum
http://oj.leetcode.com/problems/two-sum/ 求是否存在两个数的和为target,暴力法,两层循环 #include <iostream> #inclu ...