PCL裁剪之多邊形裁剪

     PCL自帶的裁剪方法,本人就不做介紹了,具體詳見本人之間的博客https://www.cnblogs.com/z-web-2017/p/10187556.html,此處主要是對以前裁剪方法存在的不足進行完善,加入視點方向進行投影。保證相機轉動時,投影方向隨之轉動:html

具體代碼以下:web

 

    pcl::visualization::Camera camera1;
    viewer->getCameraParameters(camera1);
    PointXYZ eyeLine1 = PointXYZ(camera1.focal[0] - camera1.pos[0],
        camera1.focal[1] - camera1.pos[1], camera1.focal[2] - camera1.pos[2]);
    float mochang = sqrt(pow(eyeLine1.x, 2) + pow(eyeLine1.y, 2) + pow(eyeLine1.z, 2));
    PointXYZ eyeLine = PointXYZ(eyeLine1.x / mochang, eyeLine1.y / mochang, eyeLine1.z / mochang);

    PointCloud<PointXYZRGB>::Ptr cloudIn_Prj(new PointCloud<PointXYZRGB>);
    PointCloud<PointXYZRGB>::Ptr cloudCiecle_result(new PointCloud<PointXYZRGB>);
    ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());//ax+by+cz+d=0
    coefficients->values.resize(4);
    coefficients->values[0] = eyeLine.x;
    coefficients->values[1] = eyeLine.y;
    coefficients->values[2] = eyeLine.z;
    coefficients->values[3] = 0;
    // 建立濾波器對象
    ProjectInliers<PointXYZRGB> proj;//創建投影對象
    proj.setModelType(pcl::SACMODEL_PLANE);//設置投影類型
    proj.setInputCloud(cloudPoly);//設置輸入點雲
    proj.setModelCoefficients(coefficients);//加載投影參數
    proj.filter(*cloudCiecle_result);//執行程序,並將結果保存

    // 建立濾波器對象
    ProjectInliers<PointXYZRGB> projCloudIn;//創建投影對象
    projCloudIn.setModelType(pcl::SACMODEL_PLANE);//設置投影類型
    projCloudIn.setInputCloud(cloudIn);//設置輸入點雲
    projCloudIn.setModelCoefficients(coefficients);//加載投影參數
    projCloudIn.filter(*cloudIn_Prj);//執行程序,並將結果保存
    
    int ret;
    double *PloyXarr = new double[cloudCiecle_result->points.size()];
    double *PloyYarr = new double[cloudCiecle_result->points.size()];
    for (int i = 0; i < cloudCiecle_result->points.size(); i++)
    {
        PloyXarr[i] = cloudCiecle_result->points[i].x;
        PloyYarr[i] = cloudCiecle_result->points[i].y;
    }


    for (int i = 0; i < cloudIn_Prj->points.size(); i++)
    {
        ret = inOrNot1(cloudPoly->points.size(), PloyXarr, PloyYarr, cloudIn_Prj->points[i].x, cloudIn_Prj->points[i].y);
        if (1 == ret)//表示在裏面
        {
            cloudRe->points.push_back(cloudIn->points[i]);
        }//表示在外面
    }

int inOrNot1(int poly_sides, double *poly_X, double *poly_Y, double x, double y){ int i, j; j = poly_sides - 1; int res = 0; for (i = 0; i < poly_sides; i++) {  //對每一條邊進行遍歷,該邊的兩個端點,有一個必須在待檢測點(x,y)的左邊,且兩個點中,有一個點的y左邊比p.y小,另外一個點的y比p.y大。  if ((poly_Y[i] < y && poly_Y[j] >= y || poly_Y[j] < y && poly_Y[i] >= y) && (poly_X[i] <= x || poly_X[j] <= x))  {   //用水平的直線與該邊相交,求交點的x座標。   res ^= ((poly_X[i] + (y - poly_Y[i]) / (poly_Y[j] - poly_Y[i])  *(poly_X[j] - poly_X[i])) < x);  }  j = i; } return res;}