Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <ias_descriptors_3d/generic/spin_image_generic.h>
00036
00037 using namespace std;
00038
00039
00040
00041
00042 SpinImageGeneric::SpinImageGeneric()
00043 {
00044 spin_axes_ = NULL;
00045 }
00046
00047
00048
00049
00050 SpinImageGeneric::~SpinImageGeneric()
00051 {
00052 }
00053
00054 void SpinImageGeneric::display(const std::vector<float>& spin_image) const
00055 {
00056 if(spin_image.empty()) {
00057 ROS_WARN("No spin image to display.");
00058 return;
00059 }
00060
00061 assert(spin_image.size() == nbr_rows_ * nbr_cols_);
00062
00063 CvSize sz = cvSize(nbr_cols_, nbr_rows_);
00064 IplImage* img = cvCreateImage(sz, IPL_DEPTH_8U, 1);
00065
00066 for(int y=0; y<img->height; ++y) {
00067 uchar* ptr = (uchar*)img->imageData + y * img->widthStep;
00068 for(int x=0; x<img->width; ++x, ++ptr) {
00069 *ptr = spin_image[x + y * nbr_cols_] * 255;
00070 }
00071 }
00072
00073 float scale = 40;
00074 IplImage* img_big = cvCreateImage(cvSize(((float)img->width)*scale, ((float)img->height)*scale), img->depth, img->nChannels);
00075 cvResize(img, img_big, CV_INTER_AREA);
00076
00077
00078 ostringstream oss;
00079 oss << nbr_rows_ * row_res_ << "x" << nbr_cols_ * col_res_ << " m, " << row_res_ << "x" << col_res_ << "pix/m" << endl;
00080 cvNamedWindow(oss.str().c_str());
00081 cvShowImage(oss.str().c_str(), img_big);
00082 cvWaitKey();
00083 cvDestroyWindow(oss.str().c_str());
00084 cvReleaseImage(&img);
00085 cvReleaseImage(&img_big);
00086 }
00087
00088
00089
00090
00091 void SpinImageGeneric::computeNeighborhoodFeature(const sensor_msgs::PointCloud& data,
00092 const std::vector<int>& neighbor_indices,
00093 const unsigned int interest_sample_idx,
00094 std::vector<float>& result) const
00095 {
00096 const Eigen3::Vector3d* curr_spin_axis = (*spin_axes_)[interest_sample_idx];
00097 if (curr_spin_axis == NULL)
00098 {
00099 ROS_DEBUG("SpinImageGeneric::computeNeighborhoodFeature() no spin axis for sample %u", interest_sample_idx);
00100 return;
00101 }
00102
00103
00104 result.resize(result_size_);
00105 for (size_t i = 0 ; i < result_size_ ; i++)
00106 {
00107 result[i] = 0.0;
00108 }
00109
00110 const Eigen3::Vector3d& center_pt = spin_image_centers_[interest_sample_idx];
00111
00112
00113 const unsigned int row_offset = nbr_rows_ / 2;
00114
00115 float max_bin_count = 1.0;
00116 unsigned int nbr_neighbors = neighbor_indices.size();
00117 for (unsigned int i = 0 ; i < nbr_neighbors ; i++)
00118 {
00119
00120 const geometry_msgs::Point32& curr_neighbor_pt = data.points.at(neighbor_indices[i]);
00121 Eigen3::Vector3d neighbor_vec;
00122 neighbor_vec[0] = curr_neighbor_pt.x - center_pt[0];
00123 neighbor_vec[1] = curr_neighbor_pt.y - center_pt[1];
00124 neighbor_vec[2] = curr_neighbor_pt.z - center_pt[2];
00125 const double neighbor_vec_norm = neighbor_vec.norm();
00126
00127
00128
00129 const double axis_projection = neighbor_vec_norm * neighbor_vec.dot(*curr_spin_axis);
00130
00131 const int signed_row_nbr = static_cast<int> (floor(axis_projection / row_res_));
00132
00133 const int curr_row = signed_row_nbr + row_offset;
00134
00135
00136
00137
00138
00139
00140
00141
00142 const unsigned int curr_col = static_cast<unsigned int> (floor((curr_spin_axis->cross(
00143 neighbor_vec)).norm() / col_res_));
00144
00145
00146
00147 if (curr_row >= 0 && static_cast<unsigned int> (curr_row) < nbr_rows_ && curr_col < nbr_cols_)
00148 {
00149
00150 size_t cell_nbr = static_cast<size_t> (curr_row * nbr_cols_ + curr_col);
00151 result[cell_nbr] += 1.0;
00152
00153
00154 if (result[cell_nbr] > max_bin_count)
00155 {
00156 max_bin_count = result[cell_nbr];
00157 }
00158 }
00159 }
00160
00161
00162 for (size_t i = 0 ; i < result_size_ ; i++)
00163 {
00164 result[i] /= max_bin_count;
00165 }
00166
00167 if(debug_)
00168 display(result);
00169 }