11 #ifndef BRAINRAT_CLASSIFICATION_BIOVISION_D_H
12 #define BRAINRAT_CLASSIFICATION_BIOVISION_D_H
18 #include <aims/data/data_g.h>
19 #include <aims/io/writer.h>
20 #include <aims/io/reader.h>
21 #include <aims/utility/converter_g.h>
22 #include <aims/utility/progress.h>
24 #include <aims/roi/roiIterator.h>
25 #include <aims/roi/maskIterator.h>
26 #include <aims/connectivity/connectivity.h>
27 #include <aims/connectivity/component.h>
30 #include <cartodata/volume/volume.h>
32 #include <soma-io/allocator/allocator.h>
34 #include <cartobase/stream/fileutil.h>
35 #include <cartobase/smart/rcptr.h>
36 #include <cartobase/type/string_conversion.h>
48 template <
typename T> int32_t
50 const std::string & inputGraph,
51 const std::string & fileOutMeasure,
52 std::vector<carto::Object > & classDesc,
53 std::vector<std::vector<std::vector<double> > > & classVectors )
56 carto::rc_ptr<aims::MaskIterator> mask = aims::getMaskIterator( inputGraph );
59 std::vector< aims::InterpolatedVolume > interpolators;
60 interpolators.reserve(_measuresize);
62 for(
int j=0; j<_measuresize; ++j) {
63 carto::VolumeRef<T> view = image.view( Point4di( 0, 0, 0, j), Point4di(image.getSizeX(), image.getSizeY(), image.getSizeZ(), 1) );
66 interpolators.push_back( interpolated );
70 const carto::rc_ptr<aims::RoiIterator> roiIterator = aims::getRoiIterator( inputGraph );
72 while( roiIterator->isValid() ) {
74 bool newregion =
true;
77 for( k=0; k<classDesc.size(); ++k )
80 const std::string & s = classDesc[k]->getProperty(
"n")->carto::GenericObject::value<std::string>();
81 if( s == roiIterator->regionName() ) {
84 std::cout <<
"Add measure vectors to existing region "
85 << roiIterator->regionName() << std::endl;
94 std::cout <<
"Create new region " << roiIterator->regionName()
97 carto::Object c = carto::Object::value(carto::PropertySet());
98 c->setProperty(
"n", roiIterator->regionName() );
99 c->setProperty(
"p", 0.);
100 classDesc.push_back(c);
102 std::vector<std::vector<double> > cv;
103 classVectors.push_back( cv );
106 carto::rc_ptr<aims::MaskIterator> roiMaskIterator = roiIterator->maskIterator();
107 size_t point_count = 0;
110 while( roiMaskIterator->isValid() ) {
112 std::vector<double> v(_measuresize);
113 Point3df coord_f = roiMaskIterator->valueMillimeters();
115 for( int32_t j=0; j<_measuresize; ++j )
116 v[j] = interpolators[j].atMm( coord_f[0], coord_f[1], coord_f[2] );
118 classVectors[k].push_back(v);
121 roiMaskIterator->next();
125 std::cout << carto::toString(point_count)
126 <<
" measure vectors added to "
127 << roiIterator->regionName()
137 std::vector<carto::Object > & classDesc,
138 std::vector<std::vector<std::vector<double> > > & classVectors )
142 std::cout <<
"Clustering measure vectors ..." << std::endl
143 <<
"Clustering parameters [ threshold = " << _threshold
144 <<
", cluster number maximum = " << _nbclustermax
145 <<
", sigma minimum = " << _sigmamin
146 <<
", sigma ratio = " << _sigmaratio <<
" ]" << std::endl;
148 if( !inputListOfPrior.empty() && inputListOfPrior.size() != classDesc.size() )
149 throw (
"number of priors and classes must match! " ) ;
151 std::list<double>::iterator itp = inputListOfPrior.begin();
154 std::vector<carto::Array<carto::Array<carto::Array<int> > > > histo(classDesc.size());
161 for(
int p = 0; p < classDesc.size(); ++p )
164 std::vector<std::vector<double> > & mv = classVectors[p];
165 std::vector<double> d;
167 int nbvectors = mv.size();
168 nbtotal += nbvectors;
170 if( carto::verbose ) {
171 std::cout <<
"Clustering " << carto::toString(nbvectors)
172 <<
" measure vectors of " << classDesc[p]->getProperty(
"n")->value<std::string>()
173 <<
"..." << std::endl;
176 carto::VolumeRef<int> C( nbvectors );
178 std::vector<std::vector<double> > centroids
179 = Clustering( mv, _threshold, _sigmamin, _sigmaratio,
180 _nbclustermax, _newclusterpolicy, _clustersizemin, C ) ;
183 int nbclusters = centroids.size();
184 d.push_back(nbclusters);
187 std::cout <<
"Processing density parameters for "
188 << carto::toString(nbclusters)
189 <<
" clusters..." << std::endl;
192 carto::VolumeRef<double> ro( nbclusters );
194 for(
int i = 0 ; i < nbvectors; ++i ) {
200 for(
int k = 0 ; k < nbclusters ; ++k ) {
207 std::cout <<
"ro(" << carto::toString(k) <<
") : "
208 << carto::toString(ro(k)) << std::endl;
211 std::vector<double> mu = centroids[k];
213 for (
int i = 0; i < _measuresize; ++i) {
218 std::vector<std::vector<double> > M;
219 std::vector<std::vector<double> > qk;
220 for (
int i = 0 ; i < nbvectors; ++i) {
227 for (
int i = 0; i < _measuresize; ++i) {
231 carto::VolumeRef<double> hdata(qk.size());
232 for(int32_t j = 0; j < hdata.getSizeX(); ++j) {
233 hdata(j) = ((std::vector<double>)qk[j])[i];
236 h.
doit(hdata, 0, 255);
240 for (int32_t j = 0; j < h.
data().getSizeX(); ++j) {
241 v.push_back(h.
data()(j));
245 histo[p].push_back(mh);
247 int nvcluster = qk.
size();
248 d.push_back(nvcluster);
251 for (
int i = 0 ; i < nvcluster; ++i) {
252 std::vector<double> diff(qk[i].size());
253 for(
int j = 0;j<qk[i].size(); ++j){
254 diff[j] = qk[i][j] - mu[j];
259 carto::VolumeRef<double> cov(_measuresize, _measuresize), I(_measuresize, _measuresize);
261 for (
int i = 0; (i< _measuresize); ++i) {
263 for (
int j = 0 ; (j < _measuresize); ++j) {
264 for (
int k = 0 ; k < nvcluster; ++k) {
265 cov (i,j) += M[k][i] * M[k][j] ;
267 cov(i,j) /= nvcluster;
272 double detcov = det(cov, I);
274 for (
int i = 0; i < _measuresize; ++i) {
275 for (
int j = 0 ; j < _measuresize; ++j) {
281 classDesc[p]->setProperty(
"d", d);
282 classDesc[p]->setProperty(
"h", histo[p]);
285 if (inputListOfPrior.empty ())
286 classDesc[p]->getProperty(
"p")->value<
double>() = 1.0 / ((
double)classDesc.size());
288 classDesc[p]->getProperty(
"p")->value<
double>() = (*itp) ;
293 std::cout <<
"prior : " << classDesc[p]->getProperty(
"p")->value<
double>() << std::endl;
294 std::cout <<
"density : [" << d[0];
295 for(
int i=1; i<d.size(); ++i)
296 std::cout <<
"," << d[i];
297 std::cout <<
"]" << std::endl;
301 std::cout << carto::toString(nbtotal) <<
" pixels clustered." << std::endl;
303 _learningmodel = carto::Object::value(carto::PropertySet());
304 _learningmodel->setProperty(
"data", classDesc );
313 template <
typename T>
315 carto::VolumeRef<T> &image )
317 std::vector<double> w(_measuresize);
318 for ( int32_t j = 0; j < _measuresize; ++j) {
319 w[j] = image(t[0],t[1],t[2],j);
322 return Classifier(w, t,
false,
false,
true);
325 template <
typename T> int32_t
327 const std::vector<int32_t> &labels,
328 const std::vector<std::string> &classesorder,
329 const std::string &maskFile,
330 const bool keepClasses,
331 const bool keepProba,
332 const bool keepDensity)
335 std::vector<int32_t> l = labels;
338 for (int32_t i = 0; i < _nbclasses; ++i)
341 else if (l.size() != _nbclasses) {
342 throw std::runtime_error(
"Number of labels specified does not match the number of classes in model." );
345 std::map<std::string, int32_t> orders;
346 if (classesorder.empty()) {
348 for (int32_t i = 0; i < _nbclasses; ++i)
349 orders[_classdesc[i]->getProperty(
"n")->carto::GenericObject::value<std::string>()] = i;
351 else if (classesorder.size() != _nbclasses) {
352 throw std::runtime_error(
"Number of classes specified in classes order does not match the number of classes in model." );
358 std::vector<std::string>::const_iterator k, ek = classesorder.end();
359 for ( k = classesorder.begin(); k != ek; ++k, ++i) {
362 for (int32_t j = 0; j < _classdesc.size(); ++j) {
363 if (_classdesc[j]->getProperty(
"n")->carto::GenericObject::value<std::string>() == *k) {
374 throw std::runtime_error(
"Class " + *k +
" specified in classes order was not found in model." );
379 int dx = image.getSizeX(), dy = image.getSizeY(), dz = image.getSizeZ();
382 carto::rc_ptr<aims::MaskIterator> mask;
385 if (!maskFile.empty()) {
387 std::cout <<
"Reading mask image ..." << std::endl;
388 mask = aims::getMaskIterator( maskFile );
394 std::cout <<
"Allocating classification image ..." << std::endl;
395 _Cimage = carto::VolumeRef<int16_t>(dx, dy, dz);
396 _Cimage.copyHeaderFrom(image.header());
403 std::cout <<
"Allocating probability image ..." << std::endl;
404 _Pimage = carto::VolumeRef<double>( dx, dy, dz, _nbclasses );
405 _Pimage.copyHeaderFrom(image.header());
412 std::cout <<
"Allocating density image ..." << std::endl;
413 _Dimage = carto::VolumeRef<double>( dx, dy, dz, _nbclasses );
414 _Dimage.copyHeaderFrom(image.header());
419 if (carto::verbose) {
420 std::cout <<
"Starting segmentation ..." << std::endl;
421 for (int32_t i = 0; i < _nbclasses; ++i)
423 const std::string & s = _classdesc[i]->getProperty(
"n")->carto::GenericObject::value<std::string>();
424 std::cout <<
"Class " << s
425 <<
" label " << carto::toString(l[i]) << std::endl;
429 std::vector<double> w(_measuresize);
438 aims::Progression progress(dz - 1);
440 std::cout <<
"Progress: ";
442 for( int32_t z = 0; z < dz; ++z, ++progress ) {
443 if(dz>1) std::cout << progress << std::flush;
444 for( int32_t y = 0; y < dy; ++y )
445 for( int32_t x = 0; x < dx; ++x )
446 if( mask.isNull() || mask->contains( Point3df(
447 image.getVoxelSize()[0] * x, image.getVoxelSize()[1] * y, image.getVoxelSize()[2] * z ) ) )
449 c = Point3dl( x, y, z );
450 for ( int32_t j = 0; j < _measuresize; j++)
451 w[j] = image(x,y,z,j);
452 ic = Classifier( w, c, keepProba, keepDensity );
455 if( (ic > -1) && keepClasses ) {
457 int32_t o = orders[_classdesc[ic]->getProperty(
"n")->carto::GenericObject::value<std::string>()];
458 _Cimage(x,y,z) = l[ o ];
467 const std::string &outputProbaFile,
468 const std::string &outputDensityFile )
470 int out = EXIT_SUCCESS;
473 if( !outputProbaFile.empty() && !_Pimage.get() )
475 std::cout <<
"Proba image was not saved ! "
477 <<
"Run classification again with keepProba parameter "
482 else if( !outputProbaFile.empty() )
485 std::cout <<
"Writing proba image : " << outputProbaFile << std::endl;
487 aims::Writer<carto::Volume<double> > outputProbaWriter( outputProbaFile );
488 outputProbaWriter << *(_Pimage);
492 if( !outputDensityFile.empty() && !_Dimage.get() )
494 std::cout <<
"Density image was not saved ! "
496 <<
"Run classification again with keepDensity parameter "
501 else if( !outputDensityFile.empty() )
504 std::cout <<
"Writing density image : " << outputDensityFile << std::endl;
506 aims::Writer<carto::Volume<double> > outputDensityWriter( outputDensityFile );
507 outputDensityWriter << *(_Dimage);
511 if( !outputFile.empty() && !_Cimage.get() )
513 std::cout <<
"Classification image was not saved ! "
515 <<
"Run classification again with keepClasses parameter "
520 else if( !outputFile.empty() )
523 std::cout <<
"Writing output image : " << outputFile << std::endl;
525 aims::Writer<carto::Volume<int16_t> > outputWriter(outputFile);
526 outputWriter << *(_Cimage);
carto::VolumeRef< int32_t > & data()
void setVolume(const carto::Volume< T > &vol, int order=-1)
void doit(const carto::rc_ptr< carto::Volume< T > > &thing)
int32_t writeResults(const std::string &outputFile="", const std::string &outputProbaFile="", const std::string &outputDensityFile="")
int32_t classify(carto::VolumeRef< T > &image, const std::vector< int32_t > &labels, const std::vector< std::string > &classesorder, const std::string &maskFile="", const bool keepClasses=true, const bool keepProba=false, const bool keepDensity=false)
virtual int32_t learnClustering(std::list< double > &inputListOfPrior, std::vector< carto::Object > &classDesc, std::vector< std::vector< std::vector< double > > > &classVectors)
int32_t processOneImage(carto::VolumeRef< T > &inputImage, const std::string &inputGraph, const std::string &fileOutMeasure, std::vector< carto::Object > &classDesc, std::vector< std::vector< std::vector< double > > > &classVectors)
virtual size_t size() const