[ros-users] [camera_divers/camera1394] not able to set bayer…

Top Page
Attachments:
Message as email
+ (text/plain)
+ format7-bayer-patter.patch (text/plain)
Delete this message
Reply to this message
Author: User discussions
Date:  
To: User discussions
Subject: [ros-users] [camera_divers/camera1394] not able to set bayer pattern if camera is format7
Hello,

I tried to obtain images from an AVT Guppy using the nodelet
configuration, as shown below:

<launch>
   <!-- nodelet manager process -->
   <node pkg="nodelet" type="nodelet" name="camera_nodelet_manager"
         args="manager" />


   <!-- camera driver nodelet -->
   <node pkg="nodelet" type="nodelet" name="camera1394_nodelet"
         args="load camera1394/driver camera_nodelet_manager">
    <param name="video_mode" value="format7_mode0"/>
    <param name="format7_color_coding" value="raw8"/>
    <param name="bayer_pattern" value="bggr"/>
    <param name="bayer_method" value="" />
   </node>


   <!-- Bayer color decoding -->
   <node pkg="nodelet" type="nodelet" name="image_proc_debayer"
         args="load image_proc/debayer camera_nodelet_manager">
     <remap from="image_color" to="camera/image_color" />
     <remap from="image_mono" to="camera/image_mono" />
     <remap from="image_raw" to="camera/image_raw" />
   </node>


   <!-- Image View Node -->
   <node pkg="image_view" type="image_view" name="image_view" >
     <remap from="image" to="camera/image_color"/>
   </node>
</launch>


However, the bayer pattern reconstruction is using the pattern rggb,
instead of bggr, as it was told. Changing the pattern using the
dynamic_reconfigure GUI, also does have no effect.

I tried to trace the problem down and I found out, that as my camera is
set to work in the format7 video-mode, thus most of the work is
happening in camera_drivers/camera1394/src/nodes/format7.{h,cpp}. I
looked into the files and found out, that the desired pattern is no
where set in the code. Instead, regardless of the configured value, the
pattern type is always read from the camera, using the
dc1394_format7_get_color_filter function. The corresponding function to
set the value was removed from libdc1394 a long time ago (God knows why).

Since I don't know how to manipulate this value, I wrote a patch for
format7.{h,cpp} that basically stores the value of the desired bayer
pattern, and passes this value on in the corresponding field of
sensor_msgs::Image in the function unpackData. The patch is appended to
this email.

I'm not sure if what I do there is right, even though I now have color
images with the correct color (the sky is really blue now). Maybe
someone responsible for the developement of this driver can have a look
at it.

Yours,

Sebastian
--- format7.h.orig    2011-07-13 10:32:04.000000000 +0200
+++ format7.h    2011-07-13 11:36:28.000000000 +0200
@@ -70,7 +70,8 @@
     maxWidth_(0),
     maxHeight_(0),
     binning_x_(0),
-    binning_y_(0)
+    binning_y_(0),
+    BayerPattern_((dc1394color_filter_t) DC1394_COLOR_FILTER_NUM)
   {};
   ~Format7() {};


@@ -87,6 +88,7 @@
void setOperationalParameters(sensor_msgs::CameraInfo &cinfo);

private:
+ dc1394color_filter_t findBayerPattern(const char* bayer);

   bool active_;
   dc1394color_coding_t coding_;
--- format7.cpp.orig    2011-07-13 12:56:59.000000000 +0200
+++ format7.cpp    2011-07-13 13:00:16.000000000 +0200
@@ -81,6 +81,18 @@
       newconfig.bayer_method = "";
     }


+  const char* pattern = newconfig.bayer_pattern.c_str();
+  dc1394color_filter_t bayer_pattern = findBayerPattern(pattern);
+  if ((bayer_pattern >= DC1394_COLOR_FILTER_MIN) && (bayer_pattern <= DC1394_COLOR_FILTER_MAX))
+    {
+      BayerPattern_ = bayer_pattern;
+    }
+  else
+    {
+      ROS_WARN_STREAM("Bayer pattern [" << newconfig.bayer_pattern << " (" 
+                      << bayer_pattern << ")] is invalid.");
+    }
+
   // scan all Format7 modes to determine the full-sensor image size,
   // from which we will calculate the binning values
   uint32_t sensor_width = 0, sensor_height = 0;
@@ -267,12 +279,23 @@
   if (coding_ == DC1394_COLOR_CODING_RAW8
       || coding_ == DC1394_COLOR_CODING_RAW16)
     {
+      dc1394color_filter_t color_filter = (dc1394color_filter_t) DC1394_COLOR_FILTER_NUM;
       if (DC1394_SUCCESS != dc1394_format7_get_color_filter(camera, mode,
-                                                            &BayerPattern_))
+                                                            &color_filter))
         {
           ROS_ERROR("Could not determine color pattern");
           return false;
         }
+      if (BayerPattern_ == (dc1394color_filter_t) DC1394_COLOR_FILTER_NUM)
+        {
+          BayerPattern_ = color_filter;
+        }
+      else if ( BayerPattern_ != color_filter )
+        {
+          ROS_WARN_STREAM("Bayer Pattern was set to "
+                          << BayerPattern_ << "but get_color_filter returned "
+                          << color_filter << ". Using " << BayerPattern_);
+        }
     }


   active_ = true;                       // Format7 mode is active
@@ -470,3 +493,38 @@
     }
     }
 }
+
+/** returns the DC1394 color filter for the given bayer pattern string
+ *
+ *  @param bayer the string describing the pattern (e.g. bggr, rggb, ...)
+ *  @return the dc1394color_filter_t corresponding to the given string
+ *
+ */
+dc1394color_filter_t Format7::findBayerPattern(const char* bayer)
+{
+  // determine Bayer color encoding pattern
+  // (default is different from any color filter provided by DC1394)
+  dc1394color_filter_t pattern = (dc1394color_filter_t) DC1394_COLOR_FILTER_NUM;
+  if (0 == strcmp(bayer, "bggr"))
+    {
+      pattern = DC1394_COLOR_FILTER_BGGR;
+    }
+  else if (0 == strcmp(bayer, "grbg"))
+    {
+      pattern = DC1394_COLOR_FILTER_GRBG;
+    }
+  else if (0 == strcmp(bayer, "rggb"))
+    {
+      pattern = DC1394_COLOR_FILTER_RGGB;
+    }
+  else if (0 == strcmp(bayer, "gbrg"))
+    {
+      pattern = DC1394_COLOR_FILTER_GBRG;
+    }
+  else if (0 != strcmp(bayer, ""))
+    {
+      ROS_ERROR("unknown bayer pattern [%s]", bayer);
+    }
+  return pattern;
+}
+