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.