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
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
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);
00073 jxx = KERNEL_P * pow(((i+1)*DELTA_X),(KERNEL_P-1));
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;
00088 jacobian_mat.at<double>(0,3) = jacobian_mat.at<double>(0,3) + jxtheta * pixel_value;
00089 jacobian_mat.at<double>(1,1) = jacobian_mat.at<double>(1,1) - jyy * pixel_value;
00090 jacobian_mat.at<double>(1,3) = jacobian_mat.at<double>(1,3) - jytheta * pixel_value;
00091 jacobian_mat.at<double>(2,2) = jacobian_mat.at<double>(2,2) + 2 * pixel_value;
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 }