19 #include <opencv2/imgproc/imgproc.hpp>    20 #include <Image/ImageProcessor.h>    22 #include <boost/make_shared.hpp>    30   if (encoding == enc::BGR8)   
return CV_8UC3;
    31   if (encoding == enc::MONO8)  
return CV_8UC1;
    32   if (encoding == enc::RGB8)   
return CV_8UC3;
    33   if (encoding == enc::MONO16) 
return CV_16UC1;
    34   if (encoding == enc::BGR16)  
return CV_16UC3;
    35   if (encoding == enc::RGB16)  
return CV_16UC3;
    36   if (encoding == enc::BGRA8)  
return CV_8UC4;
    37   if (encoding == enc::RGBA8)  
return CV_8UC4;
    38   if (encoding == enc::BGRA16) 
return CV_16UC4;
    39   if (encoding == enc::RGBA16) 
return CV_16UC4;
    42   if (encoding == enc::BAYER_RGGB8) 
return CV_8UC1;
    43   if (encoding == enc::BAYER_BGGR8) 
return CV_8UC1;
    44   if (encoding == enc::BAYER_GBRG8) 
return CV_8UC1;
    45   if (encoding == enc::BAYER_GRBG8) 
return CV_8UC1;
    46   if (encoding == enc::BAYER_RGGB16) 
return CV_16UC1;
    47   if (encoding == enc::BAYER_BGGR16) 
return CV_16UC1;
    48   if (encoding == enc::BAYER_GBRG16) 
return CV_16UC1;
    49   if (encoding == enc::BAYER_GRBG16) 
return CV_16UC1;
    52 #define CHECK_ENCODING(code)                            \    53   if (encoding == enc::TYPE_##code) return CV_##code    \    55 #define CHECK_CHANNEL_TYPE(t)                   \    56   CHECK_ENCODING(t##1);                         \    57   CHECK_ENCODING(t##2);                         \    58   CHECK_ENCODING(t##3);                         \    59   CHECK_ENCODING(t##4);                         \    70 #undef CHECK_CHANNEL_TYPE    73   throw Exception(
"Unrecognized image encoding [" + encoding + 
"]");
    76 CByteImage::ImageType 
