inline void pcl::registration::getCorDistMeanStd (const pcl::Correspondences &correspondences, double &mean, double &stddev) { if (correspondences.empty ()) return; double sum = 0, sq_sum = 0; for (size_t i = 0; i < correspondences.size (); ++i) { sum += correspondences[i].distance; sq_sum += correspondences[i].distance * correspondences[i].distance; } mean = sum / static_cast<double> (correspondences.size ()); double variance = (sq_sum - sum * sum / static_cast<double> (correspondences.size ())) / static_cast<double> (correspondences.size () - 1); stddev = sqrt (variance); }
template <typename PointT> bool pcl::visualization::ImageViewer::showCorrespondences ( const pcl::PointCloud<PointT> &source_img, const pcl::PointCloud<PointT> &target_img, const pcl::Correspondences &correspondences, int nth, const std::string &layer_id) { if (correspondences.empty ()) { PCL_DEBUG ("[pcl::visualization::ImageViewer::addCorrespondences] An empty set of correspondences given! Nothing to display.\n"); return (false); } // Check to see if this ID entry already exists (has it been already added to the visualizer?) LayerMap::iterator am_it = std::find_if (layer_map_.begin (), layer_map_.end (), LayerComparator (layer_id)); if (am_it == layer_map_.end ()) { PCL_DEBUG ("[pcl::visualization::ImageViewer::addCorrespondences] No layer with ID='%s' found. Creating new one...\n", layer_id.c_str ()); am_it = createLayer (layer_id, source_img.width + target_img.width, std::max (source_img.height, target_img.height), 1.0, false); } int src_size = source_img.width * source_img.height * 3; int tgt_size = target_img.width * target_img.height * 3; // Set window size setSize (source_img.width + target_img.width , std::max (source_img.height, target_img.height)); // Set data size if (data_size_ < (src_size + tgt_size)) { data_size_ = src_size + tgt_size; data_.reset (new unsigned char[data_size_]); } // Copy data in VTK format int j = 0; for (size_t i = 0; i < std::max (source_img.height, target_img.height); ++i) { // Still need to copy the source? if (i < source_img.height) { for (size_t k = 0; k < source_img.width; ++k) { data_[j++] = source_img[i * source_img.width + k].r; data_[j++] = source_img[i * source_img.width + k].g; data_[j++] = source_img[i * source_img.width + k].b; } } else { memcpy (&data_[j], 0, source_img.width * 3); j += source_img.width * 3; } // Still need to copy the target? if (i < source_img.height) { for (size_t k = 0; k < target_img.width; ++k) { data_[j++] = target_img[i * source_img.width + k].r; data_[j++] = target_img[i * source_img.width + k].g; data_[j++] = target_img[i * source_img.width + k].b; } } else { memcpy (&data_[j], 0, target_img.width * 3); j += target_img.width * 3; } } void* data = const_cast<void*> (reinterpret_cast<const void*> (data_.get ())); vtkSmartPointer<vtkImageData> image = vtkSmartPointer<vtkImageData>::New (); image->SetDimensions (source_img.width + target_img.width, std::max (source_img.height, target_img.height), 1); image->SetScalarTypeToUnsignedChar (); image->SetNumberOfScalarComponents (3); image->AllocateScalars (); image->GetPointData ()->GetScalars ()->SetVoidArray (data, data_size_, 1); vtkSmartPointer<PCLContextImageItem> image_item = vtkSmartPointer<PCLContextImageItem>::New (); #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION < 10)) // Now create filter and set previously created transformation algo_->SetInput (image); algo_->Update (); image_item->set (0, 0, algo_->GetOutput ()); #else image_item->set (0, 0, image); interactor_style_->adjustCamera (image, ren_); #endif am_it->actor->GetScene ()->AddItem (image_item); image_viewer_->SetSize (image->GetDimensions ()[0], image->GetDimensions ()[1]); // Draw lines between the best corresponding points for (size_t i = 0; i < correspondences.size (); i += nth) { double r, g, b; getRandomColors (r, g, b); unsigned char u_r = static_cast<unsigned char> (255.0 * r); unsigned char u_g = static_cast<unsigned char> (255.0 * g); unsigned char u_b = static_cast<unsigned char> (255.0 * b); vtkSmartPointer<context_items::Circle> query_circle = vtkSmartPointer<context_items::Circle>::New (); query_circle->setColors (u_r, u_g, u_b); vtkSmartPointer<context_items::Circle> match_circle = vtkSmartPointer<context_items::Circle>::New (); match_circle->setColors (u_r, u_g, u_b); vtkSmartPointer<context_items::Line> line = vtkSmartPointer<context_items::Line>::New (); line->setColors (u_r, u_g, u_b); float query_x = correspondences[i].index_query % source_img.width; float match_x = correspondences[i].index_match % target_img.width + source_img.width; #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 10)) float query_y = correspondences[i].index_query / source_img.width; float match_y = correspondences[i].index_match / target_img.width; #else float query_y = getSize ()[1] - correspondences[i].index_query / source_img.width; float match_y = getSize ()[1] - correspondences[i].index_match / target_img.width; #endif query_circle->set (query_x, query_y, 3.0); match_circle->set (match_x, match_y, 3.0); line->set (query_x, query_y, match_x, match_y); am_it->actor->GetScene ()->AddItem (query_circle); am_it->actor->GetScene ()->AddItem (match_circle); am_it->actor->GetScene ()->AddItem (line); } return (true); }