template <typename PointSource, typename PointFeature> void pcl::MultiscaleFeaturePersistence<PointSource, PointFeature>::extractUniqueFeatures () { unique_features_indices_.resize (scale_values_.size ()); unique_features_table_.resize (scale_values_.size ()); for (size_t scale_i = 0; scale_i < features_at_scale_vectorized_.size (); ++scale_i) { // Calculate standard deviation within the scale float standard_dev = 0.0; std::vector<float> diff_vector (features_at_scale_vectorized_[scale_i].size ()); for (size_t point_i = 0; point_i < features_at_scale_vectorized_[scale_i].size (); ++point_i) { float diff = distanceBetweenFeatures (features_at_scale_vectorized_[scale_i][point_i], mean_feature_); standard_dev += diff * diff; diff_vector[point_i] = diff; } standard_dev = sqrtf (standard_dev / static_cast<float> (features_at_scale_vectorized_[scale_i].size ())); PCL_DEBUG ("[pcl::MultiscaleFeaturePersistence::extractUniqueFeatures] Standard deviation for scale %f is %f\n", scale_values_[scale_i], standard_dev); // Select only points outside (mean +/- alpha * standard_dev) std::list<size_t> indices_per_scale; std::vector<bool> indices_table_per_scale (features_at_scale_[scale_i]->points.size (), false); for (size_t point_i = 0; point_i < features_at_scale_[scale_i]->points.size (); ++point_i) { if (diff_vector[point_i] > alpha_ * standard_dev) { indices_per_scale.push_back (point_i); indices_table_per_scale[point_i] = true; } } unique_features_indices_[scale_i] = indices_per_scale; unique_features_table_[scale_i] = indices_table_per_scale; } }
SpectrumCoef_d MERLMeasuredData::GetBRDF(const Vector3D_d &i_incident, const Vector3D_d &i_exitant) const { if (m_brdf_data.empty()) return SpectrumCoef_d(); Vector3D_d half_angle = i_incident+i_exitant; if (half_angle[0] == 0.0 && half_angle[1] == 0.0 && half_angle[2] == 0.0) return SpectrumCoef_d(); half_angle.Normalize(); double sin_theta, cos_theta, sin_phi, cos_phi; MathRoutines::SphericalAngles(half_angle, sin_theta, cos_theta, sin_phi, cos_phi); Vector3D_d whx(cos_phi * cos_theta, sin_phi * cos_theta, -sin_theta); Vector3D_d why(-sin_phi, cos_phi, 0); Vector3D_d diff_vector(i_incident*whx, i_incident*why, i_incident*half_angle); double half_vector_theta = MathRoutines::SphericalTheta(half_angle); double diff_vector_theta = MathRoutines::SphericalTheta(diff_vector), diff_vector_phi = MathRoutines::SphericalPhi(diff_vector); ASSERT(half_vector_theta >= 0.0 && diff_vector_phi >= 0.0 && diff_vector_theta >= 0.0); // Because of reciprocity, the BRDF is unchanged under diff_vector_phi -> diff_vector_phi - M_PI // Instead of subtracting M_PI from diff_vector_phi (if needed) we just take the computed index modulo BRDF_SAMPLING_RES_PHI_D size_t diff_vector_phi_index = size_t(diff_vector_phi * INV_PI * BRDF_SAMPLING_RES_PHI_D) % BRDF_SAMPLING_RES_PHI_D; size_t diff_vector_theta_index = std::min(size_t(diff_vector_theta * 2.0 * INV_PI * BRDF_SAMPLING_RES_THETA_D), BRDF_SAMPLING_RES_THETA_D - 1); double half_vector_theta_deg_scaled = sqrt(half_vector_theta * 2.0 * INV_PI) * BRDF_SAMPLING_RES_THETA_H; size_t half_vector_theta_index = std::min(size_t(half_vector_theta_deg_scaled), BRDF_SAMPLING_RES_THETA_H - 1); size_t index = diff_vector_phi_index + (diff_vector_theta_index + half_vector_theta_index * BRDF_SAMPLING_RES_THETA_D) * BRDF_SAMPLING_RES_PHI_D; ASSERT(index>=0 && index<BRDF_SAMPLING_RES_THETA_H*BRDF_SAMPLING_RES_THETA_D*BRDF_SAMPLING_RES_PHI_D); if (index < (BRDF_SAMPLING_RES_THETA_H-1)*BRDF_SAMPLING_RES_THETA_D*BRDF_SAMPLING_RES_PHI_D) { // Interpolate by the theta angle of half vector. double t = half_vector_theta_deg_scaled-(size_t)half_vector_theta_deg_scaled; return Convert<double>(m_brdf_data[index])*(1.0-t) + Convert<double>(m_brdf_data[index+BRDF_SAMPLING_RES_THETA_D*BRDF_SAMPLING_RES_PHI_D])*t; } else return Convert<double>( m_brdf_data[index] ); }