optris_colorconvert_node.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2012-2015
00005  *  Technische Hochschule Nürnberg Georg Simon Ohm
00006  *  All rights reserved.
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *
00012  *   * Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *   * Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions and the following
00016  *     disclaimer in the documentation and/or other materials provided
00017  *     with the distribution.
00018  *   * Neither the name of Nuremberg Institute of Technology
00019  *     Georg Simon Ohm nor the authors names may be used to endorse
00020  *     or promote products derived from this software without specific
00021  *     prior written permission.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00027  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00029  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034  *  POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  * Author: Stefan May
00037  *********************************************************************/
00038 
00039 #include "ros/ros.h"
00040 #include <image_transport/image_transport.h>
00041 
00042 #include "libirimager/ImageBuilder.h"
00043 
00044 #include <camera_info_manager/camera_info_manager.h>
00045 #include <sensor_msgs/CameraInfo.h>
00046 
00047 unsigned char*                    _bufferThermal = NULL;
00048 unsigned char*                    _bufferVisible = NULL;
00049 image_transport::Publisher*       _pubThermal;
00050 image_transport::Publisher*       _pubVisible;
00051 unsigned int                      _frame = 0;
00052 
00053 optris::ImageBuilder              _iBuilder;
00054 optris::EnumOptrisColoringPalette _palette;
00055 
00056 sensor_msgs::CameraInfo _camera_info;
00057 image_transport::CameraPublisher* _camera_info_pub = NULL;
00058 camera_info_manager::CameraInfoManager* _camera_info_manager = NULL;
00059 
00060 void onThermalDataReceive(const sensor_msgs::ImageConstPtr& image)
00061 {
00062    // check for any subscribers to save computation time
00063   if((_pubThermal->getNumSubscribers() == 0) && (_camera_info_pub->getNumSubscribers() == 0))
00064      return;
00065 
00066   unsigned short* data = (unsigned short*)&image->data[0];
00067   _iBuilder.setData(image->width, image->height, data);
00068 
00069   if(_bufferThermal==NULL)
00070     _bufferThermal = new unsigned char[image->width * image->height * 3];
00071 
00072   _iBuilder.convertTemperatureToPaletteImage(_bufferThermal, true);
00073 
00074   sensor_msgs::Image img;
00075   img.header.frame_id = "thermal_image_view";
00076   img.height            = image->height;
00077   img.width             = image->width;
00078   img.encoding        = "rgb8";
00079   img.step            = image->width*3;
00080   img.header.seq      = ++_frame;
00081   img.header.stamp    = ros::Time::now();
00082 
00083   // copy the image buffer
00084   img.data.resize(img.height*img.step);
00085   memcpy(&img.data[0], &_bufferThermal[0], img.height * img.step * sizeof(*_bufferThermal));
00086   
00087   _camera_info = _camera_info_manager->getCameraInfo();
00088   _camera_info.header = img.header;
00089   _camera_info_pub->publish(img, _camera_info);
00090 
00091   _pubThermal->publish(img);
00092 }
00093 
00094 void onVisibleDataReceive(const sensor_msgs::ImageConstPtr& image)
00095 {
00096   // check for any subscribers to save computation time
00097   if(_pubVisible->getNumSubscribers() == 0)
00098      return;
00099 
00100   if(_bufferVisible==NULL)
00101     _bufferVisible = new unsigned char[image->width * image->height * 3];
00102 
00103   const unsigned char* data = &image->data[0];
00104   _iBuilder.yuv422torgb24(data, _bufferVisible, image->width, image->height);
00105 
00106   sensor_msgs::Image img;
00107   img.header.frame_id = "visible_image_view";
00108   img.height          = image->height;
00109   img.width           = image->width;
00110   img.encoding        = "rgb8";
00111   img.step            = image->width*3;
00112   img.data.resize(img.height*img.step);
00113 
00114   img.header.seq      = _frame;
00115   img.header.stamp    = ros::Time::now();
00116 
00117   for(unsigned int i=0; i<image->width*image->height*3; i++) {
00118     img.data[i] = _bufferVisible[i];
00119   }
00120 
00121   _pubVisible->publish(img);
00122 }
00123 
00124 int main (int argc, char* argv[])
00125 {
00126   ros::init (argc, argv, "optris_colorconvert_node");
00127 
00128   // private node handle to support command line parameters for rosrun
00129   ros::NodeHandle n_("~");
00130 
00131   int palette = 6;
00132   n_.getParam("palette", palette);
00133   _palette = (optris::EnumOptrisColoringPalette) palette;
00134 
00135   optris::EnumOptrisPaletteScalingMethod scalingMethod = optris::eMinMax;
00136   int sm;
00137   n_.getParam("paletteScaling", sm);
00138   if(sm>=1 && sm <=4) scalingMethod = (optris::EnumOptrisPaletteScalingMethod) sm;
00139 
00140   _iBuilder.setPaletteScalingMethod(scalingMethod);
00141   _iBuilder.setPalette(_palette);
00142 
00143   double tMin     = 20.;
00144   double tMax     = 40.;
00145   double looprate = 30.;
00146 
00147   n_.getParam("temperatureMin", tMin);
00148   n_.getParam("temperatureMax", tMax);
00149   n_.getParam("looprate",       looprate);
00150 
00151   _iBuilder.setManualTemperatureRange((float)tMin, (float)tMax);
00152 
00153   ros::NodeHandle n;
00154   image_transport::ImageTransport it(n);
00155   image_transport::Subscriber subThermal = it.subscribe("thermal_image", 1, onThermalDataReceive);
00156   image_transport::Subscriber subVisible = it.subscribe("visible_image", 1, onVisibleDataReceive);
00157 
00158   image_transport::Publisher pubt = it.advertise("thermal_image_view", 1);
00159   image_transport::Publisher pubv = it.advertise("visible_image_view", 1);
00160 
00161   _pubThermal = &pubt;
00162   _pubVisible = &pubv;
00163 
00164   std::string camera_name;
00165   std::string camera_info_url;
00166   n_.getParam("camera_name", camera_name);
00167   n_.getParam("camera_info_url", camera_info_url);
00168 
00169   // initialize CameraInfoManager, providing set_camera_info service for geometric calibration
00170   // see http://wiki.ros.org/camera_info_manager
00171   camera_info_manager::CameraInfoManager cinfo_manager(n);
00172   _camera_info_manager = &cinfo_manager;
00173 
00174   if (!_camera_info_manager->setCameraName(camera_name))
00175   {
00176     // GUID is 16 hex digits, which should be valid.
00177     // If not, use it for log messages anyway.
00178     ROS_WARN_STREAM("[" << camera_name
00179                     << "] name not valid"
00180                     << " for camera_info_manger");
00181   }
00182 
00183   if (_camera_info_manager->validateURL(camera_info_url))
00184   {
00185     if ( !_camera_info_manager->loadCameraInfo(camera_info_url) )
00186     {
00187       ROS_WARN( "camera_info_url does not contain calibration data." );
00188     } 
00189     else if ( !_camera_info_manager->isCalibrated() )
00190     {
00191       ROS_WARN( "Camera is not calibrated. Using default values." );
00192     } 
00193   } 
00194   else
00195   {
00196     ROS_ERROR_STREAM_ONCE( "Calibration URL syntax is not supported by CameraInfoManager." );
00197   }
00198 
00199   // Advertise a synchronized camera raw image + info topic pair with subscriber status callbacks.
00200   image_transport::CameraPublisher cinfo_pub = it.advertiseCamera("image_raw", 1);
00201   _camera_info_pub = &cinfo_pub;
00202 
00203   // set to png compression
00204   std::string key;
00205   if(ros::param::search("thermal_image/compressed/format", key))
00206   {
00207      ros::param::set(key, "png");
00208   }
00209   if(ros::param::search("thermal_image/compressed/png_level", key))
00210   {
00211      ros::param::set(key, 9);
00212   }
00213 
00214   // specify loop rate: a meaningful value according to your publisher configuration
00215   ros::Rate loop_rate(looprate);
00216   while (ros::ok())
00217   {
00218     ros::spinOnce();
00219     loop_rate.sleep();
00220   }
00221 
00222   if(_bufferThermal)     delete [] _bufferThermal;
00223   if(_bufferVisible)  delete [] _bufferVisible;
00224 }


optris_drivers
Author(s): Stefan May (Nuremberg Institute of Technology Georg Simon Ohm - www.th-nuernberg.de), 64-Bit platform supported by Fraunhofer IPA (www.ipa.fraunhofer.de), Support for ROS hydro migration by Christopher-Eyk Hrabia (DAI-Labor, Technische Universität Berlin)
autogenerated on Thu Jun 6 2019 22:02:23