|
@@ -1,41 +1,39 @@
|
|
|
//
|
|
|
// Created by zx on 2019/12/6.
|
|
|
//
|
|
|
-#include "region_detect.h"
|
|
|
+#include "include/region_detect.h"
|
|
|
|
|
|
Region_detector::Region_detector(int id, EleFence::Region region):m_region_id(-1)
|
|
|
{
|
|
|
m_region_param.CopyFrom(region);
|
|
|
m_region_id = id;
|
|
|
- for (int i = 0; i < 4; ++i) {
|
|
|
- m_cloud_segs.push_back(pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>));
|
|
|
- }
|
|
|
- cut_cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
|
|
|
}
|
|
|
|
|
|
Region_detector::~Region_detector()
|
|
|
{
|
|
|
-
|
|
|
}
|
|
|
|
|
|
-bool Region_detector::preprocess(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_out){
|
|
|
- if(!m_region_param.has_maxx() || !m_region_param.has_maxy() || !m_region_param.has_minx() || !m_region_param.has_miny())
|
|
|
+bool Region_detector::preprocess(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_out)
|
|
|
+{
|
|
|
+ if (!m_region_param.has_maxx() || !m_region_param.has_maxy() || !m_region_param.has_minx() || !m_region_param.has_miny())
|
|
|
+ return false;
|
|
|
+ if (cloud_in->size() <= 0)
|
|
|
return false;
|
|
|
-// if(cloud_in->size() <= 0)
|
|
|
-// return false;
|
|
|
cloud_out->clear();
|
|
|
pcl::copyPointCloud(*cloud_in, *cloud_out);
|
|
|
- if(cloud_out->size() <= 0)
|
|
|
+ if (cloud_out->size() <= 0)
|
|
|
return false;
|
|
|
// 直通滤波, 筛选xy
|
|
|
// pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
|
|
|
pcl::PassThrough<pcl::PointXYZ> pass;
|
|
|
pass.setInputCloud(cloud_out);
|
|
|
- pass.setFilterFieldName("x");//设置想在哪个坐标轴上操作
|
|
|
- pass.setFilterLimits(m_region_param.minx(), m_region_param.maxx());//将x轴的0到1范围内
|
|
|
- pass.setFilterLimitsNegative(false);//保留(true就是删除,false就是保留而删除此区间外的)
|
|
|
+ pass.setFilterFieldName("x"); //设置想在哪个坐标轴上操作
|
|
|
+ pass.setFilterLimits(m_region_param.minx(), m_region_param.maxx()); //将x轴的0到1范围内
|
|
|
+ pass.setFilterLimitsNegative(false); //保留(true就是删除,false就是保留而删除此区间外的)
|
|
|
pass.filter(*cloud_out);//输出到结果指针
|
|
|
|
|
|
+ if (cloud_out->size() <= 0)
|
|
|
+ return false;
|
|
|
pass.setInputCloud(cloud_out);
|
|
|
pass.setFilterFieldName("y");//设置想在哪个坐标轴上操作
|
|
|
pass.setFilterLimits(m_region_param.miny(), m_region_param.maxy());//将x轴的0到1范围内
|
|
@@ -58,14 +56,6 @@ bool Region_detector::preprocess(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in, p
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-bool Region_detector::findWheelbase()
|
|
|
-{
|
|
|
- if (cut_cloud->size() <= 0)
|
|
|
- return false;
|
|
|
-
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
double distance(cv::Point2f p1, cv::Point2f p2)
|
|
|
{
|
|
|
return sqrt(pow(p1.x - p2.x, 2.0) + pow(p1.y - p2.y, 2.0));
|
|
@@ -177,7 +167,7 @@ bool Region_detector::isRect(std::vector<cv::Point2f>& points)
|
|
|
|
|
|
}
|
|
|
|
|
|
-bool Region_detector::clustering(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in) {
|
|
|
+bool Region_detector::clustering(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in, std::vector<cv::Point2f>& corner_points) {
|
|
|
if (cloud_in->size() == 0) return false;
|
|
|
/////聚类
|
|
|
pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree(new pcl::search::KdTree<pcl::PointXYZ>);
|
|
@@ -215,7 +205,8 @@ bool Region_detector::clustering(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in) {
|
|
|
|
|
|
std::cout << " cluster class:" << clusters.size() << std::endl;
|
|
|
|
|
|
- std::vector<cv::Point2f> cvPoints;
|
|
|
+ // std::vector<cv::Point2f> cvPoints;
|
|
|
+ corner_points.clear();
|
|
|
for(int i=0;i<clusters.size();++i)
|
|
|
{
|
|
|
if(seg_clouds[i]->size()==0)
|
|
@@ -229,48 +220,43 @@ bool Region_detector::clustering(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in) {
|
|
|
|
|
|
float center_x=sumX/float(seg_clouds[i]->size());
|
|
|
float center_y=sumY/float(seg_clouds[i]->size());
|
|
|
- cvPoints.push_back(cv::Point2f(center_x,center_y));
|
|
|
+ corner_points.push_back(cv::Point2f(center_x,center_y));
|
|
|
}
|
|
|
- return isRect(cvPoints);
|
|
|
-
|
|
|
+ return isRect(corner_points);
|
|
|
}
|
|
|
|
|
|
bool Region_detector::detect(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in)
|
|
|
{
|
|
|
return false;
|
|
|
bool result = false;
|
|
|
- preprocess(cloud_in, cut_cloud);
|
|
|
+ pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
|
|
|
+ preprocess(cloud_in, cloud_filtered);
|
|
|
|
|
|
- if (cut_cloud->size() <= 0)
|
|
|
+ if (cloud_filtered->size() <= 0)
|
|
|
return false;
|
|
|
- m_seg_mutex.lock();
|
|
|
- result = clustering(cut_cloud);
|
|
|
- m_seg_mutex.unlock();
|
|
|
+ std::vector<cv::Point2f> corner_points;
|
|
|
+ result = clustering(cloud_filtered, corner_points);
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
bool Region_detector::detect(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in, double &x, double &y, double &c, double &wheelbase, double &width)
|
|
|
{
|
|
|
bool result = false;
|
|
|
- pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filterd(pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>));
|
|
|
- preprocess(cloud_in, cloud_filterd);
|
|
|
+ pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>));
|
|
|
+ preprocess(cloud_in, cloud_filtered);
|
|
|
// std::cout<<"--------detector after preprocess------"<<std::endl;
|
|
|
|
|
|
- if (cloud_filterd->size() <= 0)
|
|
|
+ if (cloud_filtered->size() <= 0)
|
|
|
return false;
|
|
|
-
|
|
|
- m_seg_mutex.lock();
|
|
|
- result = clustering(cloud_filterd);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+ std::vector<cv::Point2f> corner_points;
|
|
|
+ result = clustering(cloud_filtered, corner_points);
|
|
|
if(result)
|
|
|
{
|
|
|
// convert all points after preprocessing into 2d
|
|
|
std::vector<cv::Point2f> all_points;
|
|
|
// car center
|
|
|
- for (int j = 0; j < cloud_filterd->size(); ++j) {
|
|
|
- all_points.push_back(cv::Point2f(cloud_filterd->points[j].x, cloud_filterd->points[j].y));
|
|
|
+ for (int j = 0; j < cloud_filtered->size(); ++j) {
|
|
|
+ all_points.push_back(cv::Point2f(cloud_filtered->points[j].x, cloud_filtered->points[j].y));
|
|
|
}
|
|
|
std::cout<<"--------detector find center------"<<std::endl;
|
|
|
cv::RotatedRect wheel_box = cv::minAreaRect(all_points);
|
|
@@ -294,11 +280,19 @@ bool Region_detector::detect(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in, doubl
|
|
|
}
|
|
|
float angle_x = 180.0 / M_PI * acos(vec.x / sqrt(vec.x * vec.x + vec.y * vec.y));
|
|
|
c = angle_x;
|
|
|
+ // calculate wheelbase according to corner points
|
|
|
+ double dist0=0, dist1=0, dist2=0;
|
|
|
wheelbase = std::max(wheel_box.size.width, wheel_box.size.height);
|
|
|
+ cv::RotatedRect wheel_center_box = cv::minAreaRect(corner_points);
|
|
|
+ cv::Point2f center_vertice[4];
|
|
|
+ wheel_box.points(center_vertice);
|
|
|
+ len1 = pow(center_vertice[0].x - center_vertice[1].x, 2.0) + pow(center_vertice[0].y - center_vertice[1].y, 2.0);
|
|
|
+ len2 = pow(center_vertice[1].x - center_vertice[2].x, 2.0) + pow(center_vertice[1].y - center_vertice[2].y, 2.0);
|
|
|
+ if(len1 > 0 && len2 > 0){
|
|
|
+ wheelbase = std::max(len1, len2);
|
|
|
+ }
|
|
|
width = std::min(wheel_box.size.width, wheel_box.size.height);
|
|
|
std::cout<<"--------detector find all------"<<std::endl;
|
|
|
}
|
|
|
-
|
|
|
- m_seg_mutex.unlock();
|
|
|
return result;
|
|
|
}
|