segment.cc
来自「用于计算矩阵的特征值,及矩阵的其他运算.可以用与稀疏矩阵」· CC 代码 · 共 797 行 · 第 1/2 页
CC
797 行
// Copyright (C) 2002 Charless C. Fowlkes <fowlkes@eecs.berkeley.edu>// Copyright (C) 2002 David R. Martin <dmartin@eecs.berkeley.edu>//// 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, or see http://www.gnu.org/copyleft/gpl.html.#include <assert.h>#include <stdio.h>#include <string.h>#include <fstream>#include <iostream>#include "types.hh"#include "array.hh"#include "util.hh"#include "exception.hh"#include "string.hh"#include "configure.hh"#include "kmeans.hh"#include "segmentation.hh"#include "smatrix.hh"#include "dmatrix.hh"#include "affinity.hh"#include "pb.hh"#include "ic.hh"#include "region.hh"//read/write cached Pb edge map?static bool readLattice;static const char* latticeFileName;//write out intermediate resultsstatic const char* evecFileName;static const char* egradFileName;//cuesstatic Group::cueModeType cueMode;static const char* const cueModeStrings[] = {"ic","patch","both",NULL};static bool useColor;static int dthresh;static float sigma;//computing discrete ncutstatic const char** segFiles;static int numSegFiles;static int dustThresh;//affinity matrixstatic const char* smatrixFileName;//eigenvectorsstatic bool filterEvec;static int numVectors;//clusteringstatic int numSuperpixels;static const char* segFileName;static const char* graphFileName;//static int numGroups;//static const char* segFileName;//the imagestatic const char* imageFileName;static voidregisterConfig (){ Util::registerConfig(); Group::Pb::registerConfig(); Group::Region::registerConfig(); Configure::registerString( "image", NULL, "Image file to proccess"); Configure::registerBool( "readlattice", false, "Read in pb data?"); Configure::registerString( "latticefile", NULL, "Pb lattice data file name"); Configure::registerInt( "dthresh",5,"Connectivity distance threshold in pixels"); Configure::registerFloat( "sigma",0.1,"Sigma non-linearity"); Configure::registerBool( "usecolor", true, "Use color info."); Configure::registerEnum( "cues",cueModeStrings,Group::ic, "What cues to use in similarity computation"); Configure::registerString( "smatrixfile", NULL, "Write out affinity matrix"); Configure::registerInt( "numvectors", 16, "Number of eigenvectors."); Configure::registerBool( "filterevec", true, "Median filter eigenvectors."); Configure::registerString( "evecfile", NULL, "Write out eigenvector data"); Configure::registerString( "egradfile", NULL, "Write out eigenvector gradient data"); Configure::registerInt( "numsuperpixels", 50, "Number of superpixels."); Configure::registerString( "segfile", NULL, "Write out superpixel segmentation"); Configure::registerString( "graphfile", NULL, "Write out collapsed graph data"); Configure::registerInt( "dustthresh", 10, "How small before we merge a disconnected component.");}static voidinit (const int index, const int argc, const char** argv){ Util::init(); segFiles = &argv[index]; numSegFiles = argc - index; imageFileName = Configure::getString("image"); latticeFileName = Configure::getString("latticefile"); readLattice = Configure::getBool("readlattice"); dthresh = Configure::getInt("dthresh"); sigma = Configure::getFloat("sigma"); useColor = Configure::getBool("usecolor"); cueMode = (Group::cueModeType)Configure::getEnum("cues"); smatrixFileName = Configure::getString("smatrixfile"); numVectors = Configure::getInt("numvectors"); filterEvec = Configure::getBool("filterevec"); egradFileName = Configure::getString("egradfile"); evecFileName = Configure::getString("evecfile"); graphFileName = Configure::getString("graphfile"); numSuperpixels = Configure::getInt("numsuperpixels"); dustThresh = Configure::getInt("dustthresh"); segFileName = Configure::getString("segfile"); if (imageFileName == NULL) { throw Util::Exception (Util::String ("image filename is required")); }}////////////////////////////////////////////////////////////////////////////////// compute gradients on telescoping sets of eigenvectors and run// non-maxima supression on the results.//void computeEigengradients(const Util::ImageStack& evec, Util::ImageStack& pbs){ const int numVectors = evec.size(0); const int width = evec.size(1); const int height = evec.size(2); Util::Image g1(width,height); g1.init(0); Util::Image g2(width,height); g2.init(0); Util::Image g12(width,height); g12.init(0); Util::Image mag(width,height); Util::Image ori(width,height); Util::Image dx(width,height); Util::Image dy(width,height); Util::Image gradient(width,height); pbs.resize(numVectors,width,height); //create filters double smooth = 0.5; Util::Image hFilt; Util::Image vFilt; Group::FilterBank::createGaussianKernel(smooth, smooth, 10.0, 1.5708, 1, false,hFilt); Group::FilterBank::createGaussianKernel(smooth, smooth, 10.0, 0, 1, false,vFilt); //filter each set of vectors up to i for (int i = 0; i < numVectors; i++) { getFiltered(*evec.slice(i),hFilt,dx); getFiltered(*evec.slice(i),vFilt,dy); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { double f1 = g1(x,y) + dx(x,y)*dx(x,y); double f2 = g2(x,y) + dy(x,y)*dy(x,y); double f12 = g12(x,y) + dx(x,y)*dy(x,y); double orival = 0.5*atan(2*f12 / (f1 - f2)); if ((f1-f2) < 0) { if (2*f12>0) { orival+=M_PI/2; } else { orival-=M_PI/2; } } mag(x,y) = 0.5*(f1 + f2 + sqrt((f1-f2)*(f1-f2) + 4*f12*f12)); ori(x,y) = fmod(-orival+(M_PI/2),M_PI); g1(x,y) = f1; g2(x,y) = f2; g12(x,y) = f12; } } Group::nonmaxSuppress(mag,ori,gradient); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { pbs(i,x,y) = gradient(x,y); } } }}//////////////////////////////////////////////////////////////////////////////void densify(const Util::Array2D<float>& W, const Util::Segmentation& seg, const int desiredNumSP, Util::Segmentation& coarseSeg, Util::Array2D<float>& Wcoarse){ static int level = 0; const int width = seg.getWidth(); const int height = seg.getHeight(); const int numP = W.size(0); level++; Util::Message::debug("computing eigenvectors of G"); DMatrix* DW = new DMatrix(W); double* rowSum = DW->getRowSum(); DW->normalizedLaplacian(rowSum); double* devec; double* deval; DW->eig(numVectors+1,&devec,&deval); DW->undoNormalizedLaplacian(rowSum); Util::Message::startBlock("finding superpixels"); Util::Message::debug("transposing eigenvectors"); Util::Array2D<float> embed(numP,numVectors); for (int vnum = 0; vnum < numVectors; vnum++) { for (int pnum = 0; pnum < numP; pnum++) { embed(pnum,vnum) = devec[(vnum+1)*numP + pnum] / devec[0*numP + pnum]; } } Util::Message::startBlock(50,Util::String("running kmeans k=%d",desiredNumSP)); Util::Image means(desiredNumSP, numVectors); Util::Array1D<int> bestMembership(numP); Util::kmeans(embed, desiredNumSP, 1e-4, 30, true, means, bestMembership); float bestNcut = DW->computeNCut(rowSum,bestMembership); for (int iter = 0; iter < 50; iter++) { Util::Message::stepBlock(); Util::Array1D<int> membership(width*height); Util::kmeans(embed, desiredNumSP, 1e-4, 30, true, means, membership); float ncut = DW->computeNCut(rowSum,membership); if (ncut < bestNcut) { ncut = bestNcut; bestMembership = membership; } } Util::Message::endBlock(); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { coarseSeg(x,y) = bestMembership(seg(x,y)); } } Util::Message::debug("post-processing segmentation"); coarseSeg.fragment(); coarseSeg.mergeDust(dustThresh); Util::Array1D<int> segmentSizes; coarseSeg.segSizes(segmentSizes); int numSP = segmentSizes.size(0); Util::Message::debug(Util::String("found %d superpixels",numSP)); Util::Message::endBlock(); Util::Message::debug("coarsening graph"); Util::Array1D<int> p2sp(numP); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { p2sp(seg(x,y)) = coarseSeg(x,y); } } Util::Array2D<float> Wsum(numSP,numSP); Wsum.init(0); Util::Array2D<float> D(numSP,numSP); D.init(0); for (int i = 0; i < numP; i++) { for (int j = 0; j < numP; j++) { //collapse the edge from i to j into the superpixel edge Wsum(p2sp(i),p2sp(j)) += W(i,j); D(p2sp(i),p2sp(j))++; //TODO???? should we be adding a different degree here? } } Util::Message::debug("densifying graph"); Wcoarse.resize(numSP,numSP); for (int i = 0; i < numSP; i++) { for (int j = 0; j < numSP; j++) { double dense = 0; if (D(i,j) != 0) { dense = segmentSizes(i)*(Wsum(i,j) / D(i,j))*segmentSizes(j); } Wcoarse(i,j) = dense; } } if (evecFileName != NULL) { Util::ImageStack evecImage(numVectors,width,height); for (int vnum = 0; vnum < numVectors; vnum++) { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { int pnum = seg(x,y); evecImage(vnum,x,y) = devec[vnum*numP + pnum]; } } } char filename[1000]; sprintf(filename,"%s.%d",evecFileName,level); Util::Message::debug("writing eigenvector file"); std::ofstream out(filename); if (!out.good()) { throw Util::Exception (Util::String ("Error opening '%s' for writing.", evecFileName)); } out << evecImage; out.close(); } if (graphFileName != NULL) { char filename[1000]; sprintf(filename,"%s.%d",graphFileName,level); Util::Message::debug("writing coarsened graph file"); std::ofstream out(filename); out << seg << W << Wsum << D << Wcoarse << coarseSeg; out.close(); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?