format7.cpp
Go to the documentation of this file.
1 /* $Id$ */
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"
45 #include <cstdlib>
47 #include "format7.h"
48 #include "modes.h"
49 
50 
59 bool Format7::start(dc1394camera_t *camera,
60  dc1394video_mode_t mode,
61  Config &newconfig)
62 {
63  active_ = false;
64 
65  // copy Format7 parameters for updateCameraInfo()
66  binning_x_ = newconfig.binning_x;
67  binning_y_ = newconfig.binning_y;
68  roi_.x_offset = newconfig.x_offset;
69  roi_.y_offset = newconfig.y_offset;
70  roi_.width = newconfig.roi_width;
71  roi_.height = newconfig.roi_height;
72 
73  uint32_t packet_size = newconfig.format7_packet_size;
74 
75  // Built-in libdc1394 Bayer decoding (now deprecated) is not
76  // supported at all in Format7 modes.
77  if (newconfig.bayer_method != "")
78  {
79  ROS_WARN_STREAM("Bayer method [" << newconfig.bayer_method
80  << "] not supported for Format7 modes."
81  << " Using image_proc instead.");
82  newconfig.bayer_method = "";
83  }
84 
85  const char* pattern = newconfig.bayer_pattern.c_str();
86  dc1394color_filter_t bayer_pattern = findBayerPattern(pattern);
87  if ((bayer_pattern >= DC1394_COLOR_FILTER_MIN)
88  && (bayer_pattern <= DC1394_COLOR_FILTER_MAX))
89  {
90  BayerPattern_ = bayer_pattern;
91  }
92  else
93  {
94  ROS_WARN_STREAM("Bayer pattern [" << newconfig.bayer_pattern << " ("
95  << bayer_pattern << ")] is invalid.");
96  }
97 
98  // scan all Format7 modes to determine the full-sensor image size,
99  // from which we will calculate the binning values
100  uint32_t sensor_width = 0, sensor_height = 0;
101 
102  for (int scan_mode = DC1394_VIDEO_MODE_FORMAT7_MIN;
103  scan_mode <= DC1394_VIDEO_MODE_FORMAT7_MAX;
104  ++scan_mode)
105  {
106  uint32_t scan_width, scan_height;
107 
108  // TODO: only scan modes supported by this device
109  if (dc1394_format7_get_max_image_size(camera,
110  (dc1394video_mode_t) scan_mode,
111  &scan_width, &scan_height)
112  != DC1394_SUCCESS)
113  continue;
114 
115  if (scan_width > sensor_width)
116  sensor_width = scan_width;
117 
118  if (scan_height > sensor_height)
119  sensor_height = scan_height;
120  }
121 
122  if (DC1394_SUCCESS != dc1394_format7_get_max_image_size(camera, mode,
123  &maxWidth_,
124  &maxHeight_))
125  {
126  ROS_ERROR("Could not get max image size");
127  return false;
128  }
129 
130  if (newconfig.binning_x == 0 || newconfig.binning_y == 0)
131  {
132  binning_x_ = sensor_width / maxWidth_;
133  binning_y_ = sensor_height / maxHeight_;
134  }
135  else
136  {
137  binning_x_ = newconfig.binning_x;
138  binning_y_ = newconfig.binning_y;
139  }
140 
143 
144  if ((roi_.x_offset | roi_.y_offset | roi_.width | roi_.height) == 0)
145  {
146  roi_.width = maxWidth_;
147  roi_.height = maxHeight_;
148  }
149 
150  uint32_t unit_w, unit_h, unit_x, unit_y;
151 
152  if (DC1394_SUCCESS != dc1394_format7_get_unit_size(camera, mode,
153  &unit_w, &unit_h))
154  {
155  ROS_ERROR("Could not get ROI size units");
156  return false;
157  }
158 
159  unit_w *= binning_x_;
160  unit_h *= binning_y_;
161 
162  if (DC1394_SUCCESS != dc1394_format7_get_unit_position(camera, mode,
163  &unit_x, &unit_y))
164  {
165  ROS_ERROR("Could not get ROI position units");
166  return false;
167  }
168 
169  // some devices return zeros for the position units
170  if (unit_x == 0) unit_x = 1;
171  if (unit_y == 0) unit_y = 1;
172 
173  unit_x *= binning_x_;
174  unit_y *= binning_y_;
175 
176  ROS_INFO_STREAM("Format7 unit size: ("
177  << unit_w << "x" << unit_h
178  << "), position: ("
179  << unit_x << "x" << unit_y
180  << ")");
181  ROS_INFO_STREAM("Format7 region size: ("
182  << roi_.width << "x" << roi_.height
183  << "), offset: ("
184  << roi_.x_offset << ", " << roi_.y_offset
185  << ")");
186 
187  /* Reset ROI position to (0,0). If it was previously (x,y) and
188  * the requested ROI size (w,h) results in (x,y) + (w,h) >
189  * (max_w,max_h), we'll be unable to set up some valid ROIs
190  */
191  dc1394_format7_set_image_position(camera, mode, 0, 0);
192 
193  if ((roi_.width % unit_w) || (roi_.height % unit_h))
194  {
196  ROS_ERROR("Requested image size invalid; (w,h) must be"
197  " a multiple of (%d, %d)", unit_w, unit_h);
198  return false;
199  }
200 
201  uint32_t binned_width = roi_.width / binning_x_;
202  uint32_t binned_height = roi_.height / binning_y_;
203 
204  uint32_t binned_x_offset = roi_.x_offset / binning_x_;
205  uint32_t binned_y_offset = roi_.y_offset / binning_y_;
206 
207  if (DC1394_SUCCESS != dc1394_format7_set_image_size(camera, mode,
208  binned_width,
209  binned_height))
210  {
211  ROS_ERROR("Could not set size of ROI");
212  return false;
213  }
214 
215  if ((roi_.x_offset % unit_x) || (roi_.y_offset % unit_y))
216  {
217  ROS_ERROR("Requested image position invalid; (x,y) must"
218  " be a multiple of (%d, %d)", unit_x, unit_y);
219  return false;
220  }
221 
222  if (DC1394_SUCCESS != dc1394_format7_set_image_position(camera, mode,
223  binned_x_offset,
224  binned_y_offset))
225  {
226  ROS_ERROR("Could not set position of ROI");
227  return false;
228  }
229 
230  // Try to set requested color coding. Use current camera value if
231  // requested coding is not supported by the camera.
232  coding_ = Modes::getColorCoding(camera, mode,
233  newconfig.format7_color_coding);
234 
235  if (DC1394_SUCCESS != dc1394_format7_set_color_coding(camera, mode,
236  coding_))
237  {
238  ROS_ERROR("Could not set color coding");
239  return false;
240  }
241 
242  uint32_t rec_packet_size;
243 
244  if (DC1394_SUCCESS
245  != dc1394_format7_get_recommended_packet_size(camera, mode,
246  &rec_packet_size))
247  {
248  ROS_ERROR("Could not get default packet size");
249  return false;
250  }
251 
252  if (0 == packet_size)
253  packet_size = rec_packet_size;
254 
255  uint32_t unit_bytes, max_bytes;
256 
257  if (DC1394_SUCCESS
258  != dc1394_format7_get_packet_parameters(camera, mode,
259  &unit_bytes, &max_bytes))
260  {
261  ROS_ERROR("Could not determine maximum and increment for packet size");
262  return false;
263  }
264 
265  if (packet_size % unit_bytes
266  || (max_bytes > 0 && packet_size > max_bytes))
267  {
268  ROS_ERROR("Invalid packet size: %d. Must be a "
269  "multiple of %d, at most %d [%d]",
270  packet_size, unit_bytes, max_bytes, rec_packet_size);
271  return false;
272  }
273 
274  if (DC1394_SUCCESS != dc1394_format7_set_packet_size(camera, mode,
275  packet_size))
276  {
277  ROS_ERROR("Could not set packet size");
278  return false;
279  }
280 
281  if (coding_ == DC1394_COLOR_CODING_RAW8
282  || coding_ == DC1394_COLOR_CODING_RAW16)
283  {
284  dc1394color_filter_t
285  color_filter = (dc1394color_filter_t) DC1394_COLOR_FILTER_NUM;
286  if (DC1394_SUCCESS != dc1394_format7_get_color_filter(camera, mode,
287  &color_filter))
288  {
289  ROS_ERROR("Could not determine color pattern");
290  return false;
291  }
292  if (BayerPattern_ == (dc1394color_filter_t) DC1394_COLOR_FILTER_NUM)
293  {
294  BayerPattern_ = color_filter;
295  }
296  else if ( BayerPattern_ != color_filter )
297  {
298  ROS_WARN_STREAM("Bayer Pattern was set to "
299  << BayerPattern_ << "but get_color_filter returned "
300  << color_filter << ". Using " << BayerPattern_);
301  }
302  }
303 
304  active_ = true; // Format7 mode is active
305 
306  return true;
307 }
308 
310 void Format7::stop(void)
311 {
312  active_ = false;
313 }
314 
315 extern std::string bayer_string(dc1394color_filter_t pattern,
316  unsigned int bits);
317 
319 void Format7::unpackData(sensor_msgs::Image &image, uint8_t *capture_buffer)
320 {
321  int image_size;
322  switch (coding_)
323  {
324  case DC1394_COLOR_CODING_MONO8:
325  image.step = image.width;
326  image_size = image.height * image.step;
327  image.encoding = sensor_msgs::image_encodings::MONO8;
328  image.is_bigendian = false;
329  image.data.resize(image_size);
330  memcpy(&image.data[0], capture_buffer, image_size);
331  break;
332  case DC1394_COLOR_CODING_YUV411:
333  image.step = image.width * 3;
334  image_size = image.height * image.step;
335  image.encoding = sensor_msgs::image_encodings::RGB8;
336  image.data.resize(image_size);
337  yuv::uyyvyy2rgb(reinterpret_cast<unsigned char *> (capture_buffer),
338  reinterpret_cast<unsigned char *> (&image.data[0]),
339  image.width * image.height);
340  break;
341  case DC1394_COLOR_CODING_YUV422:
342  image.step = image.width * 3;
343  image_size = image.height * image.step;
344  image.encoding = sensor_msgs::image_encodings::RGB8;
345  image.data.resize(image_size);
346  yuv::uyvy2rgb(reinterpret_cast<unsigned char *> (capture_buffer),
347  reinterpret_cast<unsigned char *> (&image.data[0]),
348  image.width * image.height);
349  break;
350  case DC1394_COLOR_CODING_YUV444:
351  image.step=image.width * 3;
352  image_size = image.height * image.step;
353  image.encoding = sensor_msgs::image_encodings::RGB8;
354  image.data.resize(image_size);
355  yuv::uyv2rgb(reinterpret_cast<unsigned char *> (capture_buffer),
356  reinterpret_cast<unsigned char *> (&image.data[0]),
357  image.width * image.height);
358  break;
359  case DC1394_COLOR_CODING_RGB8:
360  image.step=image.width*3;
361  image_size = image.height*image.step;
362  image.encoding = sensor_msgs::image_encodings::RGB8;
363  image.data.resize(image_size);
364  memcpy(&image.data[0], capture_buffer, image_size);
365  break;
366  case DC1394_COLOR_CODING_MONO16:
367  image.step=image.width*2;
368  image_size = image.height*image.step;
369  image.encoding = sensor_msgs::image_encodings::MONO16;
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_RGB16:
375  image.step = image.width * 6;
376  image_size = image.height * image.step;
378  image.is_bigendian = true;
379  image.data.resize(image_size);
380  memcpy(&image.data[0], capture_buffer, image_size);
381  break;
382  case DC1394_COLOR_CODING_MONO16S:
383  image.step = image.width * 2;
384  image_size = image.height * image.step;
386  image.is_bigendian = true;
387  image.data.resize(image_size);
388  memcpy(&image.data[0], capture_buffer, image_size);
389  break;
390  case DC1394_COLOR_CODING_RGB16S:
391  image.step = image.width * 6;
392  image_size = image.height * image.step;
394  image.is_bigendian = true;
395  image.data.resize(image_size);
396  memcpy(&image.data[0], capture_buffer, image_size);
397  break;
398  case DC1394_COLOR_CODING_RAW8:
399  image.step = image.width;
400  image_size = image.height * image.step;
401  image.encoding = bayer_string(BayerPattern_, 8);
402  image.data.resize(image_size);
403  memcpy(&image.data[0], capture_buffer, image_size);
404  break;
405  case DC1394_COLOR_CODING_RAW16:
406  image.step = image.width * 2;
407  image_size = image.height * image.step;
408  image.encoding = bayer_string(BayerPattern_, 16);
409  image.is_bigendian = true;
410  image.data.resize(image_size);
411  memcpy(&image.data[0], capture_buffer, image_size);
412  break;
413  default:
414  ROS_ERROR_STREAM("Driver bug: unknown Format7 color coding:"
415  << coding_);
416  ROS_BREAK();
417  }
418 }
419 
430 bool Format7::checkCameraInfo(const sensor_msgs::CameraInfo &cinfo)
431 {
432  // see if the (full) image size matches the calibration
433  if (cinfo.width == maxWidth_ && cinfo.height == maxHeight_)
434  {
435  return true;
436  }
437  // or if the ROI size matches the calibration
438  else if (cinfo.width == roi_.width && cinfo.height == roi_.height)
439  {
440  return true;
441  }
442  else
443  {
444  ROS_WARN_STREAM_THROTTLE(30, "Calibrated image size ("
445  << cinfo.width << "x" << cinfo.height
446  << ") matches neither full Format7 size ("
447  << maxWidth_ << "x" << maxHeight_ << ")"
448  << ") nor ROI size ("
449  << roi_.width << "x" << roi_.height << ")");
450  return false;
451  }
452 }
453 
464 void Format7::setOperationalParameters(sensor_msgs::CameraInfo &cinfo)
465 {
466  // copy the operational data determined during start()
467  cinfo.binning_x = binning_x_;
468  cinfo.binning_y = binning_y_;
469  cinfo.roi = roi_;
470 
471  // set do_rectify depending on current calibration parameters
472  cinfo.roi.do_rectify = false;
473 
474  if (cinfo.K[0] == 0.0)
475  return; // uncalibrated
476 
477  bool roiMatchesCalibration = (cinfo.width == roi_.width
478  && cinfo.height == roi_.height);
479 
480  if (cinfo.width == maxWidth_ && cinfo.height == maxHeight_)
481  {
482  // calibration matches full image size
483  if (!roiMatchesCalibration)
484  {
485  // ROI is not full image: tell image_pipeline to rectify
486  cinfo.roi.do_rectify = true;
487  }
488  }
489  else
490  {
491  // calibration differs from full image
492  if (!roiMatchesCalibration)
493  {
494  // calibrated size is neither full image nor current ROI:
495  // tell image_pipeline to rectify the data.
496  cinfo.roi.do_rectify = true;
497  }
498  }
499 }
500 
507 dc1394color_filter_t Format7::findBayerPattern(const char* bayer)
508 {
509  // determine Bayer color encoding pattern
510  // (default is different from any color filter provided by DC1394)
511  dc1394color_filter_t
512  pattern = (dc1394color_filter_t) DC1394_COLOR_FILTER_NUM;
513 
514  if (0 == strcmp(bayer, "bggr"))
515  {
516  pattern = DC1394_COLOR_FILTER_BGGR;
517  }
518  else if (0 == strcmp(bayer, "grbg"))
519  {
520  pattern = DC1394_COLOR_FILTER_GRBG;
521  }
522  else if (0 == strcmp(bayer, "rggb"))
523  {
524  pattern = DC1394_COLOR_FILTER_RGGB;
525  }
526  else if (0 == strcmp(bayer, "gbrg"))
527  {
528  pattern = DC1394_COLOR_FILTER_GBRG;
529  }
530  else if (0 != strcmp(bayer, ""))
531  {
532  ROS_ERROR("unknown bayer pattern [%s]", bayer);
533  }
534  return pattern;
535 }
536 
void unpackData(sensor_msgs::Image &image, uint8_t *capture_buffer)
Definition: format7.cpp:319
void stop(void)
Definition: format7.cpp:310
libdc1394 enumerated modes interface
uint32_t maxHeight_
Definition: format7.h:96
dc1394color_filter_t findBayerPattern(const char *bayer)
Definition: format7.cpp:507
dc1394color_coding_t coding_
Definition: format7.h:94
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)
Definition: format7.cpp:59
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:95
std::string bayer_string(dc1394color_filter_t pattern, unsigned int bits)
uint32_t binning_y_
Definition: format7.h:103
YUV to RGB conversion functions.
bool active_
Definition: format7.h:93
const std::string TYPE_16SC3
dc1394color_filter_t BayerPattern_
Definition: format7.h:106
const std::string MONO16
void setOperationalParameters(sensor_msgs::CameraInfo &cinfo)
Definition: format7.cpp:464
#define ROS_WARN_STREAM(args)
const std::string TYPE_16UC3
#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:102
camera1394::Camera1394Config Config
Definition: driver1394.h:53
#define ROS_ERROR_STREAM(args)
bool checkCameraInfo(const sensor_msgs::CameraInfo &cinfo)
Definition: format7.cpp:430
#define ROS_BREAK()
sensor_msgs::RegionOfInterest roi_
Definition: format7.h:99
#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


camera1394
Author(s): Jack O'Quin, Ken Tossell, Patrick Beeson, Nate Koenig, Andrew Howard, Damien Douxchamps, Dan Dennedy
autogenerated on Mon Jun 10 2019 12:52:31