diff options
Diffstat (limited to 'source/blender/freestyle/intern/view_map/SteerableViewMap.cpp')
-rw-r--r-- | source/blender/freestyle/intern/view_map/SteerableViewMap.cpp | 477 |
1 files changed, 254 insertions, 223 deletions
diff --git a/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp index 6b76c2512f0..e39181e335d 100644 --- a/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp +++ b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp @@ -1,267 +1,298 @@ -// -// 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. -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/freestyle/intern/view_map/SteerbaleViewMap.cpp + * \ingroup freestyle + * \brief Convenient access to the steerable ViewMap to which any element of the ViewMap belongs to. + * \author Stephane Grabli + * \date 01/07/2003 + */ + +#include <math.h> +//soc #include <qimage.h> +//soc #include <qstring.h> +#include <sstream> #include "Silhouette.h" #include "SteerableViewMap.h" -#include "../image/ImagePyramid.h" -#include "../image/Image.h" -#include <math.h> + #include "../geometry/Geom.h" -using namespace Geometry; -//soc #include <qstring.h> -//soc #include <qimage.h> -#include <sstream> +#include "../image/ImagePyramid.h" +#include "../image/Image.h" extern "C" { #include "IMB_imbuf.h" #include "IMB_imbuf_types.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(); +using namespace Geometry; + +SteerableViewMap::SteerableViewMap(unsigned int nbOrientations) +{ + _nbOrientations = nbOrientations; + _bound = cos(M_PI/(float)_nbOrientations); + for (unsigned int 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*)); +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(const SteerableViewMap& iBrother) +{ + _nbOrientations = iBrother._nbOrientations; + unsigned int 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(); +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::Clear() +{ + unsigned int 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(); +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; +double SteerableViewMap::ComputeWeight(const Vec2d& dir, unsigned i) +{ + double dotp = fabs(dir * _directions[i]); + if (dotp < _bound) + return 0.0; + if (dotp > 1.0) + dotp = 1.0; - return cos((float)_nbOrientations/2.0*acos(dotp)); + 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; +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.0; + } + Vec3r o2d3 = iFEdge->orientation2d(); + Vec2r o2d2(o2d3.x(), o2d3.y()); + real norm = o2d2.norm(); + if (norm < 1.0e-6) { + return res; + } + o2d2 /= norm; - for(i=0; i<_nbOrientations; ++i){ - res[i] = ComputeWeight(o2d2, i); - } - _mapping[id] = res; - return res; + 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); - //soc 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(const Vec2f& orient) +{ + Vec2f dir(orient); + //soc unsigned res = 0; + real norm = dir.norm(); + if (norm < 1.0e-6) { + return _nbOrientations + 1; + } + dir /= norm; + double maxw = 0.0f; + unsigned winner = _nbOrientations + 1; + for (unsigned int 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; +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.0; + 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; - } +void SteerableViewMap::buildImagesPyramids(GrayImage **steerableBases, bool copy, unsigned iNbLevels, float iSigma) +{ + for (unsigned int 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::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.0f; + // 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. + float v = pyramid->pixel(x, pyramid->height() - 1 - y, iLevel) / 32.0f; + return v; } -float SteerableViewMap::readCompleteViewMapPixel(int iLevel, int x, int y){ - return readSteerableViewMapPixel(_nbOrientations,iLevel,x,y); +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; +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); +void SteerableViewMap::saveSteerableViewMap() const +{ + for (unsigned int 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); + + //soc QString base("SteerableViewMap"); + string base("SteerableViewMap"); + stringstream filename; + + for (int j = 0; j < _imagesPyramids[i]->getNumberOfLevels(); ++j) { //soc + float coeff = 1.0f; // 1 / 255.0f; // 100 * 255; // * pow(2, j); + //soc QImage qtmp(ow, oh, QImage::Format_RGB32); + ImBuf *ibuf = IMB_allocImBuf(ow, oh, 32, IB_rect); + int rowbytes = ow * 4; + char *pix; + + for (int y = 0; y < oh; ++y) { //soc + for (int x = 0; x < ow; ++x) { //soc + int c = (int)(coeff * _imagesPyramids[i]->pixel(x, y, j)); + if (c > 255) + c = 255; + //int c = (int)(_imagesPyramids[i]->pixel(x, y, j)); - //soc QString base("SteerableViewMap"); - string base("SteerableViewMap"); - stringstream filename; - - for(int j=0; j<_imagesPyramids[i]->getNumberOfLevels(); ++j){ //soc - float coeff = 1;//1/255.f; //100*255;//*pow(2,j); - //soc QImage qtmp(ow, oh, QImage::Format_RGB32); - ImBuf *ibuf = IMB_allocImBuf(ow, oh, 32, IB_rect); - int rowbytes = ow*4; - char *pix; - - for(int y=0;y<oh;++y){ //soc - for(int x=0;x<ow;++x){ //soc - int c = (int)(coeff*_imagesPyramids[i]->pixel(x,y,j)); - if(c>255) - c=255; - //int c = (int)(_imagesPyramids[i]->pixel(x,y,j)); - - //soc qtmp.setPixel(x,y,qRgb(c,c,c)); - pix = (char*)ibuf->rect + y*rowbytes + x*4; - pix[0] = pix [1] = pix[2] = c; - } - } + //soc qtmp.setPixel(x, y, qRgb(c, c, c)); + pix = (char*)ibuf->rect + y * rowbytes + x * 4; + pix[0] = pix [1] = pix[2] = c; + } + } - //soc qtmp.save(base+QString::number(i)+"-"+QString::number(j)+".png", "PNG"); - filename << base; - filename << i << "-" << j << ".png"; - ibuf->ftype= PNG; - IMB_saveiff(ibuf, const_cast<char *>(filename.str().c_str()), 0); - - } - // 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"); - // } - // - } + //soc qtmp.save(base+QString::number(i)+"-"+QString::number(j)+".png", "PNG"); + filename << base; + filename << i << "-" << j << ".png"; + ibuf->ftype = PNG; + IMB_saveiff(ibuf, const_cast<char *>(filename.str().c_str()), 0); + } +#if 0 + 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.0f; // 100 * 255; // * pow(2, j); + QImage qtmp(ow, oh, 32); + for (unsigned int y = 0; y < oh; ++y) { + for (unsigned int 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"); + } +#endif + } } |