aras_visual_servo_camera.cpp
Go to the documentation of this file.
00001 #include "aras_visual_servo_camera/aras_visual_servo_camera.h"
00002 VisualServoCamera::VisualServoCamera()
00003 {
00004     image_transport::ImageTransport it(nh_);
00005     image_sub_ = it.subscribe("/labrob/camera/image_raw", 1, &VisualServoCamera::imageCB,this);
00006     threshold_image_pub_ = it.advertise("/aras_visual_servo/camera/thresholded_image", 1);
00007     camera_data_pub_ = nh_.advertise<std_msgs::Float64MultiArray>("/aras_visual_servo/camera/data",1);
00008     cv::namedWindow( "Orginal Image", CV_WINDOW_AUTOSIZE);
00009     cv::namedWindow( "Thresholded Image", CV_WINDOW_AUTOSIZE );
00010     cv::moveWindow("Orginal Image",0,0);
00011     cv::moveWindow("Thresholded Image",0,320);
00012 }
00013 
00014 void VisualServoCamera::imageCB(const sensor_msgs::ImageConstPtr &image_msg)
00015 {
00016     try
00017     {
00018         color_image_ = cv_bridge::toCvShare(image_msg, "bgr8")->image;
00019         cv::cvtColor(color_image_, grey_image_, CV_BGR2GRAY);
00020         cv::threshold( grey_image_, threshold_image_, THRESHOLD_VALUE, MAX_BINARY_VALUE ,cv::THRESH_BINARY_INV );
00021 
00022         cv::Mat jacobian_mat(KERNEL_SIZE,DOF,cv::DataType<double>::type);
00023         cv::Mat jacobian_inverse_mat(KERNEL_SIZE,DOF,cv::DataType<double>::type);
00024         float kernel[4];
00025         calculateKernel(&threshold_image_,kernel,jacobian_mat,jacobian_inverse_mat);
00026         publishCameraData(kernel,jacobian_inverse_mat);
00027 
00028         cv::imshow("Orginal Image",color_image_);
00029         cv::imshow("Thresholded Image",threshold_image_);
00030         cv::waitKey(1);
00031     }
00032     catch (cv_bridge::Exception& e)
00033     {
00034         ROS_ERROR("Could not convert from '%s' to 'bgr8'.", image_msg->encoding.c_str());
00035     }
00036 
00037 }
00038 
00039 bool VisualServoCamera::calculateKernel(const cv::Mat *image, float kernel[KERNEL_SIZE], cv::Mat &jacobian_mat , cv::Mat &jacobian_inverse_mat)
00040 {
00041     //we should add mutex-lock
00042     if(jacobian_mat.rows !=KERNEL_SIZE && jacobian_mat.cols!=DOF)
00043     {
00044         ROS_ERROR("the jacobian matrix size is not %d x %d",KERNEL_SIZE,DOF);
00045         return false;
00046     }
00047     //just in case
00048     for(int i=0;i<KERNEL_SIZE;i++)
00049     {
00050         for(int j=0;j<DOF;j++)
00051         {
00052             jacobian_mat.at<double>(i,j)=0;
00053         }
00054     }
00055 
00056     jacobian_mat.at<double>(3,3)=-1;
00057 
00058     int img_height = image->rows;
00059     int img_width = image->cols;
00060     double jxx,jxtheta,jyy,jytheta;
00061 
00062     for(int i=0;i<KERNEL_SIZE;i++)
00063     {
00064         kernel[i] = 0;
00065     }
00066 
00067     double kx = 0;
00068     double ky = 0;
00069 
00070     for(int i=0;i<img_height;i++ )
00071     {
00072         kx = pow(((i+1)*DELTA_X),KERNEL_P);//k_x(x,y) = x^(-2);
00073         jxx =  KERNEL_P * pow(((i+1)*DELTA_X),(KERNEL_P-1));//dk_x(x,y)/dx = -2 * x^(-3)
00074         for(int j=0;j<img_width;j++)
00075         {
00076             double pixel_value = (double)image->at<uchar>(i,j)/MAX_BINARY_VALUE;
00077 
00078             ky = pow(((j+1)*DELTA_Y),KERNEL_Q);
00079 
00080             jyy = KERNEL_Q * pow(((j+1)*DELTA_Y),(KERNEL_Q-1));
00081             jxtheta = jxx*(j + 1)*DELTA_Y;
00082             jytheta = jyy*(i + 1)*DELTA_X;
00083             kernel[0] = kernel[0] + kx * pixel_value*DELTA_Y*DELTA_X;
00084             kernel[1] = kernel[1] + ky * pixel_value*DELTA_Y*DELTA_X;
00085             kernel[2] = kernel[2] + pixel_value*DELTA_Y*DELTA_X;
00086 
00087             jacobian_mat.at<double>(0,0) = jacobian_mat.at<double>(0,0) - jxx * pixel_value; //jacobianxx
00088             jacobian_mat.at<double>(0,3) = jacobian_mat.at<double>(0,3) + jxtheta * pixel_value;//jacobianxtheta
00089             jacobian_mat.at<double>(1,1) = jacobian_mat.at<double>(1,1) - jyy * pixel_value;//jacobianyy
00090             jacobian_mat.at<double>(1,3) = jacobian_mat.at<double>(1,3) - jytheta * pixel_value;//jacobianytheta
00091             jacobian_mat.at<double>(2,2) = jacobian_mat.at<double>(2,2) + 2 * pixel_value;//jacobianz
00092 
00093         }
00094     }
00095 
00096     cv::Moments image_moments = cv::moments(*image);
00097     kernel[3] = 0.5 * atan2( (2*image_moments.mu11/255.0) , (image_moments.mu20/255.0-image_moments.mu02/255.0) );
00098     cv::invert(jacobian_mat,jacobian_inverse_mat);
00099 }
00100 
00101 void VisualServoCamera::publishCameraData(const float kernel[KERNEL_SIZE] ,const cv::Mat jacobian_inverse_mat)
00102 {
00103     std_msgs::Float64MultiArray camera_data_msg;
00104     for(int i=0;i<jacobian_inverse_mat.rows;i++)
00105     {
00106         for(int j=0;j<jacobian_inverse_mat.cols;j++)
00107         {
00108             camera_data_msg.data.push_back(jacobian_inverse_mat.at<double>(i,j));
00109         }
00110     }
00111     for(int i=0;i<KERNEL_SIZE;i++)
00112     {
00113         camera_data_msg.data.push_back(kernel[i]);
00114     }
00115     camera_data_pub_.publish(camera_data_msg);
00116 }
00117 
00118 VisualServoCamera::~VisualServoCamera()
00119 {
00120 
00121 }


aras_visual_servo_camera
Author(s): Babak Sistani Zadeh , Javad Ramezan Zadeh , Parisa Masnadi , Ebrahim Abedloo , Prof. Hamid D. Taghirad
autogenerated on Thu Jun 6 2019 21:48:43