@@ -56,10 +56,9 @@ template <typename PointT, typename Scalar> inline unsigned int
5656compute3DCentroid (ConstCloudIterator<PointT> &cloud_iterator,
5757 Eigen::Matrix<Scalar, 4 , 1 > ¢roid)
5858{
59- // Initialize to 0
60- centroid.setZero ();
59+ Eigen::Matrix<Scalar, 4 , 1 > accumulator {0 , 0 , 0 , 0 };
6160
62- unsigned cp = 0 ;
61+ unsigned int cp = 0 ;
6362
6463 // For each point in the cloud
6564 // If the data is dense, we don't need to check for NaN
@@ -68,15 +67,19 @@ compute3DCentroid (ConstCloudIterator<PointT> &cloud_iterator,
6867 // Check if the point is invalid
6968 if (pcl::isFinite (*cloud_iterator))
7069 {
71- centroid [0 ] += cloud_iterator->x ;
72- centroid [1 ] += cloud_iterator->y ;
73- centroid [2 ] += cloud_iterator->z ;
70+ accumulator [0 ] += cloud_iterator->x ;
71+ accumulator [1 ] += cloud_iterator->y ;
72+ accumulator [2 ] += cloud_iterator->z ;
7473 ++cp;
7574 }
7675 ++cloud_iterator;
7776 }
78- centroid /= static_cast <Scalar> (cp);
79- centroid[3 ] = 1 ;
77+
78+ if (cp > 0 ) {
79+ centroid = accumulator;
80+ centroid /= static_cast <Scalar> (cp);
81+ centroid[3 ] = 1 ;
82+ }
8083 return (cp);
8184}
8285
@@ -88,12 +91,12 @@ compute3DCentroid (const pcl::PointCloud<PointT> &cloud,
8891 if (cloud.empty ())
8992 return (0 );
9093
91- // Initialize to 0
92- centroid.setZero ();
9394 // For each point in the cloud
9495 // If the data is dense, we don't need to check for NaN
9596 if (cloud.is_dense )
9697 {
98+ // Initialize to 0
99+ centroid.setZero ();
97100 for (const auto & point: cloud)
98101 {
99102 centroid[0 ] += point.x ;
@@ -106,20 +109,24 @@ compute3DCentroid (const pcl::PointCloud<PointT> &cloud,
106109 return (static_cast <unsigned int > (cloud.size ()));
107110 }
108111 // NaN or Inf values could exist => check for them
109- unsigned cp = 0 ;
112+ unsigned int cp = 0 ;
113+ Eigen::Matrix<Scalar, 4 , 1 > accumulator {0 , 0 , 0 , 0 };
110114 for (const auto & point: cloud)
111115 {
112116 // Check if the point is invalid
113117 if (!isFinite (point))
114118 continue ;
115119
116- centroid [0 ] += point.x ;
117- centroid [1 ] += point.y ;
118- centroid [2 ] += point.z ;
120+ accumulator [0 ] += point.x ;
121+ accumulator [1 ] += point.y ;
122+ accumulator [2 ] += point.z ;
119123 ++cp;
120124 }
121- centroid /= static_cast <Scalar> (cp);
122- centroid[3 ] = 1 ;
125+ if (cp > 0 ) {
126+ centroid = accumulator;
127+ centroid /= static_cast <Scalar> (cp);
128+ centroid[3 ] = 1 ;
129+ }
123130
124131 return (cp);
125132}
@@ -133,11 +140,11 @@ compute3DCentroid (const pcl::PointCloud<PointT> &cloud,
133140 if (indices.empty ())
134141 return (0 );
135142
136- // Initialize to 0
137- centroid.setZero ();
138143 // If the data is dense, we don't need to check for NaN
139144 if (cloud.is_dense )
140145 {
146+ // Initialize to 0
147+ centroid.setZero ();
141148 for (const auto & index : indices)
142149 {
143150 centroid[0 ] += cloud[index].x ;
@@ -149,20 +156,24 @@ compute3DCentroid (const pcl::PointCloud<PointT> &cloud,
149156 return (static_cast <unsigned int > (indices.size ()));
150157 }
151158 // NaN or Inf values could exist => check for them
152- unsigned cp = 0 ;
159+ Eigen::Matrix<Scalar, 4 , 1 > accumulator {0 , 0 , 0 , 0 };
160+ unsigned int cp = 0 ;
153161 for (const auto & index : indices)
154162 {
155163 // Check if the point is invalid
156164 if (!isFinite (cloud [index]))
157165 continue ;
158166
159- centroid [0 ] += cloud[index].x ;
160- centroid [1 ] += cloud[index].y ;
161- centroid [2 ] += cloud[index].z ;
167+ accumulator [0 ] += cloud[index].x ;
168+ accumulator [1 ] += cloud[index].y ;
169+ accumulator [2 ] += cloud[index].z ;
162170 ++cp;
163171 }
164- centroid /= static_cast <Scalar> (cp);
165- centroid[3 ] = 1 ;
172+ if (cp > 0 ) {
173+ centroid = accumulator;
174+ centroid /= static_cast <Scalar> (cp);
175+ centroid[3 ] = 1 ;
176+ }
166177 return (cp);
167178}
168179
@@ -184,13 +195,11 @@ computeCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
184195 if (cloud.empty ())
185196 return (0 );
186197
187- // Initialize to 0
188- covariance_matrix.setZero ();
189-
190198 unsigned point_count;
191199 // If the data is dense, we don't need to check for NaN
192200 if (cloud.is_dense )
193201 {
202+ covariance_matrix.setZero ();
194203 point_count = static_cast <unsigned > (cloud.size ());
195204 // For each point in the cloud
196205 for (const auto & point: cloud)
@@ -214,6 +223,8 @@ computeCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
214223 // NaN or Inf values could exist => check for them
215224 else
216225 {
226+ Eigen::Matrix<Scalar, 3 , 3 > temp_covariance_matrix;
227+ temp_covariance_matrix.setZero ();
217228 point_count = 0 ;
218229 // For each point in the cloud
219230 for (const auto & point: cloud)
@@ -227,17 +238,23 @@ computeCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
227238 pt[1 ] = point.y - centroid[1 ];
228239 pt[2 ] = point.z - centroid[2 ];
229240
230- covariance_matrix (1 , 1 ) += pt.y () * pt.y ();
231- covariance_matrix (1 , 2 ) += pt.y () * pt.z ();
241+ temp_covariance_matrix (1 , 1 ) += pt.y () * pt.y ();
242+ temp_covariance_matrix (1 , 2 ) += pt.y () * pt.z ();
232243
233- covariance_matrix (2 , 2 ) += pt.z () * pt.z ();
244+ temp_covariance_matrix (2 , 2 ) += pt.z () * pt.z ();
234245
235246 pt *= pt.x ();
236- covariance_matrix (0 , 0 ) += pt.x ();
237- covariance_matrix (0 , 1 ) += pt.y ();
238- covariance_matrix (0 , 2 ) += pt.z ();
247+ temp_covariance_matrix (0 , 0 ) += pt.x ();
248+ temp_covariance_matrix (0 , 1 ) += pt.y ();
249+ temp_covariance_matrix (0 , 2 ) += pt.z ();
239250 ++point_count;
240251 }
252+ if (point_count > 0 ) {
253+ covariance_matrix = temp_covariance_matrix;
254+ }
255+ }
256+ if (point_count == 0 ) {
257+ return 0 ;
241258 }
242259 covariance_matrix (1 , 0 ) = covariance_matrix (0 , 1 );
243260 covariance_matrix (2 , 0 ) = covariance_matrix (0 , 2 );
@@ -268,13 +285,11 @@ computeCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
268285 if (indices.empty ())
269286 return (0 );
270287
271- // Initialize to 0
272- covariance_matrix.setZero ();
273-
274288 std::size_t point_count;
275289 // If the data is dense, we don't need to check for NaN
276290 if (cloud.is_dense )
277291 {
292+ covariance_matrix.setZero ();
278293 point_count = indices.size ();
279294 // For each point in the cloud
280295 for (const auto & idx: indices)
@@ -298,6 +313,8 @@ computeCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
298313 // NaN or Inf values could exist => check for them
299314 else
300315 {
316+ Eigen::Matrix<Scalar, 3 , 3 > temp_covariance_matrix;
317+ temp_covariance_matrix.setZero ();
301318 point_count = 0 ;
302319 // For each point in the cloud
303320 for (const auto &index : indices)
@@ -311,17 +328,23 @@ computeCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
311328 pt[1 ] = cloud[index].y - centroid[1 ];
312329 pt[2 ] = cloud[index].z - centroid[2 ];
313330
314- covariance_matrix (1 , 1 ) += pt.y () * pt.y ();
315- covariance_matrix (1 , 2 ) += pt.y () * pt.z ();
331+ temp_covariance_matrix (1 , 1 ) += pt.y () * pt.y ();
332+ temp_covariance_matrix (1 , 2 ) += pt.y () * pt.z ();
316333
317- covariance_matrix (2 , 2 ) += pt.z () * pt.z ();
334+ temp_covariance_matrix (2 , 2 ) += pt.z () * pt.z ();
318335
319336 pt *= pt.x ();
320- covariance_matrix (0 , 0 ) += pt.x ();
321- covariance_matrix (0 , 1 ) += pt.y ();
322- covariance_matrix (0 , 2 ) += pt.z ();
337+ temp_covariance_matrix (0 , 0 ) += pt.x ();
338+ temp_covariance_matrix (0 , 1 ) += pt.y ();
339+ temp_covariance_matrix (0 , 2 ) += pt.z ();
323340 ++point_count;
324341 }
342+ if (point_count > 0 ) {
343+ covariance_matrix = temp_covariance_matrix;
344+ }
345+ }
346+ if (point_count == 0 ) {
347+ return 0 ;
325348 }
326349 covariance_matrix (1 , 0 ) = covariance_matrix (0 , 1 );
327350 covariance_matrix (2 , 0 ) = covariance_matrix (0 , 2 );
0 commit comments