00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <pcl/pcl_config.h>
00040 #ifdef HAVE_FZAPI
00041
00042 #include <pcl/io/fotonic_grabber.h>
00043 #include <pcl/point_cloud.h>
00044 #include <pcl/point_types.h>
00045 #include <pcl/common/time.h>
00046 #include <pcl/common/io.h>
00047 #include <pcl/console/print.h>
00048 #include <pcl/io/boost.h>
00049 #include <pcl/exceptions.h>
00050
00051 #include <boost/thread.hpp>
00052
00053 #include <iostream>
00054
00056 pcl::FotonicGrabber::FotonicGrabber (const FZ_DEVICE_INFO& device_info, const Mode& depth_mode, const Mode& image_mode)
00057 : running_ (false)
00058 {
00059
00060 onInit (device_info, depth_mode, image_mode);
00061
00062 point_cloud_signal_ = createSignal<sig_cb_fotonic_point_cloud> ();
00063 point_cloud_rgb_signal_ = createSignal<sig_cb_fotonic_point_cloud_rgb> ();
00064 point_cloud_rgba_signal_ = createSignal<sig_cb_fotonic_point_cloud_rgba> ();
00065 }
00066
00068 pcl::FotonicGrabber::~FotonicGrabber () throw ()
00069 {
00070 stop ();
00071
00072 disconnect_all_slots<sig_cb_fotonic_point_cloud> ();
00073 disconnect_all_slots<sig_cb_fotonic_point_cloud_rgb> ();
00074 disconnect_all_slots<sig_cb_fotonic_point_cloud_rgba> ();
00075 }
00076
00078 void
00079 pcl::FotonicGrabber::initAPI ()
00080 {
00081 FZ_Init ();
00082 }
00083
00085 void
00086 pcl::FotonicGrabber::exitAPI ()
00087 {
00088 FZ_Exit ();
00089 }
00090
00092 std::vector<FZ_DEVICE_INFO>
00093 pcl::FotonicGrabber::enumDevices ()
00094 {
00095
00096 int num_of_devices = 32;
00097 FZ_DEVICE_INFO * device_infos = new FZ_DEVICE_INFO[num_of_devices];
00098 FZ_Result result = FZ_EnumDevices2 (device_infos, &num_of_devices);
00099
00100
00101 std::vector<FZ_DEVICE_INFO> devices;
00102 for (int index = 0; index < num_of_devices; ++index)
00103 {
00104 FZ_DEVICE_INFO device_info;
00105 device_info.iDeviceType = device_infos[index].iDeviceType;
00106 memcpy (device_info.iReserved, device_infos[index].iReserved, sizeof (device_infos[index].iReserved[0])*64);
00107 memcpy (device_info.szPath, device_infos[index].szPath, sizeof (device_infos[index].szPath[0])*512);
00108 memcpy (device_info.szSerial, device_infos[index].szSerial, sizeof (device_infos[index].szSerial[0])*16);
00109 memcpy (device_info.szShortName, device_infos[index].szShortName, sizeof (device_infos[index].szShortName[0])*32);
00110
00111 devices.push_back (device_info);
00112 }
00113
00114 return (devices);
00115 }
00116
00118 void
00119 pcl::FotonicGrabber::start ()
00120 {
00121 FZ_CmdRespCode_t resp;
00122 FZ_Result res = FZ_IOCtl (*fotonic_device_handle_, CMD_DE_SENSOR_START, NULL, 0, &resp, NULL, NULL);
00123
00124 running_ = true;
00125
00126 grabber_thread_ = boost::thread(&pcl::FotonicGrabber::processGrabbing, this);
00127 }
00128
00130 void
00131 pcl::FotonicGrabber::stop ()
00132 {
00133 running_ = false;
00134 grabber_thread_.join ();
00135
00136 FZ_Close (*fotonic_device_handle_);
00137 }
00138
00140 bool
00141 pcl::FotonicGrabber::isRunning () const
00142 {
00143 return (running_);
00144 }
00145
00147 std::string
00148 pcl::FotonicGrabber::getName () const
00149 {
00150 return std::string ("FotonicGrabber");
00151 }
00152
00154 float
00155 pcl::FotonicGrabber::getFramesPerSecond () const
00156 {
00157
00158 return 0.0f;
00159 }
00160
00162 void
00163 pcl::FotonicGrabber::onInit (const FZ_DEVICE_INFO& device_info, const Mode& depth_mode, const Mode& image_mode)
00164 {
00165 setupDevice (device_info, depth_mode, image_mode);
00166 }
00167
00169 void
00170 pcl::FotonicGrabber::setupDevice (const FZ_DEVICE_INFO& device_info, const Mode& depth_mode, const Mode& image_mode)
00171 {
00172
00173 fotonic_device_handle_ = new FZ_Device_Handle_t ();
00174
00175 unsigned int flags = 0;
00176
00177 FZ_Result res;
00178
00179 res = FZ_Open (device_info.szPath, flags, fotonic_device_handle_);
00180
00181
00182 FZ_CmdRespCode_t resp;
00183 unsigned short mode = DE_MODE_640X480_30;
00184 res = FZ_IOCtl (*fotonic_device_handle_, CMD_DE_SET_MODE, &mode, sizeof(mode), &resp, NULL, NULL);
00185
00186 res = FZ_SetFrameDataFmt (*fotonic_device_handle_, -1, -1, -1, -1, FZ_FMT_PIXEL_PER_PLANE+FZ_FMT_COMPONENT_Z+FZ_FMT_COMPONENT_XY+FZ_FMT_COMPONENT_B);
00187 }
00188
00190 void
00191 pcl::FotonicGrabber::processGrabbing ()
00192 {
00193 char * frame_buffer = new char [640*480*8];
00194
00195 bool continue_grabbing = running_;
00196 while (continue_grabbing)
00197 {
00198 FZ_Result result = FZ_FrameAvailable (*fotonic_device_handle_);
00199
00200
00201 if (result == FZ_Success)
00202 {
00203 size_t length_in_byte = 640*480*10;
00204 FZ_FRAME_HEADER frame_header;
00205
00206 result = FZ_GetFrame (*fotonic_device_handle_, &frame_header, frame_buffer, &length_in_byte);
00207
00208 if (result == FZ_Success)
00209 {
00210
00211
00212
00213
00214
00215
00216
00217
00218 const int width = frame_header.ncols;
00219 const int height = frame_header.nrows;
00220
00221 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGBA> ());
00222 cloud->resize (width*height);
00223 cloud->width = width;
00224 cloud->height = height;
00225 cloud->is_dense = false;
00226
00227 short * ptr = (short*) frame_buffer;
00228
00229 for (int row_index = 0; row_index < height; ++row_index)
00230 {
00231
00232 {
00233
00234 FZ_YUV422_DOUBLE_PIXEL *p = (FZ_YUV422_DOUBLE_PIXEL*)ptr;
00235 int col = 0;
00236 for (int col_index = 0; col_index < width/2; ++col_index)
00237 {
00238 pcl::PointXYZRGBA & point0 = (*cloud) (col, row_index);
00239 ++col;
00240 pcl::PointXYZRGBA & point1 = (*cloud) (col, row_index);
00241 ++col;
00242
00243 float r,g,b,u,v,u1,v1,uv1;
00244
00245 u = p[col_index].u - 128.0f;
00246 v = p[col_index].v - 128.0f;
00247 v1 = 1.13983f*v;
00248 uv1 = -0.39465f*u - 0.58060f*v;
00249 u1 = 0.03211f*u;
00250
00251 r = p[col_index].y1 + v1;
00252 g = p[col_index].y1 + uv1;
00253 b = p[col_index].y1 + u1;
00254
00255 r = std::min (255.0f, std::max (0.0f, r));
00256 g = std::min (255.0f, std::max (0.0f, g));
00257 b = std::min (255.0f, std::max (0.0f, b));
00258
00259 point0.r = unsigned(r);
00260 point0.g = unsigned(g);
00261 point0.b = unsigned(b);
00262
00263 r = p[col_index].y2 + v1;
00264 g = p[col_index].y2 + uv1;
00265 b = p[col_index].y2 + u1;
00266
00267 r = std::min (255.0f, std::max (0.0f, r));
00268 g = std::min (255.0f, std::max (0.0f, g));
00269 b = std::min (255.0f, std::max (0.0f, b));
00270
00271 point1.r = unsigned(r);
00272 point1.g = unsigned(g);
00273 point1.b = unsigned(b);
00274 }
00275
00276 ptr += width;
00277 }
00278
00279 for (int col_index = 0; col_index < width; ++col_index)
00280 {
00281 pcl::PointXYZRGBA & point = (*cloud) (col_index, row_index);
00282
00283 short z = *ptr;
00284
00285 point.z = static_cast<float> (z) / 1000.0f;
00286
00287 ++ptr;
00288 }
00289
00290 for (int col_index = 0; col_index < width; ++col_index)
00291 {
00292 pcl::PointXYZRGBA & point = (*cloud) (col_index, row_index);
00293
00294 short x = *ptr;
00295 ++ptr;
00296
00297 point.x = -static_cast<float> (x) / 1000.0f;
00298 }
00299
00300 for (int col_index = 0; col_index < width; ++col_index)
00301 {
00302 pcl::PointXYZRGBA & point = (*cloud) (col_index, row_index);
00303
00304 short y = *ptr;
00305 ++ptr;
00306
00307 point.y = static_cast<float> (y) / 1000.0f;
00308 }
00309 }
00310
00311
00312 if (num_slots<sig_cb_fotonic_point_cloud_rgba> () > 0)
00313 {
00314 point_cloud_rgba_signal_->operator() (cloud);
00315 }
00316 if (num_slots<sig_cb_fotonic_point_cloud_rgb> () > 0)
00317 {
00318 pcl::PointCloud<pcl::PointXYZRGB>::Ptr tmp_cloud (new pcl::PointCloud<pcl::PointXYZRGB> ());
00319 cloud->resize (width*height);
00320 cloud->width = width;
00321 cloud->height = height;
00322 cloud->is_dense = false;
00323
00324 pcl::copyPointCloud<pcl::PointXYZRGBA, pcl::PointXYZRGB> (*cloud, *tmp_cloud);
00325
00326 point_cloud_rgb_signal_->operator() (tmp_cloud);
00327 }
00328 if (num_slots<sig_cb_fotonic_point_cloud> () > 0)
00329 {
00330 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_tmp (new pcl::PointCloud<pcl::PointXYZ> ());
00331 cloud->resize (width*height);
00332 cloud->width = width;
00333 cloud->height = height;
00334 cloud->is_dense = false;
00335
00336 pcl::copyPointCloud<pcl::PointXYZRGBA, pcl::PointXYZ> (*cloud, *cloud_tmp);
00337
00338 point_cloud_signal_->operator() (cloud_tmp);
00339 }
00340
00341 }
00342 }
00343 else
00344 boost::this_thread::sleep (boost::posix_time::milliseconds(1));
00345
00346 continue_grabbing = running_;
00347 }
00348 }
00349
00350
00351 #endif