from:http://blog.csdn.net/onezeros/article/details/6299745
先看幾張效果圖吧
?
效果圖:
?
?
可以直接測試的代碼:
頭文件:
[cpp]?view plain
?copy ?? ?? ?? ?? ?? ?? ?? #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,?? ????????const?int&??????????????????????width,?? ????????const?int&??????????????????????height,?? ????????vector<double>&???????????????????salmap,?? ????????const?bool&?????????????????????normalizeflag?=?true);?? ?? ?? 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);?? ?? ?????? ?????? ?????? ????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:
[cpp]?view plain
?copy ?? ?? ?? ?? ?? ?? ?? #include?"Saliency.h"?? #include?<cmath>?? ?? ?? ?? ?? ?? ?? Saliency::Saliency()?? {?? ?? }?? ?? Saliency::~Saliency()?? {?? ?? }?? ?? ?? ?? ?? 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;?? ????}?? }?? ?? ?? ?? ?? ?? ?? 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;?? ????? ????? ????? ????{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++;?? ????????}?? ????}}?? ?? ?????? ?????? ?????? ????{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++;?? ????????}?? ????}}?? }?? ?? ?? ?? ?? ?? ?? ?? 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);?? ?????? ?????? ?????? ????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);?? ?? ?????? ?????? ?????? ?????? ????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);?? ????}?? }??
關于代碼的使用說明:
[cpp]?view plain
?copy 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()?? {?? ?????? ?????? ?????? ?????? ?????? ?????? ?????? ?????? ?????? ?? ????Saliency?sal;?? ????vector<double>?salmap(0);?? ????sal.GetSaliencyMap(inputImg,?inputWidth,?inputHeight,?salmap);?? ?? ?????? }??
?
我自己寫的測試主程序:
可以指定一個文件夾,程序保存該文件夾下所有jpg文件的處理結果
[cpp]?view plain
?copy #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;?? ?????????? ????????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);?? ?????????? ????????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/
總結
以上是生活随笔為你收集整理的图像显著区域检测代码及其效果图 saliency region detection的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。