getIvtType(
const std::string& encoding) {
    77           if (encoding == enc::RGB8)   
return CByteImage::eRGB24;
    78           if (encoding == enc::MONO8)  
return CByteImage::eGrayScale;
    79           throw Exception(
"No IVT equivalent to image encoding [" + encoding + 
"]");
    84 enum Format { INVALID = -1, GRAY = 0, RGB, BGR, RGBA, BGRA };
    86 Format getFormat(
const std::string& encoding) {
    87   if (encoding == enc::BGR8)   
return BGR;
    88   if (encoding == enc::MONO8)  
return GRAY;
    89   if (encoding == enc::RGB8)   
return RGB;
    90   if (encoding == enc::MONO16) 
return GRAY;
    91   if (encoding == enc::BGR16)  
return BGR;
    92   if (encoding == enc::RGB16)  
return RGB;
    93   if (encoding == enc::BGRA8)  
return BGRA;
    94   if (encoding == enc::RGBA8)  
return RGBA;
    95   if (encoding == enc::BGRA16) 
return BGRA;
    96   if (encoding == enc::RGBA16) 
return RGBA;
   102 static const int SAME_FORMAT = -1;
   104 int getConversionCode(Format src_format, Format dst_format) {
   105   static const int CONVERSION_CODES[] = { SAME_FORMAT, CV_GRAY2RGB, CV_GRAY2BGR, CV_GRAY2RGBA, CV_GRAY2BGRA,
   106                                                                                   CV_RGB2GRAY, SAME_FORMAT, CV_RGB2BGR, CV_RGB2RGBA, CV_RGB2BGRA,
   107                                                                                   CV_BGR2GRAY, CV_BGR2RGB, SAME_FORMAT, CV_BGR2RGBA, CV_BGR2BGRA,
   108                                                                                   CV_RGBA2GRAY, CV_RGBA2RGB, CV_RGBA2BGR, SAME_FORMAT, CV_RGBA2BGRA,
   109                                                                                   CV_BGRA2GRAY, CV_BGRA2RGB,  CV_BGRA2BGR, CV_BGRA2RGBA, SAME_FORMAT };
   110   return CONVERSION_CODES[src_format*5 + dst_format];
   114 IvtImagePtr toIvtCopyImpl(
const cv::Mat& source, 
const std_msgs::Header& src_header, 
const std::string& src_encoding, 
const std::string& dst_encoding) {
   119   ptr->header = src_header;
   122   Format src_format = getFormat(src_encoding);
   123   if (dst_encoding.empty()) {
   124     if (src_format == GRAY)
   125         ptr->encoding = enc::MONO8;
   127         ptr->encoding = enc::RGB8;
   130             ptr->encoding = dst_encoding;
   131   Format dst_format = getFormat(ptr->encoding);
   134   if (ptr->encoding == src_encoding) {
   139     if (src_format == INVALID || dst_format == INVALID)
   140       throw Exception(
"Unsupported conversion from [" + src_encoding + 
"] to [" + ptr->encoding + 
"]");
   142     int conversion_code = getConversionCode(src_format, dst_format);
   143     if (conversion_code == SAME_FORMAT) {
   146       int src_depth = enc::bitDepth(src_encoding);
   147       int dst_depth = enc::bitDepth(dst_encoding);
   149       if (src_depth == 8 && dst_depth == 16)
   150         alpha = 65535. / 255.;
   151       else if (src_depth == 16 && dst_depth == 8)
   152         alpha = 255. / 65535.;
   153       source.convertTo(tmp, 
getCvType(ptr->encoding), alpha);
   157       cv::cvtColor(source, tmp, conversion_code);
   161   ptr->image = 
new CByteImage(tmp.cols, tmp.rows, 
getIvtType(ptr->encoding));
   163   if (tmp.step == tmp.cols * tmp.elemSize()) {
   164           memcpy(ptr->image->pixels, tmp.data, tmp.cols * tmp.rows * tmp.elemSize());
   166           int ivtImgStep = ptr->image->bytesPerPixel*ptr->image->width;
   167           uchar *ivtImgPtr = ptr->image->pixels;
   168           uchar *cvImgPtr = tmp.data;
   169           for (
int i=0; i < tmp.rows; i++){
   170                   memcpy(ivtImgPtr, cvImgPtr, ivtImgStep);
   171                   ivtImgPtr += ivtImgStep;
   172                   cvImgPtr +=  tmp.step;
   185   sensor_msgs::ImagePtr ptr = boost::make_shared<sensor_msgs::Image>();
   191   ros_image.header = 
header;
   192   ros_image.height = 
image->height;
   193   ros_image.width = 
image->width;
   195   ros_image.is_bigendian = 
false;
   198   ros_image.data.resize(size);
   199   memcpy((
char*)(&ros_image.data[0]), 
image->pixels, size);
   209         if (encoding != enc::MONO8 && encoding != enc::RGB8 && !encoding.empty())
   210                 throw Exception(
"Encoding " + encoding + 
" not supported");
   211         int source_type = 
getCvType(source.encoding);
   212         const cv::Mat tmp((
int)source.height, (
int)source.width, source_type, const_cast<uint8_t*>(&source.data[0]), (
size_t)source.step);
   213         return toIvtCopyImpl(tmp, source.header, source.encoding, encoding);
   222         bool hasPadding = source.step != source.width * (source.encoding == enc::RGB8 ? 3 : 1);
   223         if ((!encoding.empty() && source.encoding != 
encoding) || (source.encoding != enc::MONO8 && source.encoding != enc::RGB8) || hasPadding)
   226         ptr->header = source.header;
   227         ptr->encoding = source.encoding;
   228         ptr->tracked_object_ = tracked_object;
   229         ptr->image = 
new CByteImage(source.width, source.height, 
getIvtType(ptr->encoding), 
true);
   230         ptr->image->pixels = 
const_cast<uchar*
>(&source.data[0]);
 
std::string encoding
Image encoding ("mono8", "bgr8", etc.) 
#define CHECK_CHANNEL_TYPE(t)
CByteImage::ImageType getIvtType(const std::string &encoding)
Get the CByteImage type enum corresponding to the encoding. 
IvtImagePtr toIvtCopy(const sensor_msgs::ImageConstPtr &source, const std::string &encoding=std::string())
Convert a sensor_msgs::Image message to an Ivt-compatible CByteImage, copying the image data...
int getCvType(const std::string &encoding)
Convert a IvtImage to another encoding. 
sensor_msgs::ImagePtr toImageMsg() const 
Convert this message to a ROS sensor_msgs::Image message. 
IvtImageConstPtr toIvtShare(const sensor_msgs::ImageConstPtr &source, const std::string &encoding=std::string())
Convert an immutable sensor_msgs::Image message to an Ivt-compatible CByteImage, sharing the image da...
CByteImage * image
Image data for use with Ivt. 
std_msgs::Header header
ROS header.