00001 00063 #ifndef __IMPL_EDGE_HANDLER_HPP__ 00064 #define __IMPL_EDGE_HANDLER_HPP__ 00065 00066 #include "cob_3d_segmentation/edge_handler.h" 00067 #include <pcl/common/eigen.h> 00068 00069 template<typename LabelT, typename PointT> void 00070 cob_3d_segmentation::BoundaryPointsEdgeHandler<LabelT,PointT>::erase(EdgePtr e) 00071 { 00072 // TODO: delete boundary points 00073 EdgeHandlerBase<BoundaryPointsEdge>::erase(e); 00074 } 00075 00076 template<typename LabelT, typename PointT> void 00077 cob_3d_segmentation::BoundaryPointsEdgeHandler<LabelT,PointT>::merge(EdgePtr source, EdgePtr target) 00078 { 00079 /* Assume edge_src connects cluster "a" and "b", and edge_trg connects cluster "a" and "c": 00080 * 00081 * +-----------+ 00082 * | a | src_a -> trg_a (combine boundary points on side "a") 00083 * +-----+-----+ 00084 * | b | c | src_b -> trg_c (move boundary point on side "b" to side "c") 00085 * +-----------+ 00086 */ 00087 00088 std::map<int,std::list<int> >::iterator src_pair_1st = source->boundary_pairs.begin(); // pairs of first src cluster 00089 std::map<int,std::list<int> >::iterator src_pair_2nd = ++source->boundary_pairs.begin(); // pairs of second src cluster 00090 std::map<int,std::list<int> >::iterator trg_pair_1st = target->boundary_pairs.begin(); // pairs of first trg cluster 00091 std::map<int,std::list<int> >::iterator trg_pair_2nd = ++target->boundary_pairs.begin(); // pairs of second trg cluster 00092 00093 // bring pointers in correct order ( src_1st will be appended to trg_1st and src_2nd to trg_2nd ) 00094 if (src_pair_1st->first == trg_pair_2nd->first) 00095 { 00096 trg_pair_1st = trg_pair_2nd; 00097 trg_pair_2nd = target->boundary_pairs.begin(); 00098 } 00099 else if (src_pair_2nd->first == trg_pair_1st->first) 00100 { 00101 src_pair_1st = src_pair_2nd; 00102 src_pair_2nd = source->boundary_pairs.begin(); 00103 } 00104 /* this is case shouldn't happen: (maybe throw exception or something) 00105 else if (src_pair_1st->first != trg_pair_1st->first && src_pair_2nd->first != trg_pair_2nd->first) 00106 { 00107 // no mutal clusters 00108 } 00109 */ 00110 trg_pair_1st->second.insert(trg_pair_1st->second.begin(), src_pair_1st->second.begin(), src_pair_1st->second.end()); 00111 trg_pair_2nd->second.insert(trg_pair_2nd->second.begin(), src_pair_2nd->second.begin(), src_pair_2nd->second.end()); 00112 erase(source); 00113 } 00114 00115 template<typename LabelT, typename PointT> void 00116 cob_3d_segmentation::BoundaryPointsEdgeHandler<LabelT,PointT>::move(int old_cid, int new_cid, EdgePtr e) 00117 { 00118 std::map<int,std::list<int> >::iterator it = e->boundary_pairs.find(old_cid); 00119 if (it != e->boundary_pairs.end()) 00120 { 00121 std::swap(e->boundary_pairs[new_cid], it->second); 00122 e->boundary_pairs.erase(it); 00123 } 00124 } 00125 00126 /* is now a general free function in orgnazied_normal_estimation.h 00127 template<typename LabelT, typename PointT> void 00128 cob_3d_segmentation::BoundaryPointsEdgeHandler<LabelT,PointT>::computeBoundaryPointProperties( 00129 const int r, 00130 const int index, 00131 BoundaryPoint& bp) 00132 { 00133 const int w = surface_->width, s = surface_->height * surface_->width; 00134 const int l_idx = labels_->points[index].label; 00135 00136 // compute mask boundary constrains first, 00137 const int w_rem = index%w; 00138 const int x_max = std::min(2*r, r + w - w_rem - 1); // max offset at each line 00139 const int y_min = std::max(index - r*w - r, w_rem - r); 00140 const int y_max = std::min(index + r*w - r, s - (w - w_rem) - r); 00141 Eigen::Matrix<float, 1, 9, Eigen::RowMajor> accu = Eigen::Matrix<float, 1, 9, Eigen::RowMajor>::Zero(); 00142 int point_count = 0; 00143 for (int y = y_min; y <= y_max; y += w) // y: beginning of each line 00144 { 00145 for (int idx = y; idx < y + x_max; ++idx) 00146 { 00147 if (labels_->points[idx].label != l_idx) continue; 00148 PointT const* p_idx = &(surface_->points[idx]); 00149 if (pcl_isnan(p_idx->x)) continue; 00150 accu[0] += p_idx->x * p_idx->x; 00151 accu[1] += p_idx->x * p_idx->y; 00152 accu[2] += p_idx->x * p_idx->z; 00153 accu[3] += p_idx->y * p_idx->y; 00154 accu[4] += p_idx->y * p_idx->z; 00155 accu[5] += p_idx->z * p_idx->z; 00156 accu[6] += p_idx->x; 00157 accu[7] += p_idx->y; 00158 accu[8] += p_idx->z; 00159 ++point_count; 00160 } 00161 } 00162 accu /= static_cast<float>(point_count); 00163 00164 Eigen::Matrix3f cov; 00165 cov.coeffRef(0) = accu(0) - accu(6) * accu(6); 00166 cov.coeffRef(1) = cov.coeffRef(3) = accu(1) - accu(6) * accu(7); 00167 cov.coeffRef(2) = cov.coeffRef(6) = accu(2) - accu(6) * accu(8); 00168 cov.coeffRef(4) = accu(3) - accu(7) * accu(7); 00169 cov.coeffRef(5) = cov.coeffRef(7) = accu(4) - accu(7) * accu(8); 00170 cov.coeffRef(8) = accu(5) - accu(8) * accu(8); 00171 Eigen::Vector3f eigenvalues; 00172 Eigen::Matrix3f eigenvectors; 00173 pcl::eigen33(cov, eigenvectors, eigenvalues); 00174 if ( surface_->points[index].getVector3fMap().dot(eigenvectors.col(0)) > 0) 00175 bp.normal = eigenvectors.col(0) * (-1); 00176 else 00177 bp.normal = eigenvectors.col(0); 00178 } 00179 */ 00180 #endif