1. 程式人生 > >3維Harris角點提取pcl實現

3維Harris角點提取pcl實現

Harris響應一般是用在二維影象上的,用來尋找影象上的角點,演算法見上一節描述,如何將二維擴充套件到三維呢,博主看的還不是很清楚,但是大致是這樣的,對於空間上的某一個點,進行一個半徑r的搜尋,對於區域內的點進行pca重新確定它的主方向,我個人理解是相當於確定新的x和y方向,這樣就可以類比到平面了,雖然會丟失一個維度,但是沒有關係啊,對於最後一個維度,我們認為是該點擬合的x,y平面的法線方向,這也是十分平凡的,因為三個向量互相垂直。

重點來了,對於我們得到的法線,我們認為它就是強度值,這樣,我們成功將三維點轉換到了二維平面上。那麼很好的是,pcl集成了harris響應,我們下面一起來看看把

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/keypoints/harris_3d.h>
#include <boost/thread/thread.hpp>
#include <stdlib.h>
#include <iostream>

using namespace std;
using namespace std;
int main(int argc, char** argv)
{

	// 建立點雲物件指標
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);

	pcl::io::loadPCDFile<pcl::PointXYZ>("1.pcd", *cloud);
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
	viewer->addPointCloud<pcl::PointXYZ>(cloud, "sample cloud1");
	
	//harris detect

	pcl::HarrisKeypoint3D<pcl::PointXYZ, pcl::PointXYZI, pcl::Normal> harris;
	harris.setInputCloud(cloud);//設定輸入點雲 指標
	harris.setNonMaxSupression(true);
	harris.setRadius(0.6f);// 塊體半徑
	harris.setThreshold(0.01f);//數量閾值
	//新建的點雲必須初始化,清零,否則指標會越界
	//注意Harris的輸出點雲必須是有強度(I)資訊的 pcl::PointXYZI,因為評估值儲存在I分量裡
	pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_out_ptr(new pcl::PointCloud<pcl::PointXYZI>);

	// 計算特徵點
	harris.compute(*cloud_out_ptr);
	// 關鍵點
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_harris_ptr(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointXYZ point;
	//視覺化結果不支援XYZI格式點雲,所有又要導回XYZ格式。。。。
	for (int i = 0; i<size; ++i)
	{
		point.x = cloud_out_ptr->at(i).x;
		point.y = cloud_out_ptr->at(i).y;
		point.z = cloud_out_ptr->at(i).z;
		cloud_harris_ptr->push_back(point);
	}
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> harris_color_handler(cloud_harris_ptr, 0, 255, 0);//第一個引數型別為 指標
	viewer->addPointCloud<pcl::PointXYZ>(cloud_harris_ptr, harris_color_handler, "harris");//第一個引數型別為 指標
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "harris");

	while (!viewer->wasStopped())
	{
		viewer->spinOnce(100);

	}
	system("pause");
	return 0;
}

它的引數設定主要在設定搜尋半徑和閾值上面,不得不承認,不看論文真的很難調這兩個引數,所以建議大家還是以後儘量多看論文比較好。

還有一個需要注意的是

while (!viewer->wasStopped())
    {
        viewer->spinOnce(100);

    }

這個主要是我們視覺化的時候需要它不停的重新整理,這樣才可以顯示,沒有這個視覺化介面會出不來。。。

該大家看下結果把,還是很有意思的