std::vector<Index> partition(Count k, Count n, Rng& rng) { struct P { Index idx; Count sz; bool operator<(const P& p) const { return sz < p.sz; } }; std::vector<P> ps(n, {0, 0}); auto i = 0; for (auto& p : ps) p.idx = i++; auto cs = GenerateClusters(n, rng); for (auto c : cs) { ++ps[c].sz; } std::partial_sort(ps.begin(), ps.end()-k, ps.end()); std::vector<bool> res(ps.size(), true); for (auto i = 0; i < n-k; ++i) { res[ps[i].idx] = false; } DecreaseClustering(cs, res); auto it = std::remove_if(centers_.begin(), centers_.end(), [&](Index c){ return cs[c] == -1; }); centers_.erase(it, centers_.end()); auto redoCount = std::count(cs.begin(), cs.end(), -1); std::vector<Index> origs; origs.reserve(redoCount); for (int i = 0; i < cs.size(); ++i) { if (cs[i] != -1) origs.push_back(i); } return GenerateClusters(origs); }
std::vector<Index> GenerateClusters(Count k, Rng& rng) { std::vector<Index> clusters(g.nodeCount()); std::uniform_int_distribution<> distr_v(0, g.nodeCount()-1); auto& origs = centers_; origs.clear(); for (auto i = 0; i < k;) { auto n = distr_v(rng); auto it = lower_bound(origs.begin(), origs.end(), n); if (*it == n) { continue; } // vector... origs.insert(it, n); ++i; } return GenerateClusters(origs); }
// bool TePDIIsosegClas::Implementation(const TePDIParameters& params) bool TePDIIsosegClas::RunImplementation() { // Setting the parameters TePDITypes::TePDIRasterVectorType input_rasters; params_.GetParameter("input_rasters", input_rasters); vector<int> bands; params_.GetParameter("bands", bands); W = input_rasters[0]->params().ncols_; H = input_rasters[0]->params().nlines_; TePDITypes::TePDIPolygonSetPtrType input_polygonset; params_.GetParameter("input_polygonset", input_polygonset); TePDITypes::TePDIRasterPtrType output_raster; params_.GetParameter("output_raster", output_raster); double acceptance_limiar; params_.GetParameter("acceptance_limiar", acceptance_limiar); /* Setting the output raster */ TeRasterParams output_raster_params = output_raster->params(); output_raster_params.setDataType( TeDOUBLE, -1 ); output_raster_params.nBands( 1 ); if( input_rasters[0]->projection() != 0 ) { TeSharedPtr< TeProjection > proj( TeProjectionFactory::make( input_rasters[0]->projection()->params() ) ); output_raster_params.projection( proj.nakedPointer() ); } output_raster_params.boxResolution( input_rasters[0]->params().box().x1(), input_rasters[0]->params().box().y1(), input_rasters[0]->params().box().x2(), input_rasters[0]->params().box().y2(), input_rasters[0]->params().resx_, input_rasters[0]->params().resy_ ); // output_raster_params.setPhotometric( TeRasterParams::TeRGB, -1 ); TEAGN_TRUE_OR_RETURN( output_raster->init( output_raster_params ), "Output raster reset error" ); for (unsigned pols = 0; pols < input_polygonset->size(); pols++) { TePolygon polygon(input_polygonset->operator[](pols)); // this iterator "walks" in the image, on the region defined by a specific polygon TeRaster::iteratorPoly it = input_rasters[0]->begin(polygon, TeBoxPixelIn, 0); TeRaster::iteratorPoly it_end = input_rasters[0]->end(polygon, TeBoxPixelIn, 0); long area = (long)TeGeometryArea(polygon); // pixel vector for each band vector<vector<double> > pixels_per_band(bands.size()); vector<double> sums(bands.size()); vector<double> tmp(1); for (unsigned band = 0; band < bands.size(); band++) pixels_per_band.push_back(tmp); long npix = 0; double tmp_pixel; while(it != it_end) { int col = it.currentColumn(), lin = it.currentLine(); if ((col >= 0 && col < W) && (lin >=0 && lin < H)) { for (unsigned band = 0; band < bands.size(); band++) { input_rasters[band]->getElement(col, lin, tmp_pixel, band); pixels_per_band[band].push_back(tmp_pixel); sums[band] += tmp_pixel; } npix++; } ++it; } vector<double> tmp_mean; tmp_mean.reserve(bands.size()); for (unsigned band = 0; band < bands.size(); band++) { tmp_mean.push_back(sums[band]/npix); } // sets the covarariance matrix TeMatrix tmp_covar; int nbands = bands.size(); TEAGN_TRUE_OR_RETURN(tmp_covar.Init(nbands, nbands, 0.0), "Unable to Init tmp_covar"); double sum; for(int i = 0; i < nbands; i++) for(int j = 0; j < nbands; j++) { sum = 0.0; for (int p = 0; p < npix; p++) sum += (pixels_per_band[i][p] - tmp_mean[i]) * (pixels_per_band[j][p] - tmp_mean[j]); if (npix == 1) tmp_covar(i,j) = 0.0; else tmp_covar(i,j) = (double)(sum / (npix - 1)); } TePDIRegion tmp_region(pols); TEAGN_TRUE_OR_RETURN(tmp_region.Init(bands.size(), npix, tmp_mean, tmp_covar), "Unable to Init tmp_region"); regions.insert(pair<double, TePDIRegion>(area, tmp_region)); } total_regions = regions.size(); TEAGN_TRUE_OR_RETURN(SetThreshold(acceptance_limiar, bands.size()), "Unable to SetThreshold"); TEAGN_TRUE_OR_RETURN(GenerateClusters(), "Unable to GenerateClusters"); TEAGN_TRUE_OR_RETURN(MergeClusters(), "Unable to MergeClusters"); // remap cluster values to 1 -> N std::set<unsigned int> ulabels; std::set<unsigned int>::iterator lit; std::map<unsigned int, unsigned int> colormap; for (int pols = 0; pols < total_regions; pols++) { TePolygon polygon(input_polygonset->operator[](pols)); // searches for the region with Id = pols multimap<double, TePDIRegion, greater<double> >::iterator regions_it; for (regions_it = regions.begin(); regions_it != regions.end(); ++regions_it) if (regions_it->second.GetId() == pols) break; ulabels.insert(regions_it->second.GetClass()); } unsigned int color = 1; for (lit = ulabels.begin(); lit != ulabels.end(); ++lit) colormap[*lit] = color++; // paint output_raster with the correspondent classes for (int pols = 0; pols < total_regions; pols++) { TePolygon polygon(input_polygonset->operator[](pols)); // this iterator "walks" in the image, on the region defined by a specific polygon TeRaster::iteratorPoly it = input_rasters[0]->begin(polygon, TeBoxPixelIn, 0); TeRaster::iteratorPoly it_end = input_rasters[0]->end(polygon, TeBoxPixelIn, 0); // searches for the region with Id = pols multimap<double, TePDIRegion, greater<double> >::iterator regions_it, regions_tmp = regions.begin(); for (regions_it = regions.begin(); regions_it != regions.end(); ++regions_it) if (regions_it->second.GetId() == pols) { regions_tmp = regions_it; break; } unsigned bit_class = colormap[regions_it->second.GetClass()]; /* // here, a set of colors for up to 81 classes, C(3, 4) = tree bands, four levels vector<int> levels; levels.push_back(0); levels.push_back(50); levels.push_back(100); levels.push_back(150); levels.push_back(200); levels.push_back(255); int change = levels.size(); vector<int> colors_R, colors_G, colors_B; for (int c = 0, i = 0, j = 0, k = 0; c < 81; c++) { colors_R.push_back(levels[i]); colors_G.push_back(levels[j]); colors_B.push_back(levels[k]); i++; if (i >= change) { i = 0; j++; } if (j >= change) { j = 0; k++; } if (k >= change) k = 0; } if (bit_class >= colors_R.size()) bit_class = 0; double R = colors_R[bit_class], G = colors_G[bit_class], B = colors_B[bit_class]; */ // paint output_raster with specific color class while(it != it_end) { int i = it.currentColumn(), j = it.currentLine(); output_raster->setElement(i, j, bit_class); ++it; } } return true; }