panolut_virtual_camera_node.cpp
Go to the documentation of this file.
00001 
00002 #include <ros/ros.h>
00003 #include <cv_bridge/cv_bridge.h>
00004 #include <image_transport/image_transport.h>
00005 #include <opencv2/imgproc/imgproc.hpp>
00006 #include <sensor_msgs/image_encodings.h>
00007 
00008 #include "omnicamera_msgs/GetVirtualCameraConfig.h"
00009 #include "omnicamera/panolut_virtual_camera_common.h"
00010 
00011 //#define USE_MT_NODE_HANDLE
00012 
00013 using cv::Mat_;
00014 using omnicamera_msgs::GetVirtualCameraConfig;
00015 
00016 using omnicamera::rotationMatrix;
00017 using omnicamera::panTiltToCart;
00018 using omnicamera::cartToPanTilt;
00019 using omnicamera::cameraInverse;
00020 using omnicamera::updateVcamStitcher;
00021 
00022 namespace {
00023 const int N_CAMS = 6;
00024 int inWidth, inHeight;
00025 int panoWidth, panoHeight;
00026 bool alpha;
00027 int radius;
00028 string lutPath;
00029 
00030 omnicamera::LookupStitcher pano;
00031 omnicamera::LookupStitcher vcam;
00032 image_transport::Publisher outPub;
00033 ros::Publisher camPub;
00034 
00038 VirtualCameraConfig vcamConfig;
00039 
00040 bool getVirtualCameraConfigService(GetVirtualCameraConfig::Request& request, GetVirtualCameraConfig::Response& response) {
00041   response.config = vcamConfig;
00042   return true;
00043 }
00044 
00045 void virtualCameraConfigCallback(const VirtualCameraConfig::ConstPtr& msg) {
00046   updateVcamStitcher(pano, panoWidth, panoHeight, *msg, vcam);
00047 }
00048 
00049 void imageCallback(const sensor_msgs::ImageConstPtr& msg) {
00050   ROS_INFO("imageCallback: Entering...");
00051 
00052   cv_bridge::CvImageConstPtr cvPtr;
00053   try {
00054     cvPtr = cv_bridge::toCvShare(msg);
00055     if (cvPtr->encoding.compare(sensor_msgs::image_encodings::BGR8)) {
00056       ROS_ERROR("Encoding not supported: %s.", cvPtr->encoding.data());
00057       return;
00058     }
00059   } catch (cv_bridge::Exception& e) {
00060     ROS_ERROR("cv_bridge exception: %s", e.what());
00061     return;
00062   }
00063 
00064   if (cvPtr->image.rows != inHeight || cvPtr->image.cols != inWidth) {
00065     ROS_ERROR("Unexpected image dimensions: %dx%d.", cvPtr->image.cols, cvPtr->image.rows);
00066   }
00067 
00068   Mat image;
00069   vcam.stitchImage(cvPtr->image, image);
00070 
00071   cv_bridge::CvImage out;
00072   out.encoding = sensor_msgs::image_encodings::BGR8;
00073   out.header = msg->header;
00074   out.image = image;
00075   outPub.publish(out.toImageMsg());
00076 
00077   sensor_msgs::CameraInfo camMsg;
00078   camMsg.header = out.header;
00079   camMsg.height = out.image.rows;
00080   camMsg.width = out.image.cols;
00081   camPub.publish(camMsg);
00082 
00083   ROS_INFO("imageCallback: Returning...");
00084 }
00085 
00086 } // namespace
00087 
00088 int main(int argc, char ** argv) {
00089 
00090   ros::init(argc, argv, "img2pano");
00091   ros::NodeHandle nh;
00092 
00093   // Construct a node handle with private namespace to get private parameters...
00094   ros::NodeHandle pnh("~");
00095   pnh.param("in_width", inWidth, 1616);
00096   pnh.param("in_height", inHeight, 1232);
00097   ROS_INFO("Input image size: %dx%d.", inWidth, inHeight);
00098 
00099   pnh.param("pano_width", panoWidth, 960);
00100   pnh.param("pano_height", panoHeight, 480);
00101   ROS_INFO("Panorama size: %dx%d.", panoWidth, panoHeight);
00102 
00103   pnh.param("alpha", alpha, true);
00104   ROS_INFO("Alpha blending: %s.", alpha ? "enabled" : "disabled");
00105 
00106   pnh.param("radius", radius, 20);
00107   ROS_INFO("Sphere radius: %d.", radius);
00108 
00109   pnh.param("lut_path", lutPath, string("LUT_img_%dx%d_pano_%dx%dr%d_%s%d.png"));
00110   ROS_INFO("LUT path template: %s.", lutPath.data());
00111 
00112   pano.clearLookupTables();
00113   vcam.clearLookupTables();
00114   for (int iCam = 1; iCam <= N_CAMS; iCam++) {
00115     int len = 1024;
00116     char xPath[len], yPath[len], aPath[len];
00117     snprintf(xPath, len, lutPath.data(), inWidth, inHeight, panoWidth, panoHeight, radius, "x", iCam);
00118     snprintf(yPath, len, lutPath.data(), inWidth, inHeight, panoWidth, panoHeight, radius, "y", iCam);
00119     snprintf(aPath, len, lutPath.data(), inWidth, inHeight, panoWidth, panoHeight, radius, "a", iCam);
00120     ROS_INFO("Camera %d look-up tables: %s, %s, %s.", iCam, xPath, yPath, aPath);
00121     pano.addLookupTables(string(xPath), string(yPath), string(aPath));
00122     vcam.addLookupTables(Mat(0, 0, CV_16UC1), Mat(0, 0, CV_16UC1), Mat(0, 0, CV_8UC1));
00123   }
00124 
00125   image_transport::ImageTransport it(nh);
00126   image_transport::Subscriber sub = it.subscribe("in", 1, imageCallback);
00127   outPub = it.advertise("out", 1);
00128   camPub = nh.advertise<sensor_msgs::CameraInfo>("camera_info", 1);
00129 
00130   ros::Subscriber virtualCameraConfigSubscriber = nh.subscribe("config", 1, virtualCameraConfigCallback);
00131   ros::ServiceServer getVirtualCameraConfigServer = nh.advertiseService("get_config", getVirtualCameraConfigService);
00132 
00133   vcamConfig.viewportWidth = 640;
00134   vcamConfig.viewportHeight = 480;
00135   vcamConfig.pan = 0.0;
00136   vcamConfig.tilt = 0.0;
00137   vcamConfig.horizontalFov = 90.0;
00138   vcamConfig.verticalFov = 90.0 * 3 / 4;
00139 //  setVirtualCameraConfig(vcamConfig);
00140   updateVcamStitcher(pano, panoWidth, panoHeight, vcamConfig, vcam);
00141 
00142   ros::spin();
00143 
00144   return 0;
00145 }
 All Classes Namespaces Files Functions Variables Typedefs Defines


omnicamera
Author(s): Tomas Petricek / petrito1@cmp.felk.cvut.cz
autogenerated on Tue Dec 10 2013 14:26:53