halcon_image.cpp
Go to the documentation of this file.
00001 
00018 #include <asr_halcon_bridge/halcon_image.h>
00019 #include <sensor_msgs/image_encodings.h>
00020 #include <boost/make_shared.hpp>
00021 
00022 namespace halcon_bridge {
00023 
00024     const char* INVALID = "invalid";
00025     const char* RGB = "rgb";
00026     const char* BGR = "bgr";
00027 
00028     int getHalconTypeSize(const std::string& type) {
00029 
00030         if ((type == "byte") || (type == "int1")) return 1;
00031         if ((type == "uint2") || (type == "int2")) return 2;
00032         if ((type == "int4") || (type == "real")) return 4;
00033         if (type == "int8") return 8;
00034 
00035         return -1;
00036     }
00037 
00038     const char* getHalconEncoding(const std::string& encoding) {
00039       // 3/4-channel encodings
00040       if (encoding == sensor_msgs::image_encodings::BGR8)   return "bgr";
00041       if (encoding == sensor_msgs::image_encodings::RGB8)   return "rgb";
00042       if (encoding == sensor_msgs::image_encodings::BGRA8)  return "bgrx";
00043       if (encoding == sensor_msgs::image_encodings::RGBA8)  return "rgbx";
00044 
00045       // 1-channel encoding
00046       if (encoding == sensor_msgs::image_encodings::MONO8)  return "mono";
00047 
00048       // Other formats are not supported
00049       return INVALID;
00050     }
00051 
00052 
00053 
00054     const char* getHalconChannelLength(const std::string& encoding) {
00055 
00056         if ((encoding == sensor_msgs::image_encodings::BGR8) || (encoding == sensor_msgs::image_encodings::RGB8) ||
00057                 (encoding == sensor_msgs::image_encodings::BGRA8) || (encoding == sensor_msgs::image_encodings::RGBA8) ||
00058                 (encoding == sensor_msgs::image_encodings::MONO8)) {
00059           return "byte";
00060         }
00061       if ((encoding == sensor_msgs::image_encodings::BGR16) || (encoding == sensor_msgs::image_encodings::RGB16) ||
00062               (encoding == sensor_msgs::image_encodings::BGRA16) || (encoding == sensor_msgs::image_encodings::RGBA16) ||
00063               (encoding == sensor_msgs::image_encodings::MONO16)) {
00064          return "uint2";
00065       }
00066 
00067       return INVALID;
00068     }
00069 
00070 
00071 
00072     const char* getColorChannelOrder(const std::string& encoding) {
00073         if ((encoding == sensor_msgs::image_encodings::BGR8) || (encoding == sensor_msgs::image_encodings::BGRA8) ||
00074                 (encoding == sensor_msgs::image_encodings::BGR16) || (encoding == sensor_msgs::image_encodings::BGRA16)) {
00075             return BGR;
00076         }
00077         if ((encoding == sensor_msgs::image_encodings::RGB8) || (encoding == sensor_msgs::image_encodings::RGBA8) ||
00078                 (encoding == sensor_msgs::image_encodings::RGB16) || (encoding == sensor_msgs::image_encodings::RGBA16)) {
00079             return RGB;
00080         }
00081         return INVALID;
00082     }
00083 
00084 
00085 
00086 
00087     HalconImage::~HalconImage() {
00088         delete image;
00089     }
00090 
00091     sensor_msgs::ImagePtr HalconImage::toImageMsg() const {
00092       sensor_msgs::ImagePtr ptr = boost::make_shared<sensor_msgs::Image>();
00093       toImageMsg(*ptr);
00094       return ptr;
00095     }
00096 
00097 
00098 
00099     void HalconImage::toImageMsg(sensor_msgs::Image& ros_image) const {
00100         long width, height;
00101         width = image->Width();
00102         height = image->Height();
00103 
00104         int channel_count = image->CountChannels();
00105 
00106         ros_image.height = height;
00107         ros_image.width = width;
00108         ros_image.encoding = encoding;
00109         ros_image.is_bigendian = false;
00110         ros_image.step = channel_count * width;
00111 
00112 
00113         HalconCpp::HString typeReturn;
00114         Hlong widthReturn;
00115         Hlong heightReturn;
00116         HalconCpp::HString type = image->GetImageType();
00117 
00118         if (channel_count > 1) {
00119 
00120             //build interleaved image from 3-channel image
00121 
00122             HalconCpp::HImage *interleavedImage = new HalconCpp::HImage(type, width * 3, height);
00123 
00124             HalconCpp::HHomMat2D homMat;
00125             homMat = homMat.HomMat2dScale(1, 3, 0, 0);
00126 
00127             HalconCpp::HImage transImage = image->AffineTransImageSize(homMat, "constant", width * 3, height);
00128 
00129             HalconCpp::HImage imageRed;
00130             HalconCpp::HImage imageGreen;
00131             HalconCpp::HImage imageBlue;
00132             imageRed = transImage.Decompose3(&imageGreen, &imageBlue);
00133 
00134 
00135             HalconCpp::HRegion regionGrid;
00136             regionGrid.GenGridRegion(2 * height, 3, "lines", width * 3, height + 1);
00137             HalconCpp::HRegion movedRegion = regionGrid.MoveRegion(-1, 0);
00138             HalconCpp::HRegion clippedRegion = movedRegion.ClipRegion(0, 0, height - 1, (3 * width) - 1);
00139 
00140             if (getColorChannelOrder(encoding) == RGB) {
00141                 imageRed = imageRed.ReduceDomain(clippedRegion);
00142             } else {
00143                 imageBlue = imageBlue.ReduceDomain(clippedRegion);
00144             }
00145             movedRegion = regionGrid.MoveRegion(-1, 1);
00146             clippedRegion = movedRegion.ClipRegion(0, 0, height - 1, (3 * width) - 1);
00147             imageGreen = imageGreen.ReduceDomain(clippedRegion);
00148             movedRegion = regionGrid.MoveRegion(-1, 2);
00149             clippedRegion = movedRegion.ClipRegion(0, 0, height - 1, (3 * width) - 1);
00150             if (getColorChannelOrder(encoding) == RGB) {
00151                 imageBlue = imageBlue.ReduceDomain(clippedRegion);
00152             } else {
00153                 imageRed = imageRed.ReduceDomain(clippedRegion);
00154             }
00155 
00156             interleavedImage->OverpaintGray(imageRed);
00157             interleavedImage->OverpaintGray(imageGreen);
00158             interleavedImage->OverpaintGray(imageBlue);
00159 
00160 
00161 
00162             // copy data of interleaved image into sensor_msg
00163             unsigned char* colorData = (unsigned char*)interleavedImage->GetImagePointer1(&typeReturn, &widthReturn, &heightReturn);
00164             int interleavedHeight = interleavedImage->Height();
00165             int interleavedWidth =  interleavedImage->Width();
00166             size_t size = interleavedHeight * interleavedWidth * getHalconTypeSize((std::string)typeReturn);
00167             ros_image.data.resize(size);
00168             memcpy((unsigned char*)(&ros_image.data[0]), colorData, size);
00169 
00170             interleavedImage->Clear();
00171             imageRed.Clear();
00172             imageGreen.Clear();
00173             imageBlue.Clear();
00174             homMat.Clear();
00175             regionGrid.Clear();
00176             clippedRegion.Clear();
00177             movedRegion.Clear();
00178 
00179 
00180         } else {
00181 
00182             // 1-channel image: copy data of original image
00183             unsigned char* colorData = (unsigned char*)image->GetImagePointer1(&typeReturn, &widthReturn, &heightReturn);
00184             size_t size = height * width * getHalconTypeSize((std::string)typeReturn);
00185             ros_image.data.resize(size);
00186             memcpy((unsigned char*)(&ros_image.data[0]), colorData, size);
00187         }
00188 
00189     }
00190 
00191 
00192 
00193     HalconImagePtr toHalconCopy(const sensor_msgs::ImageConstPtr& source) {
00194       return toHalconCopy(*source);
00195     }
00196 
00197     HalconImagePtr toHalconCopy(const sensor_msgs::Image& source) {
00198         HalconImagePtr ptr = boost::make_shared<HalconImage>();
00199         ptr->header = source.header;
00200         ptr->encoding = source.encoding;
00201 
00202         if (getHalconEncoding(ptr->encoding) == INVALID) {
00203             throw Exception("Encoding " + ptr->encoding + " not supported");
00204         }
00205 
00206         long* pixeldata = (long*)const_cast<unsigned char*>(&source.data[0]);
00207         HalconCpp::HImage *img = new HalconCpp::HImage();
00208         if ((std::string)getHalconEncoding(source.encoding) == "mono") {
00209              img->GenImage1(getHalconChannelLength(source.encoding), source.width, source.height, pixeldata);
00210         } else {
00211             img->GenImageInterleaved(pixeldata, getHalconEncoding(source.encoding), source.width, source.height, 0,
00212                                  getHalconChannelLength(source.encoding), source.width, source.height, 0, 0, -1, 0);
00213         }
00214         ptr->image = img;
00215 
00216         return ptr;
00217     }
00218 
00219 }
00220 
00221 


asr_halcon_bridge
Author(s): Allgeyer Tobias
autogenerated on Thu Jun 6 2019 18:32:11