LadybugProcNodelet.cpp
Go to the documentation of this file.
00001 
00002 #include "omnicamera/LadybugProcNodelet.h"
00003 
00004 #include <boost/format.hpp>
00005 #include <pluginlib/class_list_macros.h>
00006 #include <cv_bridge/cv_bridge.h>
00007 #include <opencv2/imgproc/imgproc.hpp>
00008 #include <sensor_msgs/image_encodings.h>
00009 
00010 #define USE_MT_NODE_HANDLE
00011 
00012 namespace omnicamera {
00013 
00014 void LadybugProcNodelet::onInit() {
00015   NODELET_INFO("LadybugImageProcNodelet::onInit");
00016 
00017 #ifdef USE_MT_NODE_HANDLE
00018   ros::NodeHandle nh = getMTNodeHandle();
00019   ros::NodeHandle pnh = getMTPrivateNodeHandle();
00020 #else
00021   ros::NodeHandle nh = getNodeHandle();
00022   ros::NodeHandle pnh = getPrivateNodeHandle();
00023 #endif
00024 
00025   pnh.param("in_width", inWidth, 1616);
00026   pnh.param("in_height", inHeight, 1232);
00027   NODELET_INFO("Input image size: %dx%d.", inWidth, inHeight);
00028 
00029   pnh.param("out_width", outWidth, 960);
00030   pnh.param("out_height", outHeight, 480);
00031   NODELET_INFO("Output image size: %dx%d.", outWidth, outHeight);
00032 
00033   pnh.param("alpha", alpha, true);
00034   NODELET_INFO("Alpha blending: %s.", alpha ? "enabled" : "disabled");
00035 
00036   pnh.param("radius", radius, 20);
00037   NODELET_INFO("Sphere radius: %d.", radius);
00038 
00039   pnh.param("lut_path", lutPath, string("LUT_img_%dx%d_pano_%dx%dr%d_%s%d.pgm"));
00040   NODELET_INFO("LUT path template: %s.", lutPath.data());
00041   // Loading look-up tables postponed to first callback to return fast.
00042   lookupTablesLoaded = false;
00043 
00044   image_transport::ImageTransport it(nh);
00045   string imageTopic = nh.resolveName("image", true);
00046   NODELET_INFO("Subscribing to topic %s...", imageTopic.data());
00047   imageSub = it.subscribe(imageTopic, 1, &LadybugProcNodelet::imageCallback, this);
00048 
00049   outPub = it.advertise("pano", 1);
00050   camPub = nh.advertise<sensor_msgs::CameraInfo>("camera_info", 1);
00051 
00052   boost::format imageOutFmt("image_%i");
00053   boost::format camInfoFmt("camera_info_%i");
00054   for (int i = 0; i < 6; i++) {
00055     string imageOutTopic = nh.resolveName((imageOutFmt % i).str(), true);
00056     string camInfoTopic = nh.resolveName((camInfoFmt % i).str(), true);
00057     NODELET_INFO("Advertising topics %s and %s...", imageOutTopic.data(), camInfoTopic.data());
00058     outPubs[i] = it.advertise(imageOutTopic, 1);
00059     camPubs[i] = nh.advertise<sensor_msgs::CameraInfo>(camInfoTopic, 1);
00060   }
00061 }
00062 
00063 void LadybugProcNodelet::imageCallback(const sensor_msgs::ImageConstPtr& msg) {
00064   NODELET_INFO("LadybugProcNodelet::imageCallback");
00065 
00066   NODELET_INFO("LadybugProcNodelet::imageCallback: Loading look-up tables.");
00067   if (!lookupTablesLoaded) {
00068     NODELET_INFO("Loading look-up tables...");
00069     stitcher.clearLookupTables();
00070     for (int iCam = 1; iCam <= 6; iCam++) {
00071       int len = 1024;
00072       char xPath[len], yPath[len], aPath[len];
00073       snprintf(xPath, len, lutPath.data(), inWidth, inHeight, outWidth, outHeight, radius, "x", iCam);
00074       snprintf(yPath, len, lutPath.data(), inWidth, inHeight, outWidth, outHeight, radius, "y", iCam);
00075       snprintf(aPath, len, lutPath.data(), inWidth, inHeight, outWidth, outHeight, radius, "a", iCam);
00076       NODELET_INFO("Camera %i look-up tables: %s, %s, %s.", iCam, xPath, yPath, aPath);
00077       stitcher.addLookupTables(string(xPath), string(yPath), string(aPath));
00078     }
00079     lookupTablesLoaded = true;
00080   }
00081 
00082   NODELET_INFO("LadybugProcNodelet::imageCallback: Converting message to CvImage.");
00083   cv_bridge::CvImageConstPtr cvPtr;
00084   try {
00085     cvPtr = cv_bridge::toCvShare(msg);
00086   } catch (cv_bridge::Exception& e) {
00087     NODELET_ERROR("cv_bridge exception: %s", e.what());
00088     return;
00089   }
00090 
00091   NODELET_INFO("LadybugProcNodelet::imageCallback: Checking encoding.");
00092   bool stitch = true;
00093   if (cvPtr->encoding.compare(sensor_msgs::image_encodings::BGR8)) {
00094     NODELET_ERROR("Encoding not supported: %s.", cvPtr->encoding.data());
00095     stitch = false;
00096   }
00097 
00098   NODELET_INFO("LadybugProcNodelet::imageCallback: Checking image dimensions.");
00099   if (cvPtr->image.rows != inHeight || cvPtr->image.cols != inWidth) {
00100     NODELET_ERROR("Unexpected image dimensions: %dx%d.", cvPtr->image.cols, cvPtr->image.rows);
00101     stitch = false;
00102   }
00103 
00104   if (stitch && false) {
00105     NODELET_INFO("Stitching started.");
00106     stitcher.stitchImage(cvPtr->image, pano);
00107     NODELET_INFO("Stitching finished.");
00108 
00109     NODELET_INFO("LadybugProcNodelet::imageCallback: Preparing and sending pano message.");
00110     cv_bridge::CvImage out;
00111     out.encoding = sensor_msgs::image_encodings::BGR8;
00112     out.header = msg->header;
00113     out.image = pano;
00114     outPub.publish(out.toImageMsg());
00115 
00116     NODELET_INFO("Sending camera info.");
00117     sensor_msgs::CameraInfo camMsg;
00118     camMsg.header = out.header;
00119     camMsg.height = out.image.rows;
00120     camMsg.width = out.image.cols;
00121     camPub.publish(camMsg);
00122   }
00123 
00124   NODELET_INFO("Sawing started.");
00125   ladySaw.saw(cvPtr->image, cams);
00126   NODELET_INFO("Sawing finished.");
00127 
00128   vector<int> camsOut = ladySaw.getCamsOut();
00129   for (int i = 0; i < (int) camsOut.size(); i++) {
00130     NODELET_INFO("LadybugProcNodelet::imageCallback: Publishing image %i.", i);
00131     int iCam = camsOut[i];
00132 
00133     cv_bridge::CvImage out;
00134     out.encoding = cvPtr->encoding;
00135     out.header = msg->header;
00136     out.image = cams[i];
00137     NODELET_INFO("LadybugProcNodelet::imageCallback: before publishing image %i.", i);
00138     outPubs[iCam].publish(out.toImageMsg());
00139     NODELET_INFO("LadybugProcNodelet::imageCallback: after publishing image %i.", i);
00140 
00141     sensor_msgs::CameraInfo camMsg;
00142     camMsg.header = out.header;
00143     camMsg.height = out.image.rows;
00144     camMsg.width = out.image.cols;
00145     camPubs[iCam].publish(camMsg);
00146   }
00147 }
00148 
00149 } // namespace omnicamera
00150 
00151 PLUGINLIB_DECLARE_CLASS(omnicamera, ladybug_proc, omnicamera::LadybugProcNodelet, nodelet::Nodelet)
 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