format7stereo.cpp
Go to the documentation of this file.
1 /* $Id: format7.cpp 35691 2011-02-02 04:28:58Z joq $ */
2 
3 /*********************************************************************
4 * Software License Agreement (BSD License)
5 *
6 * Copyright (c) 2010 Ken Tossell, Jack O'Quin
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution.
19 * * Neither the name of the author nor other contributors may be
20 * used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 *********************************************************************/
36 
43 #include <stdint.h>
44 #include "yuv.h"
46 #include "format7.h"
47 #include "modes.h"
48 
49 
58 bool Format7::start(dc1394camera_t *camera,
59  dc1394video_mode_t mode,
60  Config &newconfig)
61 {
62  active_ = false;
63 
64  // copy Format7 parameters for updateCameraInfo()
65  binning_x_ = newconfig.binning_x;
66  binning_y_ = newconfig.binning_y;
67  roi_.x_offset = newconfig.x_offset;
68  roi_.y_offset = newconfig.y_offset;
69  roi_.width = newconfig.roi_width;
70  roi_.height = newconfig.roi_height;
71 
72  uint32_t packet_size = newconfig.format7_packet_size;
73 
74 /*******************************************************************************
75  * Commented by JOAN PAU to allow debayering on format7 modes
76  // Built-in libdc1394 Bayer decoding (now deprecated) is not
77  // supported at all in Format7 modes.
78  if (newconfig.bayer_method != "")
79  {
80  ROS_WARN_STREAM("Bayer method [" << newconfig.bayer_method
81  << "] not supported for Format7 modes."
82  << " Using image_proc instead.");
83  newconfig.bayer_method = "";
84  }
85  ******************************************************************************/
86 
87  // scan all Format7 modes to determine the full-sensor image size,
88  // from which we will calculate the binning values
89  uint32_t sensor_width = 0, sensor_height = 0;
90 
91  for (int scan_mode = DC1394_VIDEO_MODE_FORMAT7_MIN;
92  scan_mode <= DC1394_VIDEO_MODE_FORMAT7_MAX;
93  ++scan_mode)
94  {
95  uint32_t scan_width, scan_height;
96 
97  // TODO: only scan modes supported by this device
98  if (dc1394_format7_get_max_image_size(camera,
99  (dc1394video_mode_t) scan_mode,
100  &scan_width, &scan_height)
101  != DC1394_SUCCESS)
102  continue;
103 
104  if (scan_width > sensor_width)
105  sensor_width = scan_width;
106 
107  if (scan_height > sensor_height)
108  sensor_height = scan_height;
109  }
110 
111  if (DC1394_SUCCESS != dc1394_format7_get_max_image_size(camera, mode,
112  &maxWidth_,
113  &maxHeight_))
114  {
115  ROS_ERROR("Could not get max image size");
116  return false;
117  }
118 
119  if (newconfig.binning_x == 0 || newconfig.binning_y == 0)
120  {
121  binning_x_ = sensor_width / maxWidth_;
122  binning_y_ = sensor_height / maxHeight_;
123  }
124  else
125  {
126  binning_x_ = newconfig.binning_x;
127  binning_y_ = newconfig.binning_y;
128  }
129 
132 
133  if ((roi_.x_offset | roi_.y_offset | roi_.width | roi_.height) == 0)
134  {
135  roi_.width = maxWidth_;
136  roi_.height = maxHeight_;
137  }
138 
139  uint32_t unit_w, unit_h, unit_x, unit_y;
140 
141  if (DC1394_SUCCESS != dc1394_format7_get_unit_size(camera, mode,
142  &unit_w, &unit_h))
143  {
144  ROS_ERROR("Could not get ROI size units");
145  return false;
146  }
147 
148  unit_w *= binning_x_;
149  unit_h *= binning_y_;
150 
151  if (DC1394_SUCCESS != dc1394_format7_get_unit_position(camera, mode,
152  &unit_x, &unit_y))
153  {
154  ROS_ERROR("Could not get ROI position units");
155  return false;
156  }
157 
158  // some devices return zeros for the position units
159  if (unit_x == 0) unit_x = 1;
160  if (unit_y == 0) unit_y = 1;
161 
162  unit_x *= binning_x_;
163  unit_y *= binning_y_;
164 
165  ROS_INFO_STREAM("Format7 unit size: ("
166  << unit_w << "x" << unit_h
167  << "), position: ("
168  << unit_x << "x" << unit_y
169  << ")");
170  ROS_INFO_STREAM("Format7 region size: ("
171  << roi_.width << "x" << roi_.height
172  << "), offset: ("
173  << roi_.x_offset << ", " << roi_.y_offset
174  << ")");
175 
176  /* Reset ROI position to (0,0). If it was previously (x,y) and
177  * the requested ROI size (w,h) results in (x,y) + (w,h) >
178  * (max_w,max_h), we'll be unable to set up some valid ROIs
179  */
180  dc1394_format7_set_image_position(camera, mode, 0, 0);
181 
182  if ((roi_.width % unit_w) || (roi_.height % unit_h))
183  {
185  ROS_ERROR("Requested image size invalid; (w,h) must be"
186  " a multiple of (%d, %d)", unit_w, unit_h);
187  return false;
188  }
189 
190  uint32_t binned_width = roi_.width / binning_x_;
191  uint32_t binned_height = roi_.height / binning_y_;
192 
193  uint32_t binned_x_offset = roi_.x_offset / binning_x_;
194  uint32_t binned_y_offset = roi_.y_offset / binning_y_;
195 
196  if (DC1394_SUCCESS != dc1394_format7_set_image_size(camera, mode,
197  binned_width,
198  binned_height))
199  {
200  ROS_ERROR("Could not set size of ROI");
201  return false;
202  }
203 
204  if ((roi_.x_offset % unit_x) || (roi_.y_offset % unit_y))
205  {
206  ROS_ERROR("Requested image position invalid; (x,y) must"
207  " be a multiple of (%d, %d)", unit_x, unit_y);
208  return false;
209  }
210 
211  if (DC1394_SUCCESS != dc1394_format7_set_image_position(camera, mode,
212  binned_x_offset,
213  binned_y_offset))
214  {
215  ROS_ERROR("Could not set position of ROI");
216  return false;
217  }
218 
219  // Try to set requested color coding. Use current camera value if
220  // requested coding is not supported by the camera.
221  coding_ = Modes::getColorCoding(camera, mode,
222  newconfig.format7_color_coding);
223 
224  if (DC1394_SUCCESS != dc1394_format7_set_color_coding(camera, mode,
225  coding_))
226  {
227  ROS_ERROR("Could not set color coding");
228  return false;
229  }
230 
231  uint32_t rec_packet_size;
232 
233  if (DC1394_SUCCESS
234  != dc1394_format7_get_recommended_packet_size(camera, mode,
235  &rec_packet_size))
236  {
237  ROS_ERROR("Could not get default packet size");
238  return false;
239  }
240 
241  if (0 == packet_size)
242  packet_size = rec_packet_size;
243 
244  uint32_t unit_bytes, max_bytes;
245 
246  if (DC1394_SUCCESS
247  != dc1394_format7_get_packet_parameters(camera, mode,
248  &unit_bytes, &max_bytes))
249  {
250  ROS_ERROR("Could not determine maximum and increment for packet size");
251  return false;
252  }
253 
254  if (packet_size % unit_bytes
255  || (max_bytes > 0 && packet_size > max_bytes))
256  {
257  ROS_ERROR("Invalid packet size: %d. Must be a "
258  "multiple of %d, at most %d [%d]",
259  packet_size, unit_bytes, max_bytes, rec_packet_size);
260  return false;
261  }
262 
263  if (DC1394_SUCCESS != dc1394_format7_set_packet_size(camera, mode,
264  packet_size))
265  {
266  ROS_ERROR("Could not set packet size");
267  return false;
268  }
269 
270  if (coding_ == DC1394_COLOR_CODING_RAW8
271  || coding_ == DC1394_COLOR_CODING_RAW16)
272  {
273  if (DC1394_SUCCESS != dc1394_format7_get_color_filter(camera, mode,
274  &BayerPattern_))
275  {
276  ROS_ERROR("Could not determine color pattern");
277  return false;
278  }
279  }
280 
281  active_ = true; // Format7 mode is active
282 
283  return true;
284 }
285 
287 void Format7::stop(void)
288 {
289  active_ = false;
290 }
291 
292 extern std::string bayer_string(dc1394color_filter_t pattern, unsigned int bits);
293 
295 void Format7::unpackData(sensor_msgs::Image &image, uint8_t *capture_buffer)
296 {
297  int image_size;
298  switch (coding_)
299  {
300  case DC1394_COLOR_CODING_MONO8:
301  image.step = image.width;
302  image_size = image.height * image.step;
303  image.encoding = sensor_msgs::image_encodings::MONO8;
304  image.is_bigendian = false;
305  image.data.resize(image_size);
306  memcpy(&image.data[0], capture_buffer, image_size);
307  break;
308  case DC1394_COLOR_CODING_YUV411:
309  image.step = image.width * 3;
310  image_size = image.height * image.step;
311  image.encoding = sensor_msgs::image_encodings::RGB8;
312  image.data.resize(image_size);
313  yuv::uyyvyy2rgb(reinterpret_cast<unsigned char *> (capture_buffer),
314  reinterpret_cast<unsigned char *> (&image.data[0]),
315  image.width * image.height);
316  break;
317  case DC1394_COLOR_CODING_YUV422:
318  image.step = image.width * 3;
319  image_size = image.height * image.step;
320  image.encoding = sensor_msgs::image_encodings::RGB8;
321  image.data.resize(image_size);
322  yuv::uyvy2rgb(reinterpret_cast<unsigned char *> (capture_buffer),
323  reinterpret_cast<unsigned char *> (&image.data[0]),
324  image.width * image.height);
325  break;
326  case DC1394_COLOR_CODING_YUV444:
327  image.step=image.width * 3;
328  image_size = image.height * image.step;
329  image.encoding = sensor_msgs::image_encodings::RGB8;
330  image.data.resize(image_size);
331  yuv::uyv2rgb(reinterpret_cast<unsigned char *> (capture_buffer),
332  reinterpret_cast<unsigned char *> (&image.data[0]),
333  image.width * image.height);
334  break;
335  case DC1394_COLOR_CODING_RGB8:
336  image.step=image.width*3;
337  image_size = image.height*image.step;
338  image.encoding = sensor_msgs::image_encodings::RGB8;
339  image.data.resize(image_size);
340  memcpy(&image.data[0], capture_buffer, image_size);
341  break;
342  case DC1394_COLOR_CODING_MONO16:
343  image.step=image.width*2;
344  image_size = image.height*image.step;
345  image.encoding = sensor_msgs::image_encodings::MONO16;
346  image.is_bigendian = true;
347  image.data.resize(image_size);
348  memcpy(&image.data[0], capture_buffer, image_size);
349  break;
350  case DC1394_COLOR_CODING_RGB16:
351  image.step = image.width * 6;
352  image_size = image.height * image.step;
354  image.is_bigendian = true;
355  image.data.resize(image_size);
356  memcpy(&image.data[0], capture_buffer, image_size);
357  break;
358  case DC1394_COLOR_CODING_MONO16S:
359  image.step = image.width * 2;
360  image_size = image.height * image.step;
362  image.is_bigendian = true;
363  image.data.resize(image_size);
364  memcpy(&image.data[0], capture_buffer, image_size);
365  break;
366  case DC1394_COLOR_CODING_RGB16S:
367  image.step = image.width * 6;
368  image_size = image.height * image.step;
370  image.is_bigendian = true;
371  image.data.resize(image_size);
372  memcpy(&image.data[0], capture_buffer, image_size);
373  break;
374  case DC1394_COLOR_CODING_RAW8:
375  image.step = image.width;
376  image_size = image.height * image.step;
377  image.encoding = bayer_string(BayerPattern_, 8);
378  image.data.resize(image_size);
379  memcpy(&image.data[0], capture_buffer, image_size);
380  break;
381  case DC1394_COLOR_CODING_RAW16:
382  image.step = image.width * 2;
383  image_size = image.height * image.step;
384  image.encoding = bayer_string(BayerPattern_, 16);
385  image.is_bigendian = true;
386  image.data.resize(image_size);
387  memcpy(&image.data[0], capture_buffer, image_size);
388  break;
389  default:
390  ROS_ERROR_STREAM("Driver bug: unknown Format7 color coding:"
391  << coding_);
392  ROS_BREAK();
393  }
394 }
395 
406 bool Format7::checkCameraInfo(const sensor_msgs::CameraInfo &cinfo)
407 {
408  // see if the (full) image size matches the calibration
409  if (cinfo.width == maxWidth_ && cinfo.height == maxHeight_)
410  {
411  return true;
412  }
413  // or if the ROI size matches the calibration
414  else if (cinfo.width == roi_.width && cinfo.height == roi_.height)
415  {
416  return true;
417  }
418  else
419  {
420  ROS_WARN_STREAM_THROTTLE(30, "Calibrated image size ("
421  << cinfo.width << "x" << cinfo.height
422  << ") matches neither full Format7 size ("
423  << maxWidth_ << "x" << maxHeight_
424  << ") nor ROI size ("
425  << roi_.width << "x" << roi_.height << ")");
426  return false;
427  }
428 }
429 
440 void Format7::setOperationalParameters(sensor_msgs::CameraInfo &cinfo)
441 {
442  // copy the operational data determined during start()
443  cinfo.binning_x = binning_x_;
444  cinfo.binning_y = binning_y_;
445  cinfo.roi = roi_;
446 
447  // set do_rectify depending on current calibration parameters
448  cinfo.roi.do_rectify = false;
449 
450  if (cinfo.K[0] == 0.0)
451  return; // uncalibrated
452 
453  bool roiMatchesCalibration = (cinfo.width == roi_.width
454  && cinfo.height == roi_.height);
455 
456  if (cinfo.width == maxWidth_ && cinfo.height == maxHeight_)
457  {
458  // calibration matches full image size
459  if (!roiMatchesCalibration)
460  {
461  // ROI is not full image: tell image_pipeline to rectify
462  cinfo.roi.do_rectify = true;
463  }
464  }
465  else
466  {
467  // calibration differs from full image
468  if (!roiMatchesCalibration)
469  {
470  // calibrated size is neither full image nor current ROI:
471  // tell image_pipeline to rectify the data.
472  cinfo.roi.do_rectify = true;
473  }
474  }
475 }
void unpackData(sensor_msgs::Image &image, uint8_t *capture_buffer)
camera1394stereo::Camera1394StereoConfig Config
void stop(void)
libdc1394 enumerated modes interface
uint32_t maxHeight_
Definition: format7.h:94
dc1394color_coding_t coding_
Definition: format7.h:92
void uyvy2rgb(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
Definition: yuv.h:70
bool start(dc1394camera_t *camera, dc1394video_mode_t mode, Config &newconfig)
dc1394color_coding_t getColorCoding(dc1394camera_t *camera, dc1394video_mode_t video_mode, std::string &color_coding)
Definition: modes.cpp:148
uint32_t maxWidth_
Definition: format7.h:93
uint32_t binning_y_
Definition: format7.h:101
YUV to RGB conversion functions.
bool active_
Definition: format7.h:91
const std::string TYPE_16SC3
dc1394color_filter_t BayerPattern_
Definition: format7.h:104
const std::string MONO16
void setOperationalParameters(sensor_msgs::CameraInfo &cinfo)
const std::string TYPE_16UC3
std::string bayer_string(dc1394color_filter_t pattern, unsigned int bits)
#define ROS_WARN_STREAM_THROTTLE(rate, args)
Camera1394 Format7 interface.
#define ROS_INFO_STREAM(args)
void uyyvyy2rgb(const unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
Definition: yuv.h:96
uint32_t binning_x_
Definition: format7.h:100
#define ROS_ERROR_STREAM(args)
bool checkCameraInfo(const sensor_msgs::CameraInfo &cinfo)
#define ROS_BREAK()
sensor_msgs::RegionOfInterest roi_
Definition: format7.h:97
#define ROS_ERROR(...)
void uyv2rgb(const unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
Definition: yuv.h:50
const std::string TYPE_16SC1


camera1394stereo
Author(s): Joan Pau Beltran
autogenerated on Mon Jun 10 2019 12:52:45