- Aldebaran documentation |
- C++ Libraries |
- index

libalvision 2.8.7.4

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Friends Macros Pages
alimage_opencv.h
Go to the documentation of this file.
1
14 #ifndef LIBALVISION_ALVISION_ALIMAGE_OPENCV_H_
15 #define LIBALVISION_ALVISION_ALIMAGE_OPENCV_H_
16
17 #include <cstring> // for std::memcpy
18 #include <opencv2/core.hpp>
19 #include <opencv2/imgcodecs.hpp>
20
21 #include <alerror/alerror.h>
22
23 #include "alimage.h"
24 #include "alvisiondefinitions.h"
25
26 namespace AL
27 {
34 static inline cv::Mat aLImageToCvMat(const AL::ALImage & al_image, int cv_type = -1)
35 {
36 // OpenCV does not take a const void* because the object could be modified later. This pointer will only be used
37 // in a tmp local cv::Mat so it's fine
38 unsigned char *data = const_cast<unsigned char*>(al_image.getData());
39
40 if (cv_type >= 0)
41 return cv::Mat(al_image.getHeight(), al_image.getWidth(), cv_type, data);
42
43 // Check the types
44 int n_layers = AL::getNumLayersInColorSpace(al_image.getColorSpace());
45 int n_channels = AL::getNumChannelsInColorSpace(al_image.getColorSpace());
46 if ((n_layers < 0) || (n_channels < 0)) {
47 std::stringstream ss;
48 ss << "Color space \"" << al_image.getColorSpace() << "\" not supported";
49 throw AL::ALError("ALVision", "aLImageToCvMat", ss.str());
50 }
51 int cv_depth;
52 switch (n_layers / n_channels)
53 {
54 case 4:
55 cv_depth = CV_32F;
56 break;
57 case 2:
58 cv_depth = CV_16U;
59 break;
60 case 1:
61 cv_depth = CV_8U;
62 break;
63 default:
64 std::stringstream ss;
65 ss << "Depth \"" << (n_layers / n_channels) << "\" not supported";
66 throw AL::ALError("ALVision", "aLImageToCvMat", ss.str());
67 }
68
69 return cv::Mat(al_image.getHeight(), al_image.getWidth(),
70 CV_MAKETYPE(cv_depth, n_channels), data);
71 }
72
79 static inline AL::ALImage* cvMatToALImage(const cv::Mat & img,
80 int colorSpace,
81 float pLeftAngle = 0.0f, float pTopAngle = 0.0f,
82 float pRightAngle = 0.0f, float pBottomAngle = 0.0f)
83 {
84 // Check the number of channels
85 if (AL::getNumChannelsInColorSpace(colorSpace) != img.channels())
86 throw AL::ALError("ALVision", "cvMatToALImage",
87 "Channel number incompatibility between cv::Mat and colorSpace");
88
89 // Check the channel type
90 switch (img.depth())
91 {
92 case CV_8U:
93 case CV_16U:
94 case CV_32F:
95 break;
96 default:
97 throw AL::ALError("ALVision", "cvMatToALImage",
98 "Type incompatibility between cv::Mat and colorSpace");
99 }
100
101 // Create an ALImage with the buffer
102 AL::ALImage *al_image = new AL::ALImage(img.cols, img.rows, colorSpace, true,
103 pLeftAngle, pTopAngle, pRightAngle, pBottomAngle);
104 al_image->setData(img.data);
105
106 return al_image;
107 }
108
114 static inline AL::ALImage* cvMatToALImageCopy(const cv::Mat & img,
115 int colorSpace,
116 float pLeftAngle = 0.0f, float pTopAngle = 0.0f,
117 float pRightAngle = 0.0f, float pBottomAngle = 0.0f)
118 {
119 // Check the number of channels
120 if (AL::getNumChannelsInColorSpace(colorSpace) != img.channels())
121 throw AL::ALError("ALVision", "cvMatToALImage",
122 "Channel number incompatibility between cv::Mat and colorSpace");
123
124 // Check the channel type
125 switch (img.depth())
126 {
127 case CV_8U:
128 case CV_16U:
129 case CV_32F:
130 break;
131 default:
132 throw AL::ALError("ALVision", "cvMatToALImage",
133 "Type incompatibility between cv::Mat and colorSpace");
134 }
135
136 // Create an ALImage with the buffer
137 AL::ALImage *al_image = new AL::ALImage(img.cols, img.rows, colorSpace, false,
138 pLeftAngle, pTopAngle, pRightAngle, pBottomAngle);
139 std::memcpy(al_image->getData(), img.data, img.cols * img.rows * img.elemSize());
140
141 return al_image;
142 }
143
152 static inline bool writeALImageToFile(const std::string& path, const ALImage& al_image)
153 {
154 if(!cv::imwrite(path, aLImageToCvMat(al_image)))
155 {
156 throw AL::ALError("ALVision", "writeALImageToFile",
157 "Can't write image to "+path);
158 }
159
160 const std::string path_data = path+".yml";
161 cv::FileStorage fs(path_data, cv::FileStorage::WRITE);
162 if(!fs.isOpened())
163 {
164 throw AL::ALError("ALVision", "writeALImageToFile",
165 "Can't open "+path_data+" to write metadata");
166 }
167 try {
168 fs << "width" << al_image.getWidth();
169 fs << "height" << al_image.getHeight();
170 // fs << "nb_layers" << al_image.getNbLayers(); // unused
171 fs << "colorspace" << al_image.getColorSpace();
172 long long timestamp = al_image.getTimeStamp();
173 fs << "timestamp_s" << static_cast<int>(timestamp/1000000ll);
174 fs << "timestamp_us" << static_cast<int>(timestamp%1000000ll);
175 fs << "camera_id" << static_cast<int>(al_image.getCameraId());
176 fs << "fov_left" << al_image.getLeftAngle();
177 fs << "fov_top" << al_image.getTopAngle();
178 fs << "fov_right" << al_image.getRightAngle();
179 fs << "fov_bottom" << al_image.getBottomAngle();
180 fs << "roi_enabled" << al_image.isROIEnabled();
181 fs << "rois" << "[";
182 for(int i = 0; i < al_image.getNumOfROIs(); ++i)
183 {
184 const ALImage::ROI* roi = al_image.getROI(i);
185 fs << "{"
186 << "x" << roi->x
187 << "y" << roi->y
188 << "width" << roi->w
189 << "height" << roi->h
190 << "leftAngle" << roi->leftAngle
191 << "topAngle" << roi->topAngle
192 << "rightAngle" << roi->rightAngle
193 << "bottomAngle" << roi->bottomAngle
194 << "}";
195 }
196 fs << "]";
197 fs.release();
198 } catch(const cv::Exception& e)
199 {
200 throw AL::ALError("ALVision", "writeALImageToFile",
201 "Exception caught when writing metadata to "+path_data+": "+e.what());
202 }
203
204 return true;
205 }
206
214 static inline ALImage readALImageFromFile(const std::string& path, int pColorspace = -1)
215 {
216 const cv::Mat img = cv::imread(path, cv::IMREAD_ANYCOLOR);
217
218 const std::string path_data = path+".yml";
219 cv::FileStorage fs(path_data, cv::FileStorage::READ);
220
221 if(!fs.isOpened())
222 {
223 if(pColorspace == -1)
224 {
225 throw AL::ALError("ALVision", "readALImageFromFile",
226 "Can't open "+path_data+" to read metadata");
227 }
228 else
229 {
230 ALImage al_image(img.cols, img.rows, pColorspace, false);
231 unsigned char* data = al_image.getData();
232 const size_t data_size = img.cols * img.rows * img.elemSize();
233 std::memcpy(data, img.data, data_size);
234 return al_image;
235 }
236 }
237
238 int width, height, /*nb_layers, */colorspace, timestamp_s, timestamp_us, camera_id;
239 float fov_left, fov_top, fov_right, fov_bottom;
240 bool roi_enabled;
241 std::vector<ALImage::ROI> rois;
242 try {
243 fs["width"] >> width;
244 fs["height"] >> height;
245 // fs["nb_layers"] >> nb_layers; // unused
246 fs["colorspace"] >> colorspace;
247 fs["timestamp_s"] >> timestamp_s;
248 fs["timestamp_us"] >> timestamp_us;
249 fs["camera_id"] >> camera_id;
250 fs["fov_left"] >> fov_left;
251 fs["fov_top"] >> fov_top;
252 fs["fov_right"] >> fov_right;
253 fs["fov_bottom"] >> fov_bottom;
254 fs["roi_enabled"] >> roi_enabled;
255 cv::FileNode fn_rois = fs["rois"];
256 cv::FileNodeIterator it = fn_rois.begin();
257 for(; it != fn_rois.end(); ++it)
258 {
259 const int roi_x = (*it)["x"];
260 const int roi_y = (*it)["y"];
261 const int roi_w = (*it)["width"];
262 const int roi_h = (*it)["height"];
263 const float roi_leftAngle = (*it)["leftAngle"];
264 const float roi_topAngle = (*it)["topAngle"];
265 const float roi_rightAngle = (*it)["rightAngle"];
266 const float roi_bottomAngle = (*it)["bottomAngle"];
267 const ALImage::ROI roi(roi_x, roi_y, roi_w, roi_h,
268 roi_leftAngle, roi_topAngle, roi_rightAngle, roi_bottomAngle);
269 rois.push_back(roi);
270 }
271 fs.release();
272 } catch(const cv::Exception& e)
273 {
274 throw AL::ALError("ALVision", "readALImageFromFile",
275 "Exception caught when reading metadata from "+path_data+": "+e.what());
276 }
277
278 if(width != img.cols || height != img.rows)
279 {
280 throw AL::ALError("ALVision", "readALImageFromFile",
281 "Image dimensions do not match metadata");
282 }
283
284 ALImage al_image(img.cols, img.rows, colorspace, false);
285 unsigned char* data = al_image.getData();
286 const size_t data_size = img.cols * img.rows * img.elemSize();
287 std::memcpy(data, img.data, data_size);
288 al_image.setTimeStamp(timestamp_s, timestamp_us);
289 al_image.setCameraId(static_cast<char>(camera_id));
290 al_image.setAngles(fov_left, fov_top, fov_right, fov_bottom);
291 al_image.setEnableROIs(roi_enabled);
292 for(size_t i = 0; i < rois.size(); ++i)
293 {
294 al_image.addROI(rois[i]);
295 }
296 return al_image;
297 }
298
299 }
300
301 #endif /* LIBALVISION_ALVISION_ALIMAGE_OPENCV_H_ */
AL::getNumChannelsInColorSpace
int getNumChannelsInColorSpace(const int colorSpace)
Utility function that returns the number of channels for a given color space.
AL::ALImage
Definition: alimage.h:28
AL::getNumLayersInColorSpace
int getNumLayersInColorSpace(const int colorSpace)
Utility function that returns the number of layers for a given color space.
AL::ALImage::setData
void setData(unsigned char *pData)
set the image data pointer to point to the specified buffer.
Definition: alimage.h:196
alvisiondefinitions.h
vision defines
AL::ALImage::getData
const unsigned char * getData() const
return the reference to the image data.
Definition: alimage.h:171
alimage.h
handle image
AL::ALImage::getWidth
int getWidth(void) const
Definition: alimage.h:249
AL::ALImage::getHeight
int getHeight(void) const
Definition: alimage.h:250
AL::ALImage::getColorSpace
int getColorSpace(void) const
Definition: alimage.h:252