diff options
author | Maxime Curioni <maxime.curioni@gmail.com> | 2008-05-08 23:16:40 +0400 |
---|---|---|
committer | Maxime Curioni <maxime.curioni@gmail.com> | 2008-05-08 23:16:40 +0400 |
commit | 64e4a3ec9aed6c8abe095e2cd1fe1552f7cde51c (patch) | |
tree | 6c77358bd447b6c2d215324ef48fc12d1f5ae5ca /source/blender/freestyle/intern/view_map/SteerableViewMap.cpp | |
parent | cf2e1e2857cfc5b3c2848c7fc6c9d919ac72fabb (diff) | |
parent | 106974a9d2d5caa5188322507980e3d57d2e3517 (diff) |
soc-2008-mxcurioni: merged changes to revision 14747, cosmetic changes for source/blender/freestyle
Diffstat (limited to 'source/blender/freestyle/intern/view_map/SteerableViewMap.cpp')
-rwxr-xr-x | source/blender/freestyle/intern/view_map/SteerableViewMap.cpp | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp new file mode 100755 index 00000000000..b2604606aa7 --- /dev/null +++ b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp @@ -0,0 +1,243 @@ +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "SteerableViewMap.h" +#include "../image/ImagePyramid.h" +#include "../image/Image.h" +#include "Silhouette.h" +#include <math.h> +#include "../geometry/Geom.h" +using namespace Geometry; + +#include <qstring.h> +#include <qimage.h> + +SteerableViewMap::SteerableViewMap(unsigned int nbOrientations){ + _nbOrientations = nbOrientations; + _bound = cos(M_PI/(float)_nbOrientations); + for(unsigned i=0; i<_nbOrientations; ++i){ + _directions.push_back(Vec2d(cos((float)i*M_PI/(float)_nbOrientations), sin((float)i*M_PI/(float)_nbOrientations))); + } + Build(); +} + +void SteerableViewMap::Build(){ + _imagesPyramids = new ImagePyramid*[_nbOrientations+1]; // one more map to store the complete visible VM + memset((_imagesPyramids),0,(_nbOrientations+1)*sizeof(ImagePyramid*)); +} + +SteerableViewMap::SteerableViewMap(const SteerableViewMap& iBrother){ + _nbOrientations = iBrother._nbOrientations; + unsigned i; + _bound = iBrother._bound; + _directions = iBrother._directions; + _mapping = iBrother._mapping; + _imagesPyramids = new ImagePyramid*[_nbOrientations+1]; // one more map to store the complete visible VM + for(i=0;i<_nbOrientations+1;++i) + _imagesPyramids[i] = new GaussianPyramid(*(dynamic_cast<GaussianPyramid*>(iBrother._imagesPyramids[i]))); +} + +SteerableViewMap::~SteerableViewMap(){ + Clear(); +} + +void SteerableViewMap::Clear(){ + unsigned i; + if(_imagesPyramids){ + for(i=0; i<=_nbOrientations; ++i){ + if(_imagesPyramids[i]) + delete (_imagesPyramids)[i]; + } + delete [] _imagesPyramids; + _imagesPyramids = 0; + } + if(!_mapping.empty()){ + for(map<unsigned int, double*>::iterator m=_mapping.begin(), mend=_mapping.end(); + m!=mend; + ++m){ + delete [] (*m).second; + } + _mapping.clear(); + } +} + +void SteerableViewMap::Reset(){ + Clear(); + Build(); +} + +double SteerableViewMap::ComputeWeight(const Vec2d& dir, unsigned i){ + double dotp = fabs(dir*_directions[i]); + if(dotp < _bound) + return 0; + if(dotp>1) + dotp = 1; + + return cos((float)_nbOrientations/2.0*acos(dotp)); +} + +double * SteerableViewMap::AddFEdge(FEdge *iFEdge){ + unsigned i; + unsigned id = iFEdge->getId().getFirst(); + map<unsigned int, double* >::iterator o = _mapping.find(id); + if(o!=_mapping.end()){ + return (*o).second; + } + double * res = new double[_nbOrientations]; + for(i=0; i<_nbOrientations; ++i){ + res[i] = 0; + } + Vec3r o2d3 = iFEdge->orientation2d(); + Vec2r o2d2(o2d3.x(), o2d3.y()); + real norm = o2d2.norm(); + if(norm < 1e-6){ + return res; + } + o2d2/=norm; + + for(i=0; i<_nbOrientations; ++i){ + res[i] = ComputeWeight(o2d2, i); + } + _mapping[id] = res; + return res; +} + +unsigned SteerableViewMap::getSVMNumber(const Vec2f& orient){ + Vec2f dir(orient); + unsigned res = 0; + real norm = dir.norm(); + if(norm < 1e-6){ + return _nbOrientations+1; + } + dir/=norm; + double maxw = 0.f; + unsigned winner = _nbOrientations+1; + for(unsigned i=0; i<_nbOrientations; ++i){ + double w = ComputeWeight(dir, i); + if(w>maxw){ + maxw = w; + winner = i; + } + } + return winner; +} + + +unsigned SteerableViewMap::getSVMNumber(unsigned id){ + map<unsigned int, double* >::iterator o = _mapping.find(id); + if(o!=_mapping.end()){ + double* wvalues= (*o).second; + double maxw = 0.f; + unsigned winner = _nbOrientations+1; + for(unsigned i=0; i<_nbOrientations; ++i){ + double w = wvalues[i]; + if(w>maxw){ + maxw = w; + winner = i; + } + } + return winner; + } + return _nbOrientations+1; +} + +void SteerableViewMap::buildImagesPyramids(GrayImage **steerableBases, bool copy, unsigned iNbLevels, float iSigma){ + for(unsigned i=0; i<=_nbOrientations; ++i){ + ImagePyramid * svm = (_imagesPyramids)[i]; + if(svm) + delete svm; + if(copy) + svm = new GaussianPyramid(*(steerableBases[i]), iNbLevels, iSigma); + else + svm = new GaussianPyramid(steerableBases[i], iNbLevels, iSigma); + _imagesPyramids[i] = svm; + } +} + +float SteerableViewMap::readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y){ + ImagePyramid *pyramid = _imagesPyramids[iOrientation]; + if(pyramid==0){ + cout << "Warning: this steerable ViewMap level doesn't exist" << endl; + return 0; + } + if((x<0) || (x>=pyramid->width()) || (y<0) || (y>=pyramid->height())) + return 0; + //float v = pyramid->pixel(x,pyramid->height()-1-y,iLevel)*255.f; + float v = pyramid->pixel(x,pyramid->height()-1-y,iLevel)/32.f; // we encode both the directionality and the lines counting on 8 bits + // (because of frame buffer). Thus, we allow until 8 lines to pass through + // the same pixel, so that we can discretize the Pi/_nbOrientations angle into + // 32 slices. Therefore, for example, in the vertical direction, a vertical line + // will have the value 32 on each pixel it passes through. + return v; +} + +float SteerableViewMap::readCompleteViewMapPixel(int iLevel, int x, int y){ + return readSteerableViewMapPixel(_nbOrientations,iLevel,x,y); +} + +unsigned int SteerableViewMap::getNumberOfPyramidLevels() const{ + if(_imagesPyramids[0]) + return _imagesPyramids[0]->getNumberOfLevels(); + return 0; +} +void SteerableViewMap::saveSteerableViewMap() const { + for(unsigned i=0; i<=_nbOrientations; ++i){ + if(_imagesPyramids[i] == 0){ + cerr << "SteerableViewMap warning: orientation " << i <<" of steerable View Map whas not been computed yet" << endl; + continue; + } + int ow = _imagesPyramids[i]->width(0); + int oh = _imagesPyramids[i]->height(0); + QString base("SteerableViewMap"); + for(unsigned j=0; j<_imagesPyramids[i]->getNumberOfLevels(); ++j){ + float coeff = 1;//1/255.f; //100*255;//*pow(2,j); + QImage qtmp(ow, oh, QImage::Format_RGB32); + for(unsigned y=0;y<oh;++y){ + for(unsigned x=0;x<ow;++x){ + int c = (int)(coeff*_imagesPyramids[i]->pixel(x,y,j)); + if(c>255) + c=255; + //int c = (int)(_imagesPyramids[i]->pixel(x,y,j)); + qtmp.setPixel(x,y,qRgb(c,c,c)); + } + } + qtmp.save(base+QString::number(i)+"-"+QString::number(j)+".png", "PNG"); + } + // QString base("SteerableViewMap"); + // for(unsigned j=0; j<_imagesPyramids[i]->getNumberOfLevels(); ++j){ + // GrayImage * img = _imagesPyramids[i]->getLevel(j); + // int ow = img->width(); + // int oh = img->height(); + // float coeff = 1; //100*255;//*pow(2,j); + // QImage qtmp(ow, oh, 32); + // for(unsigned y=0;y<oh;++y){ + // for(unsigned x=0;x<ow;++x){ + // int c = (int)(coeff*img->pixel(x,y)); + // if(c>255) + // c=255; + // //int c = (int)(_imagesPyramids[i]->pixel(x,y,j)); + // qtmp.setPixel(x,y,qRgb(c,c,c)); + // } + // } + // qtmp.save(base+QString::number(i)+"-"+QString::number(j)+".png", "PNG"); + // } + // + } +} |