LabelImage RandomForestImage::predict(const RGBDImage& image, cuv::ndarray<float, cuv::host_memory_space>* probabilities, const bool onGPU, bool useDepthImages) const { LabelImage prediction(image.getWidth(), image.getHeight()); const LabelType numClasses = getNumClasses(); if (treeData.size() != ensemble.size()) { throw std::runtime_error((boost::format("tree data size: %d, ensemble size: %d. histograms normalized?") % treeData.size() % ensemble.size()).str()); } cuv::ndarray<float, cuv::host_memory_space> hostProbabilities( cuv::extents[numClasses][image.getHeight()][image.getWidth()], m_predictionAllocator); if (onGPU) { cuv::ndarray<float, cuv::dev_memory_space> deviceProbabilities( cuv::extents[numClasses][image.getHeight()][image.getWidth()], m_predictionAllocator); cudaSafeCall(cudaMemset(deviceProbabilities.ptr(), 0, static_cast<size_t>(deviceProbabilities.size() * sizeof(float)))); { utils::Profile profile("classifyImagesGPU"); for (const boost::shared_ptr<const TreeNodes>& data : treeData) { classifyImage(treeData.size(), deviceProbabilities, image, numClasses, data, useDepthImages); } } normalizeProbabilities(deviceProbabilities); cuv::ndarray<LabelType, cuv::dev_memory_space> output(image.getHeight(), image.getWidth(), m_predictionAllocator); determineMaxProbabilities(deviceProbabilities, output); hostProbabilities = deviceProbabilities; cuv::ndarray<LabelType, cuv::host_memory_space> outputHost(image.getHeight(), image.getWidth(), m_predictionAllocator); outputHost = output; { utils::Profile profile("setLabels"); for (int y = 0; y < image.getHeight(); ++y) { for (int x = 0; x < image.getWidth(); ++x) { prediction.setLabel(x, y, static_cast<LabelType>(outputHost(y, x))); } } } } else { utils::Profile profile("classifyImagesCPU"); tbb::parallel_for(tbb::blocked_range<size_t>(0, image.getHeight()), [&](const tbb::blocked_range<size_t>& range) { for(size_t y = range.begin(); y != range.end(); y++) { for(int x=0; x < image.getWidth(); x++) { for (LabelType label = 0; label < numClasses; label++) { hostProbabilities(label, y, x) = 0.0f; } for (const auto& tree : ensemble) { const auto& t = tree->getTree(); PixelInstance pixel(&image, 0, x, y); const auto& hist = t->classifySoft(pixel); assert(hist.size() == numClasses); for(LabelType label = 0; label<hist.size(); label++) { hostProbabilities(label, y, x) += hist[label]; } } double sum = 0.0f; for (LabelType label = 0; label < numClasses; label++) { sum += hostProbabilities(label, y, x); } float bestProb = -1.0f; for (LabelType label = 0; label < numClasses; label++) { hostProbabilities(label, y, x) /= sum; float prob = hostProbabilities(label, y, x); if (prob > bestProb) { prediction.setLabel(x, y, label); bestProb = prob; } } } } }); } if (probabilities) { *probabilities = hostProbabilities; } return prediction; }
//------------------------------------------------------------------------------ InstancePlacer::InstancePlacer(unsigned layer_num, const TerrainDataClient * terrain_data, const std::vector<bbm::DetailTexInfo> & tex_info) : cur_camera_cell_x_(-1000), cur_camera_cell_z_(-1000), terrain_(terrain_data), instances_per_cell_(0), layer_num_(layer_num) { cos_threshold_steepness_ = cosf(deg2Rad(s_params.get<float>("instances.threshold_steepness"))); unsigned num_layers = s_params.get<unsigned>("instances.num_layers"); if (s_params.get<std::vector<float> >("instances.density_factor").size() != num_layers) { throw Exception("density factor not specified for all layers."); } cell_resolution_ = s_params.get<unsigned>("instances.cell_resolution"); cell_size_ = s_params.get<float> ("instances.base_draw_distance")*(layer_num+1) / cell_resolution_; if (!PlacedInstance::dummy_desc_.get()) { PlacedInstance::dummy_desc_.reset(new InstancedGeometryDescription("dummy")); } assert(cell_resolution_); cell_resolution_ |= 1; // Make sure we always have an odd number of cells instance_probability_.resize(tex_info.size()); instance_prototype_. resize(tex_info.size()); // The maximum density determines the number of instances allocated float max_density = std::numeric_limits<float>::min(); for (unsigned terrain_type=0; terrain_type<tex_info.size(); ++terrain_type) { max_density = std::max(max_density, tex_info[terrain_type].grass_density_); // Copy probabilities... instance_probability_[terrain_type].resize(tex_info[terrain_type].zone_info_.size()); for (unsigned t=0; t < instance_probability_[terrain_type].size(); ++t) { instance_probability_[terrain_type][t] = tex_info[terrain_type].zone_info_[t].probability_; } // Load model prototypes instance_prototype_[terrain_type].resize(tex_info[terrain_type].zone_info_.size()); for (unsigned obj=0; obj<instance_prototype_[terrain_type].size(); ++obj) { osg::ref_ptr<InstanceProxy> proxy; try { proxy = dynamic_cast<InstanceProxy*>( ReaderWriterBbm::loadModel(tex_info[terrain_type].zone_info_[obj].model_).get()); if (!proxy.get()) { Exception e("Error loading automatically placed object \""); e << tex_info[terrain_type].zone_info_[obj].model_ << "\". Perhaps it's not instanced?"; throw e; } } catch (Exception & e) { e.addHistory("InstancePlacer::InstancePlacer()"); throw e; } instance_prototype_[terrain_type][obj] = proxy; } } // Depending on the layer we are in, we want to have a different // instance density. max_density is the maximum density in // instances/m^2 specified for any terrain type and determines the // number of prototypes we have to allocate per cell. Terrain // types with smaller density have some prototypes unused // (probability doesn't sum up to one). // convert density to instances per cell, // adjust for layer number. instances_per_cell_ = (unsigned)(cell_size_*cell_size_ * max_density * s_params.get<std::vector<float> >("instances.density_factor")[layer_num_]* s_params.get<float>("instances.user_density")); // Perhaps there are no instances in this level, or user chose // zero density if (instances_per_cell_ == 0) return; normalizeProbabilities(instance_probability_, max_density, tex_info); initCells(); s_scheduler.addTask(PeriodicTaskCallback(this, &InstancePlacer::update), s_params.get<float>("instances.update_dt"), "InstancePlacer::update", &fp_group_); }