54 #define PCL_NO_PRECOMPILE 59 #include <sensor_msgs/PointCloud2.h> 60 #include <sensor_msgs/CameraInfo.h> 61 #include <pcl/point_cloud.h> 63 #include <pcl/common/transforms.h> 64 #include <opencv2/opencv.hpp> 96 if (v < (vmin + 0.25 * dv)) {
98 c.
g = 4 * (v - vmin) / dv;
99 }
else if (v < (vmin + 0.5 * dv)) {
101 c.
b = 1 + 4 * (vmin + 0.25 * dv - v) / dv;
102 }
else if (v < (vmin + 0.75 * dv)) {
103 c.
r = 4 * (v - vmin - 0.5 * dv) / dv;
106 c.
g = 1 + 4 * (vmin + 0.75 * dv - v) / dv;
115 for (std::vector<std::vector<Velodyne::Point*> >::iterator ring = rings.begin(); ring < rings.end(); ++ring){
116 if (ring->empty())
continue;
118 (*ring->begin())->intensity = 0;
119 (*(ring->end() - 1))->intensity = 0;
120 for (vector<Velodyne::Point*>::iterator pt = ring->begin() + 1; pt < ring->end() - 1; ++pt){
123 (*pt)->
intensity =
pow(std::max( std::max( prev->
range-(*pt)->range, succ->
range-(*pt)->range), 0.f), 0.5);
130 if( min < test && test < max )
return true;
134 template <
typename ImageT>
136 void get_diff(
int col,
int row,
int col_c,
int row_c,
int &result, cv::Mat& in) {
139 result = std::max(
abs(in.at<ImageT>(row, col) - in.at<ImageT>(row_c, col_c)), result);
143 template <
typename ImageT>
149 get_diff<ImageT>(col_c -1, row_c -1, col_c, row_c, result, in);
150 get_diff<ImageT>(col_c , row_c -1, col_c, row_c, result, in);
151 get_diff<ImageT>(col_c +1, row_c -1, col_c, row_c, result, in);
152 get_diff<ImageT>(col_c -1, row_c , col_c, row_c, result, in);
153 get_diff<ImageT>(col_c +1, row_c , col_c, row_c, result, in);
154 get_diff<ImageT>(col_c -1, row_c +1, col_c, row_c, result, in);
155 get_diff<ImageT>(col_c , row_c +1, col_c, row_c, result, in);
156 get_diff<ImageT>(col_c +1, row_c +1, col_c, row_c, result, in);
161 template <
typename ImageT>
165 assert(in.rows == out.rows);
166 assert(in.cols == out.cols);
167 assert(in.depth() == out.depth());
168 assert(in.channels() == out.channels());
170 for(
int r = 0; r < in.rows; r++)
172 for(
int c = 0; c < in.cols; c++)
174 out.at<ImageT>(r,c) = max_diff_neighbors<ImageT>(r, c, in);
179 template <
typename Type_in,
typename Type_out>
180 inline float calc(
float &val,
const float &psi,
int row,
int col,
const cv::Mat& in, cv::Mat& out) {
184 if (in.at<Type_in>(row, col) > val)
186 val = in.at<Type_in>(row, col);
189 if (out.at<Type_out>(row, col) < val)
191 out.at<Type_out>(row, col) = val;
194 val = out.at<Type_out>(row, col);
200 template <
typename Type_in,
typename Type_out>
203 for(
int row = 0; row < in.rows; ++row)
207 for(
int col = 0; col < in.cols; ++col)
209 val = calc<Type_in, Type_out>(val, psi, row, col, in, out);
214 template <
typename Type_in,
typename Type_out>
219 for(
int row = 0; row < in.rows; ++row)
222 for(
int col = in.cols -1; col >= 0; --col)
224 val = calc<Type_in, Type_out>(val, psi, row, col, in, out);
229 template <
typename Type_in,
typename Type_out>
234 for(
int col = 0; col < in.cols; ++col)
237 for(
int row = 0; row < in.rows; ++row)
239 val = calc<Type_in, Type_out>(val, psi, row, col, in, out);
244 template <
typename Type_in,
typename Type_out>
249 for(
int col = 0; col < in.cols; ++col)
252 for(
int row = in.rows -1; row >= 0; --row)
254 val = calc<Type_in, Type_out>(val, psi, row, col, in, out);
259 template <
typename Type_in,
typename Type_out>
263 assert(in.channels() == 1);
264 assert(in.depth() == CV_8U);
266 assert(in.size == out.size);
267 assert(in.rows == out.rows);
268 assert(in.cols == out.cols);
270 neighbors_x_pos<Type_in, Type_out>(in, out, psi, alpha);
271 neighbors_x_neg<Type_in, Type_out>(in, out, psi, alpha);
272 neighbors_y_pos<Type_in, Type_out>(in, out, psi, alpha);
273 neighbors_y_neg<Type_in, Type_out>(in, out, psi, alpha);
275 for(
int row = 0; row < in.rows; row++)
277 for(
int col = 0; col < in.cols; col++)
279 int val = alpha * in.at<Type_in>(row,col) + (1 - alpha)*(float)out.at<Type_out>(row,col);
280 out.at<Type_out>(row, col) = val;
293 out_mat (0, 0) = mv[0]; out_mat (0, 1) = mv[4]; out_mat (0, 2) = mv[8];
294 out_mat (1, 0) = mv[1]; out_mat (1, 1) = mv[5]; out_mat (1, 2) = mv[9];
295 out_mat (2, 0) = mv[2]; out_mat (2, 1) = mv[6]; out_mat (2, 2) = mv[10];
297 out_mat (3, 0) = out_mat (3, 1) = out_mat (3, 2) = 0; out_mat (3, 3) = 1;
298 out_mat (0, 3) = origin.
x ();
299 out_mat (1, 3) = origin.
y ();
300 out_mat (2, 3) = origin.
z ();
314 pcl::PointCloud<Velodyne::Point>::Ptr trans_cloud(
new pcl::PointCloud<Velodyne::Point>);
321 ROS_INFO(
"Using available tf transformation");
328 ROS_WARN(
"TF exception:\n%s", ex.what());
331 Eigen::Matrix4f transf_mat;
333 pcl::transformPointCloud(*
edges_cloud, *trans_cloud, transf_mat);
338 cv::cvtColor(
img_out, img_color, cv::COLOR_GRAY2BGR);
340 double objective_function = 0;
344 for (pcl::PointCloud<Velodyne::Point>::iterator pt = trans_cloud->points.begin(); pt < trans_cloud->points.end(); pt++)
346 cv::Point3d pt_cv((*pt).x, (*pt).y, (*pt).z);
352 cv::circle(img_color, uv, 4, cv::Scalar(
int(255*c.
b),
int(255*c.
g),
int(255*c.
r)), -1);
354 if (uv.x>=0 && uv.x <
img_out.cols && uv.y >= 0 && uv.y <
img_out.rows){
355 objective_function +=
img_out.at<uchar>(uv.y, uv.x)*(*pt).intensity;
364 ROS_INFO(
"Objective funcion: %lf", objective_function);
366 cv::imshow(
"Final Levinson", img_color);
384 ROS_WARN(
"TF exception:\n%s", ex.what());
395 ROS_INFO(
"%lf %lf %lf %lf %lf %lf", x, y, z, r, p, yaw);
397 double x_mod, y_mod, z_mod;
398 double r_mod, yaw_mod, p_mod;
402 double INC = 0.001, INC_ANG = 0.001;
405 for (
int iter_x=0; iter_x<MAX; iter_x++){
407 for (
int iter_y=0; iter_y<MAX; iter_y++){
408 for (
int iter_z=0; iter_z<MAX; iter_z++){
409 for (
int iter_r=0; iter_r<MAX; iter_r++){
410 for (
int iter_p=0; iter_p<MAX; iter_p++){
411 for (
int iter_yaw=0; iter_yaw<MAX; iter_yaw++){
412 x_mod = x + (iter_x-M)*INC;
413 y_mod = y + (iter_y-M)*INC;
414 z_mod = z + (iter_z-M)*INC;
415 r_mod = r + (iter_r-M)*INC_ANG;
416 p_mod = p + (iter_p-M)*INC_ANG;
417 yaw_mod = yaw + (iter_yaw-M)*INC_ANG;
421 q.
setRPY(r_mod,p_mod,yaw_mod);
425 Eigen::Matrix4f transf_mat;
427 pcl::transformPointCloud(*
edges_cloud, *trans_cloud, transf_mat);
432 cv::cvtColor(
img_out, img_color, cv::COLOR_GRAY2BGR);
434 double objective_function = 0;
436 for (pcl::PointCloud<Velodyne::Point>::iterator pt = trans_cloud->points.begin(); pt < trans_cloud->points.end(); ++pt)
438 cv::Point3d pt_cv((*pt).x, (*pt).y, (*pt).z);
444 cv::circle(img_color, uv, 4, cv::Scalar(
int(255*c.
b),
int(255*c.
g),
int(255*c.
r)), -1);
446 if (uv.x>=0 && uv.x <
img_out.cols && uv.y >= 0 && uv.y <
img_out.rows){
447 objective_function +=
img_out.at<uchar>(uv.y, uv.x)*(*pt).intensity;
453 savefile << transform.
getOrigin()[0] <<
", " << transform.
getOrigin()[1] <<
", " << transform.
getOrigin()[2] <<
", " << r_mod <<
", " << p_mod <<
", " << yaw_mod <<
", " << objective_function <<
", " << endl;
473 ROS_INFO(
"Velodyne pattern ready!");
475 pcl::PointCloud<Velodyne::Point>::Ptr t_laser_cloud(
new pcl::PointCloud<Velodyne::Point>);
476 pcl::PointCloud<Velodyne::Point>::Ptr
laser_cloud(
new pcl::PointCloud<Velodyne::Point>);
483 edges_cloud = pcl::PointCloud<Velodyne::Point>::Ptr(
new pcl::PointCloud<Velodyne::Point>);
485 float THRESHOLD = 0.30;
486 for (pcl::PointCloud<Velodyne::Point>::iterator pt = laser_cloud->points.begin(); pt < laser_cloud->points.end(); ++pt){
487 if(
pow(pt->intensity,2)>THRESHOLD){
492 sensor_msgs::PointCloud2 cloud_ros;
494 cloud_ros.header = velo_cloud->header;
497 t_laser_cloud.reset();
510 ROS_ERROR(
"cv_bridge exception: %s", e.what());
515 cv::cvtColor(img_in, img_gray, cv::COLOR_RGB2GRAY);
517 cv::Mat img_edge(img_gray.size(), CV_8UC1);;
518 edge_max<uchar>(img_gray, img_edge);
520 img_out = cv::Mat::zeros(img_edge.size(), CV_8UC1);
521 inverse_distance_transformation<uchar,uchar>(img_edge,
img_out);
526 time_t now = time(0);
529 tstruct = *localtime(&now);
532 strftime(buf,
sizeof(buf),
"%Y-%m-%d.%X", &tstruct);
538 int main(
int argc,
char **argv){
556 cloud_pub = nh_.
advertise<sensor_msgs::PointCloud2> (
"levinson_cloud", 1);
561 os << getenv(
"HOME") <<
"/" <<
"levinson_" <<
currentDateTime() <<
".csv" ;
564 ROS_INFO(
"Opening %s", os.str().c_str());
567 savefile <<
"x, y, z, r, p, y, obj" << endl;
572 if (save_to_file_)
savefile.close();
CvImageConstPtr toCvShare(const sensor_msgs::ImageConstPtr &source, const std::string &encoding=std::string())
Subscriber subscribe(const std::string &base_topic, uint32_t queue_size, const boost::function< void(const sensor_msgs::ImageConstPtr &)> &callback, const ros::VoidPtr &tracked_object=ros::VoidPtr(), const TransportHints &transport_hints=TransportHints())
void edges_pointcloud(pcl::PointCloud< Velodyne::Point >::Ptr pc)
void publish(const boost::shared_ptr< M > &message) const
void inverse_distance_transformation(cv::Mat &in, cv::Mat &out, float alpha=0.333333333, float psi=0.98)
vector< vector< Point * > > getRings(pcl::PointCloud< Velodyne::Point > &pc)
float intensity
laser intensity reading
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void neighbors_y_neg(cv::Mat &in, cv::Mat &out, float psi, float alpha)
bool between(T min, T test, T max)
pcl::PointCloud< Velodyne::Point >::Ptr edges_cloud
void get_diff(int col, int row, int col_c, int row_c, int &result, cv::Mat &in)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void fromROSMsg(const sensor_msgs::PointCloud2 &cloud, pcl::PointCloud< T > &pcl_cloud)
TFSIMD_FORCE_INLINE const tfScalar & getY() const
TFSIMD_FORCE_INLINE const tfScalar & y() const
TFSIMD_FORCE_INLINE const tfScalar & getZ() const
int max_diff_neighbors(int row_c, int col_c, cv::Mat &in)
ROSCPP_DECL void spin(Spinner &spinner)
TFSIMD_FORCE_INLINE const tfScalar & x() const
pcl::PointCloud< pcl::PointXYZ >::Ptr laser_cloud
void neighbors_y_pos(cv::Mat &in, cv::Mat &out, float psi, float alpha)
int main(int argc, char **argv)
void stereo_callback(const sensor_msgs::ImageConstPtr &image_msg)
TFSIMD_FORCE_INLINE const tfScalar & z() const
void setRPY(const tfScalar &roll, const tfScalar &pitch, const tfScalar &yaw)
void getRPY(tfScalar &roll, tfScalar &pitch, tfScalar &yaw, unsigned int solution_number=1) const
bool fromCameraInfo(const sensor_msgs::CameraInfo &msg)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
TFSIMD_FORCE_INLINE const tfScalar & y() const
void addRange(pcl::PointCloud< Velodyne::Point > &pc)
TFSIMD_FORCE_INLINE const tfScalar & x() const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
TFSIMD_FORCE_INLINE const tfScalar & z() const
void neighbors_x_neg(cv::Mat &in, cv::Mat &out, float psi, float alpha)
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
INLINE Rall1d< T, V, S > abs(const Rall1d< T, V, S > &x)
void laser_callback(const sensor_msgs::PointCloud2::ConstPtr &velo_cloud)
const std::string currentDateTime()
void toROSMsg(const sensor_msgs::PointCloud2 &cloud, sensor_msgs::Image &image)
TFSIMD_FORCE_INLINE const tfScalar & getX() const
COLOUR GetColour(double v, double vmin, double vmax)
cv::Point2d project3dToPixel(const cv::Point3d &xyz) const
void checkExtrinics(const sensor_msgs::CameraInfoConstPtr &cinfo_msg)
void getOpenGLSubMatrix(tfScalar *m) const
void transformAsMatrix(const tf::Transform &bt, Eigen::Matrix4f &out_mat)
void edge_max(cv::Mat &in, cv::Mat &out)
void neighbors_x_pos(cv::Mat &in, cv::Mat &out, float psi, float alpha)
float calc(float &val, const float &psi, int row, int col, const cv::Mat &in, cv::Mat &out)