diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a87e3844f21f376499af86a86c6c3e1b22434c61..965d79e87f911869a83503187f322645e4cc74fd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,7 +1,7 @@ # edit the following line to add the source code of the application -SET(sources firewirecamera.cpp firewireserver.cpp firewireexceptions.cpp pgr_stereo_camera.cpp) +SET(sources firewirecamera.cpp firewireserver.cpp firewireexceptions.cpp ptg_camera.cpp bumblebee.cpp ladybug.cpp) # edit the following line to add the header files of the application -SET(headers firewirecamera.h firewireserver.h firewireexceptions.h pgr_stereo_camera.h) +SET(headers firewirecamera.h firewireserver.h firewireexceptions.h ptg_camera.h bumblebee.h ladybug.h) #find the cv support and set HAVE_OPENCV_H for the conditional compilation FIND_PACKAGE(OpenCV) diff --git a/src/bumblebee.cpp b/src/bumblebee.cpp new file mode 100755 index 0000000000000000000000000000000000000000..27bcd0b2357c0151235701f45f6e3e2c7f33b886 --- /dev/null +++ b/src/bumblebee.cpp @@ -0,0 +1,292 @@ +#include "bumblebee.h" +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <fcntl.h> +#include <math.h> + +CBumblebee::CBumblebee(dc1394_t *firewire,uint64_t camera_id):CPTGCamera(firewire,camera_id) +{ + unsigned int left_off=0,top_off=0,rows,cols; + bool color; + + this->stereo_depth=(depths_t)-1; + this->stereo_coding=(codings_t)-1; + if(strncmp(this->camera_handle->model,"Bumblebee2",strlen("Bumblebee2"))!=0) + { + /* handle exceptions */ + throw CFirewireCameraException(_HERE_,"The camera is not a bumblebee2"); + } + this->set_ISO_speed(400); + // get the camera information + this->get_sensor_info(&color,&rows,&cols); + // configure the camera by default + if(color) + { + this->stereo_depth=DEPTH24; + this->stereo_coding=RGB; + } + else + { + this->stereo_depth=DEPTH8; + this->stereo_coding=MONO; + } + if(color) + this->set_config(&left_off,&top_off,&cols,&rows,&framerate,DEPTH16,RAW); + else + this->set_config(&left_off,&top_off,&cols,&rows,&framerate,DEPTH16,MONO); + this->get_bayer_pattern(&this->bayer_pattern); +} + +// overloaded functions from the base class +void CBumblebee::set_config(unsigned int *left_off,unsigned int *top_off,unsigned int *width,unsigned int *height, float *framerate, depths_t depth, codings_t coding) +{ + uint64_t total_bytes; + dc1394color_coding_t dc1394_coding; + dc1394error_t error; + unsigned int bpp; + + // set the operation mode + error=dc1394_video_set_mode(this->camera_handle,DC1394_VIDEO_MODE_FORMAT7_3); + if(error!=DC1394_SUCCESS) + { + /* handle exceptions */ + throw CFirewireInternalException(_HERE_,error); + } + this->mode=DC1394_VIDEO_MODE_FORMAT7_3; + // configure the camera + if(coding==MONO) + dc1394_coding=DC1394_COLOR_CODING_MONO16; + else + dc1394_coding=DC1394_COLOR_CODING_RAW16; + error=dc1394_format7_set_roi(this->camera_handle, + this->mode, + dc1394_coding, + DC1394_USE_MAX_AVAIL, + 0, + 0, + *width, + *height); + if(error!=DC1394_SUCCESS) + { + // handle exceptions + throw CFirewireInternalException(_HERE_,error); + } + this->left_offset=*left_off; + this->top_offset=*top_off; + this->width=*width; + this->height=*height; + this->coding=coding; + this->depth=depth; + // compute the actual framerate + error = dc1394_format7_get_total_bytes(this->camera_handle,this->mode,&total_bytes); + if ( error != DC1394_SUCCESS ) + { + DEBUG_INFO("failed.\n"); + /* handle the error */ + throw CFirewireInternalException(_HERE_,error); + } + error = dc1394_format7_get_packet_size(this->camera_handle,this->mode,&bpp); + if ( error != DC1394_SUCCESS ) + { + DEBUG_INFO("failed.\n"); + /* handle the error */ + throw CFirewireInternalException(_HERE_,error); + } + this->framerate=this->iso_rate*bpp*2/total_bytes; + this->set_num_DMA_buffers(4); +} + +void CBumblebee::get_stereo_image(char **left,char **right) +{ + int depth; + dc1394error_t error; + dc1394video_frame_t *frame; + unsigned char *de_interleaved,*RGB_image; + + if ( *left != NULL || *right != NULL) + { + DEBUG_INFO("Invalid image buffer.\n"); + /* handle error */ + throw CFirewireCameraException(_HERE_,"Invalid image buffer. Please provide an unallocated memory buffer."); + } + DEBUG_INFO("Capturing a new image ... "); + if ( this->one_shot_mode == DC1394_ON ) + { + /* set the one shot mode */ + DEBUG_INFO("Setting the one shot mode ... "); + error = dc1394_video_set_one_shot(this->camera_handle,DC1394_ON); + if ( error != DC1394_SUCCESS ) + { + DEBUG_INFO("failed\n"); + /* handle the error */ + throw CFirewireInternalException(_HERE_,error); + } + DEBUG_INFO("ok\n"); + DEBUG_INFO("Dequeuing a DMA buffer ... "); + error = dc1394_capture_dequeue(this->camera_handle,DC1394_CAPTURE_POLICY_WAIT,&frame); + if ( error != DC1394_SUCCESS ) + { + DEBUG_INFO("failed\n"); + /* handle error */ + throw CFirewireInternalException(_HERE_,error); + } + depth = (int)ceil((float)this->depth/8.0); + de_interleaved=new unsigned char[this->width*this->height*depth]; + // de-interlace the 16 bit data into 2 bayer tile pattern images + dc1394_deinterlace_stereo( (unsigned char *)frame->image, + de_interleaved, + this->width, + 2*this->height); + + if(this->stereo_coding==RGB) + { + depth = (int)ceil((float)this->stereo_depth/8.0); + RGB_image=new unsigned char[this->width*this->height*depth]; + // extract color from the bayer tile image + // note: this will alias colors on the top and bottom rows + dc1394_bayer_decoding_8bit( de_interleaved, + RGB_image, + this->width, + 2*this->height, + this->bayer_pattern, + DC1394_BAYER_METHOD_NEAREST); + + *left = new char[this->width*this->height*depth]; + *right = new char[this->width*this->height*depth]; + memcpy(*left,RGB_image,this->width*this->height*depth); + memcpy(*right,RGB_image+this->height*this->width*depth,this->width*this->height*depth); + delete[] RGB_image; + } + else + { + depth = (int)ceil((float)this->depth/8.0); + *left = new char[this->width*this->height*depth]; + *right = new char[this->width*this->height*depth]; + memcpy(*left,de_interleaved,this->width*this->height*depth); + memcpy(*right,de_interleaved+this->height*this->width*depth,this->width*this->height*depth); + } + if(this->frame_buffer!=NULL) + delete[] this->frame_buffer; + depth = (int)ceil((float)this->depth/8.0); + this->frame_buffer = new char[this->width*this->height*depth]; + memcpy(this->frame_buffer,frame->image,this->width*this->height*this->depth/8.0); + DEBUG_INFO("ok\n"); + DEBUG_INFO("Freeing the DMA buffer ... "); + error = dc1394_capture_enqueue(this->camera_handle,frame); + if ( error != DC1394_SUCCESS ) + { + DEBUG_INFO("failed\n"); + /* handle error */ + throw CFirewireInternalException(_HERE_,error); + } + DEBUG_INFO("ok\n"); + delete[] de_interleaved; + } + else + { + this->image_access.enter(); + depth = (int)ceil((float)this->depth/8.0); + de_interleaved=new unsigned char[this->width*this->height*depth]; + // de-interlace the 16 bit data into 2 bayer tile pattern images + dc1394_deinterlace_stereo( (unsigned char *)this->frame_buffer, + de_interleaved, + this->width, + 2*this->height); + + if(this->stereo_coding==RGB) + { + depth = (int)ceil((float)this->stereo_depth/8.0); + RGB_image=new unsigned char[this->width*this->height*depth]; + // extract color from the bayer tile image + // note: this will alias colors on the top and bottom rows + dc1394_bayer_decoding_8bit( de_interleaved, + RGB_image, + this->width, + 2*this->height, + this->bayer_pattern, + DC1394_BAYER_METHOD_NEAREST); + + *left = new char[this->width*this->height*depth]; + *right = new char[this->width*this->height*depth]; + memcpy(*left,RGB_image,this->width*this->height*depth); + memcpy(*right,RGB_image+this->width*this->height*depth,this->width*this->height*depth); + delete[] RGB_image; + } + else + { + depth = (int)ceil((float)this->depth/8.0); + *left = new char[this->width*this->height*depth]; + *right = new char[this->width*this->height*depth]; + memcpy(*left,de_interleaved,this->width*this->height*depth); + memcpy(*right,de_interleaved+this->height*this->width*depth,this->width*this->height*depth); + } + this->image_access.exit(); + delete[] de_interleaved; + } +} + +void CBumblebee::save_stereo_image(std::string &filename,char *left, char *right) +{ + std::string header,name; + std::stringstream text; + int file_left,file_right,depth=0; + unsigned int i=0; + + if(filename.size()==0) + { + DEBUG_INFO("Invalid filename for the image\n"); + /* handle the error */ + throw CFirewireCameraException(_HERE_,"Invalid filename for the image."); + } + name="left_" + filename; + file_left = open(name.c_str(),O_RDWR | O_CREAT,S_IRWXU | S_IRWXG | S_IRWXO); + name="right_" + filename; + file_right = open(name.c_str(),O_RDWR | O_CREAT,S_IRWXU | S_IRWXG | S_IRWXO); + if ( this->stereo_coding == RGB || this->stereo_coding == YUV ) + { + header="P6\n"; + text << this->width; + header+=text.str(); + text.str(""); + text << this->height; + header+=" "; + header+=text.str(); + header+='\n'; + if ( this->depth == DEPTH48 ) + header+="65535\n"; + else + header+="255\n"; + } + else + { + header="P5\n"; + text << this->width; + header+=text.str(); + text.str(""); + text << this->height; + header+=" "; + header+=text.str(); + header+='\n'; + if ( this->depth == DEPTH16 ) + header+="65535\n"; + else + header+="255\n"; + } + depth = (int)ceil((float)this->stereo_depth/8.0); + write(file_left,header.c_str(),header.size()); + write(file_right,header.c_str(),header.size()); + for( i = 0 ; i < this->height ; i++ ) + { + write(file_left,&left[i*this->width*depth],this->width*depth); + write(file_right,&right[i*this->width*depth],this->width*depth); + } + close(file_left); + close(file_right); +} + +CBumblebee::~CBumblebee() +{ + this->stereo_depth=(depths_t)-1; + this->stereo_coding=(codings_t)-1; +} diff --git a/src/bumblebee.h b/src/bumblebee.h new file mode 100755 index 0000000000000000000000000000000000000000..d3663daa958fc5c32e8785813398f8e958434f91 --- /dev/null +++ b/src/bumblebee.h @@ -0,0 +1,58 @@ +#ifndef _BUMBLEBEE_H +#define _BUMBLEBEE_H + +#include "ptg_camera.h" + +/** + * \brief + * + */ +class CBumblebee : public CPTGCamera +{ + protected: + // stereo attributes + /** + * \brief + * + */ + depths_t stereo_depth; + /** + * \brief + * + */ + codings_t stereo_coding; + public: + /** + * \brief + * + */ + CBumblebee(dc1394_t *firewire,uint64_t camera_id); + // configuration functions + /** + * \brief + * + */ + void set_config(unsigned int *left_off,unsigned int *top_off,unsigned int *width,unsigned int *height, float *framerate, depths_t depth, codings_t coding); + // stereo camera operation functions + /** + * \brief + * + */ + void get_stereo_image(char **left,char **right); + /** + * \brief + * + */ + void save_stereo_image(std::string &filename,char *left, char *right); + /** + * \brief + * + */ + ~CBumblebee(); + /** + * \brief + * + */ +}; + +#endif diff --git a/src/examples/CMakeLists.txt b/src/examples/CMakeLists.txt index 009621face698a326ea50139348977da697dec02..9912e94cb4022ff0ec6fbf01cf56e8f14173e61b 100644 --- a/src/examples/CMakeLists.txt +++ b/src/examples/CMakeLists.txt @@ -25,6 +25,16 @@ ADD_EXECUTABLE(bumblebee bumblebee.cpp) # edit the following line to add the necessary libraries TARGET_LINK_LIBRARIES(bumblebee ${iriutils_LIBRARY} ${raw1394_LIBRARY} ${dc1394_LIBRARY} firewire pthread) +# edit the following line to add the source code for the example and the name of the executable +ADD_EXECUTABLE(ptg_camera ptg_camera.cpp) +# edit the following line to add the necessary libraries +TARGET_LINK_LIBRARIES(ptg_camera ${iriutils_LIBRARY} ${raw1394_LIBRARY} ${dc1394_LIBRARY} firewire pthread) + +# edit the following line to add the source code for the example and the name of the executable +ADD_EXECUTABLE(ladybug ladybug.cpp) +# edit the following line to add the necessary libraries +TARGET_LINK_LIBRARIES(ladybug ${iriutils_LIBRARY} ${raw1394_LIBRARY} ${dc1394_LIBRARY} firewire pthread) + if (USE_CV) # edit the following line to add the source code for the example and the name of the executable ADD_EXECUTABLE(firewire_cont_CV firewire_camera_cont_CV.cpp) diff --git a/src/examples/bumblebee.cpp b/src/examples/bumblebee.cpp index 633d53ad581e4c488af2195cb1b1ee49ee8f845a..afe0d15e8c68aa8d7f7bf93d58556be27351b3a1 100755 --- a/src/examples/bumblebee.cpp +++ b/src/examples/bumblebee.cpp @@ -1,5 +1,5 @@ #include "firewireserver.h" -#include "pgr_stereo_camera.h" +#include "bumblebee.h" #include "firewireexceptions.h" #include "eventserver.h" #include <sys/time.h> @@ -14,7 +14,7 @@ int main(int argc, char *argv[]) CFirewireServer *server; CEventServer *event_server; timeval start_time,end_time; - CPGRStereoCamera *camera1=NULL; + CBumblebee *bumblebee=NULL; long elapsed_time[num_frames]; unsigned int left_off,top_off,width,height; float framerate; @@ -24,7 +24,8 @@ int main(int argc, char *argv[]) char *left=NULL,*right=NULL; std::string new_frame,filename; std::stringstream text; - uint64_t guid=0x00B09D01007D6D85LL; + uint64_t guid=0x0000b09d01006b6fb5; +// uint64_t guid=0x00B09D01007D6D85LL; std::list<std::string> events; try @@ -36,25 +37,26 @@ int main(int argc, char *argv[]) std::cout << "Num. Cam. : " << server->get_num_cameras() << std::endl; /* get the new camera with index 0 */ /* get the new camera with guid = 0x00B09D01007D6D85 */ - server->get_pgr_stereo_camera_guid(guid,&camera1); +// server->get_pgr_stereo_camera_guid(guid,&camera1); + server->get_bumblebee_camera(0,&bumblebee); /* get the reference to the event server */ event_server=CEventServer::instance(); - camera1->get_config(&left_off,&top_off,&width,&height,&framerate,&depth,&coding); + bumblebee->get_config(&left_off,&top_off,&width,&height,&framerate,&depth,&coding); std::cout << "Fremerate: " << framerate << std::endl; - camera1->get_new_frame_event_id(new_frame); + bumblebee->get_new_frame_event_id(new_frame); events.push_back(new_frame); - camera1->start(); + bumblebee->start(); for ( i=0 ; i<num_frames ; i++ ) { text.str(""); gettimeofday(&start_time,NULL); event_server->wait_all(events,0); - camera1->get_stereo_image(&left,&right); + bumblebee->get_stereo_image(&left,&right); filename="image_"; text << i; filename+=text.str(); filename+=".ppm"; - camera1->save_stereo_image(filename,left,right); + bumblebee->save_stereo_image(filename,left,right); if(left!=NULL) { delete[] left; @@ -69,8 +71,8 @@ int main(int argc, char *argv[]) elapsed_time[i]=(end_time.tv_sec-start_time.tv_sec)*1000000+end_time.tv_usec-start_time.tv_usec; std::cout << "Elapsed time: " << elapsed_time[i] << "s" << std::endl; } - camera1->stop(); - delete camera1; + bumblebee->stop(); + delete bumblebee; server->close(); } catch(CException& e) diff --git a/src/examples/firewire_camera_cont.cpp b/src/examples/firewire_camera_cont.cpp index 82d0d236a14364de55b6e8f3f7757f5d572ff07c..47c58cbff807abc4dd2be9a15eba59b6b9927d93 100644 --- a/src/examples/firewire_camera_cont.cpp +++ b/src/examples/firewire_camera_cont.cpp @@ -7,7 +7,7 @@ #include <string> #include <sstream> -const int num_frames=1000; +const int num_frames=10; int main(int argc, char *argv[]) { @@ -22,7 +22,7 @@ int main(int argc, char *argv[]) codings_t coding; int i=0; std::list<std::string> event_list; - float framerate=15; + float framerate=30; char *image=NULL; std::string new_frame,filename; std::stringstream text; @@ -45,7 +45,10 @@ int main(int argc, char *argv[]) event_list.push_back(new_frame); /* configure the camera */ camera1->get_config(&left_off,&top_off,&width,&height,&framerate,&depth,&coding); + framerate=3.75; + height=4608; camera1->set_config(&left_off,&top_off,&width,&height,&framerate,depth,coding); + std::cout << framerate << std::endl; /* start continuous acquisition */ camera1->start(); for ( i=0 ; i<num_frames ; i++ ) diff --git a/src/examples/ladybug.cpp b/src/examples/ladybug.cpp new file mode 100755 index 0000000000000000000000000000000000000000..7f4d202410d5f2691e9a1d94001d6d67d89e97f8 --- /dev/null +++ b/src/examples/ladybug.cpp @@ -0,0 +1,104 @@ +#include "firewireserver.h" +#include "ladybug.h" +#include "firewireexceptions.h" +#include "eventserver.h" +#include <sys/time.h> +#include <string> +#include <sstream> +#include <iostream> + +const int num_frames=1; + +int main(int argc, char *argv[]) +{ + CFirewireServer *server; + CEventServer *event_server; + timeval start_time,end_time; + CLadyBug *ladybug=NULL; + long elapsed_time[num_frames]; + unsigned int left_off,top_off,width,height; + float framerate; + codings_t coding; + depths_t depth; + int i=0; + char *front=NULL,*front_right=NULL,*rear_right=NULL,*rear_left=NULL,*front_left=NULL,*top=NULL; + std::string new_frame,filename; + std::stringstream text; + uint64_t guid=0x0000b09d01006b6fb5; +// uint64_t guid=0x00B09D01007D6D85LL; + std::list<std::string> events; + + try + { + /* get the reference to the firewire camera server */ + server=CFirewireServer::instance(); + /* initialize the camera server */ + server->init(); + std::cout << "Num. Cam. : " << server->get_num_cameras() << std::endl; + /* get the new camera with index 0 */ + /* get the new camera with guid = 0x00B09D01007D6D85 */ +// server->get_pgr_stereo_camera_guid(guid,&camera1); + server->get_ladybug_camera(0,&ladybug); + /* get the reference to the event server */ + event_server=CEventServer::instance(); + ladybug->get_config(&left_off,&top_off,&width,&height,&framerate,&depth,&coding); + std::cout << "Fremerate: " << framerate << std::endl; + coding=MONO; + ladybug->set_config(&left_off,&top_off,&width,&height,&framerate,depth,coding); + ladybug->get_new_frame_event_id(new_frame); + events.push_back(new_frame); + ladybug->start(); + for ( i=0 ; i<num_frames ; i++ ) + { + text.str(""); + gettimeofday(&start_time,NULL); + event_server->wait_all(events,0); + ladybug->get_images(&front,&front_right,&rear_right,&rear_left,&front_left,&top); + filename="image_"; + text << i; + filename+=text.str(); + filename+=".ppm"; + ladybug->save_images(filename,front,front_right,rear_right,rear_left,front_left,top); + if(front!=NULL) + { + delete[] front; + front=NULL; + } + if(front_right!=NULL) + { + delete[] front_right; + front_right=NULL; + } + if(rear_right!=NULL) + { + delete[] rear_right; + rear_right=NULL; + } + if(rear_left!=NULL) + { + delete[] rear_left; + rear_left=NULL; + } + if(front_left!=NULL) + { + delete[] front_left; + front_left=NULL; + } + if(top!=NULL) + { + delete[] top; + top=NULL; + } + gettimeofday(&end_time,NULL); + elapsed_time[i]=(end_time.tv_sec-start_time.tv_sec)*1000000+end_time.tv_usec-start_time.tv_usec; + std::cout << "Elapsed time: " << elapsed_time[i] << "s" << std::endl; + } + ladybug->stop(); + delete ladybug; + server->close(); + } + catch(CException& e) + { + std::cout << e.what() << std::endl; + } +} diff --git a/src/examples/ptg_camera.cpp b/src/examples/ptg_camera.cpp new file mode 100755 index 0000000000000000000000000000000000000000..d4a946cd29a6286a0b71ba3cc9daf9016913e3ff --- /dev/null +++ b/src/examples/ptg_camera.cpp @@ -0,0 +1,84 @@ +#include "firewireserver.h" +#include "ptg_camera.h" +#include "firewireexceptions.h" +#include "eventserver.h" +#include <sys/time.h> +#include <string> +#include <sstream> +#include <iostream> + +const int num_frames=1; + +int main(int argc, char *argv[]) +{ + CFirewireServer *server; + CEventServer *event_server; + timeval start_time,end_time; + CPTGCamera *camera=NULL; + long elapsed_time[num_frames]; + unsigned int left_off,top_off,width,height; + float framerate; + codings_t coding; + depths_t depth; + int i=0; + char *image=NULL; + std::string new_frame,filename; + std::stringstream text; + uint64_t guid=0x0000b09d01006b6fb5; +// uint64_t guid=0x00B09D01007D6D85LL; + std::list<std::string> events; + + try + { + /* get the reference to the firewire camera server */ + server=CFirewireServer::instance(); + /* initialize the camera server */ + server->init(); + std::cout << "Num. Cam. : " << server->get_num_cameras() << std::endl; + /* get the new camera with index 0 */ +// server->get_pgr_stereo_camera_guid(guid,&camera1); + server->get_ptg_camera(0,&camera); + /* get the reference to the event server */ + event_server=CEventServer::instance(); + /* configure the camera */ + camera->set_ISO_speed(800); + camera->get_config(&left_off,&top_off,&width,&height,&framerate,&depth,&coding); + framerate=30; + coding=MONO; + depth=DEPTH8; + /* select the left or right camera */ + camera->select_sensor(5);//left + camera->set_config(&left_off,&top_off,&width,&height,&framerate,depth,coding); + std::cout << "Fremerate: " << framerate << std::endl; + camera->get_new_frame_event_id(new_frame); + events.push_back(new_frame); + camera->start(); + for ( i=0 ; i<num_frames ; i++ ) + { + text.str(""); + gettimeofday(&start_time,NULL); + event_server->wait_all(events,0); + camera->get_image(&image); + filename="image_"; + text << i; + filename+=text.str(); + filename+=".ppm"; + camera->save_image(filename,image); + if(image!=NULL) + { + delete[] image; + image=NULL; + } + gettimeofday(&end_time,NULL); + elapsed_time[i]=(end_time.tv_sec-start_time.tv_sec)*1000000+end_time.tv_usec-start_time.tv_usec; + std::cout << "Elapsed time: " << elapsed_time[i] << "s" << std::endl; + } + camera->stop(); + delete camera; + server->close(); + } + catch(CException& e) + { + std::cout << e.what() << std::endl; + } +} diff --git a/src/firewireserver.cpp b/src/firewireserver.cpp index ac9db77074c9a694c46f44ec1196e7f8661e8d85..0a3909aaac4ddecd943240320ba03bc094a3dff8 100644 --- a/src/firewireserver.cpp +++ b/src/firewireserver.cpp @@ -1,6 +1,5 @@ #include "firewireserver.h" #include "firewirecamera.h" -#include "pgr_stereo_camera.h" #include <iostream> void DEBUG_INFO(const char *string,int param1, int param2) @@ -164,7 +163,7 @@ void CFirewireServer::get_camera_guid(uint64_t uid,CFirewireCamera **camera) throw CFirewireCameraException(_HERE_,"No connected camera has the desired identifier"); } -void CFirewireServer::get_pgr_stereo_camera(int id,CPGRStereoCamera **camera) +void CFirewireServer::get_ptg_camera(int id,CPTGCamera **camera) { if ( *camera != NULL ) { @@ -185,11 +184,11 @@ void CFirewireServer::get_pgr_stereo_camera(int id,CPGRStereoCamera **camera) /* handle the error */ throw CFirewireCameraException(_HERE_,"The desired camera is already in use."); } - *camera = new CPGRStereoCamera(this->dc1394_handle,this->camera_list->ids[id].guid); + *camera = new CPTGCamera(this->dc1394_handle,this->camera_list->ids[id].guid); this->active_cameras[id]=true; } -void CFirewireServer::get_pgr_stereo_camera_guid(uint64_t uid,CPGRStereoCamera **camera) +void CFirewireServer::get_ptg_camera_guid(uint64_t uid,CPTGCamera **camera) { int i=0; @@ -212,7 +211,125 @@ void CFirewireServer::get_pgr_stereo_camera_guid(uint64_t uid,CPGRStereoCamera * } else { - (*camera) = new CPGRStereoCamera(this->dc1394_handle,uid); + *camera = new CPTGCamera(this->dc1394_handle,uid); + this->active_cameras[i]=true; + return; + } + } + } + DEBUG_INFO("No camera present with the given identifier: %d\n",uid); + /* handle the error */ + throw CFirewireCameraException(_HERE_,"No connected camera has the desired identifier"); +} + +void CFirewireServer::get_bumblebee_camera(int id,CBumblebee **camera) +{ + if ( *camera != NULL ) + { + DEBUG_INFO("Camera already initialized.\n"); + /* handle the error */ + throw CFirewireCameraException(_HERE_,"The camera object has already been created. Please supply an unitialized CFirewireCamera object."); + } + DEBUG_INFO("Creating a new firewire camera with index %d\n",id); + if ( id < 0 || id >= this->num_cameras ) + { + DEBUG_INFO("Invalid camera index %d\n",id); + /* handle the error */ + throw CFirewireCameraException(_HERE_,"The supplied camera index is outside the valid range. Check the number of available cameras first."); + } + if(this->active_cameras[id]==true) + { + DEBUG_INFO("The camera %d is already in use.\n",id); + /* handle the error */ + throw CFirewireCameraException(_HERE_,"The desired camera is already in use."); + } + *camera = new CBumblebee(this->dc1394_handle,this->camera_list->ids[id].guid); + this->active_cameras[id]=true; +} + +void CFirewireServer::get_bumblebee_camera_guid(uint64_t uid,CBumblebee **camera) +{ + int i=0; + + if ( *camera != NULL ) + { + DEBUG_INFO("Camera already initialized.\n"); + /* handle the error */ + throw CFirewireCameraException(_HERE_,"The camera object has already been created. Please supply an unitialized CFirewireCamera object."); + } + DEBUG_INFO("Creating a new firewire camera with identifier %d\n",uid); + for(i = 0; i < this->num_cameras ; i++) + { + if(this->camera_list->ids[i].guid==uid) + { + if(this->active_cameras[i]==true) + { + DEBUG_INFO("The camera with guid %d is already in use.\n",uid); + /* handle the error */ + throw CFirewireCameraException(_HERE_,"The desired camera is already in use."); + } + else + { + (*camera) = new CBumblebee(this->dc1394_handle,uid); + this->active_cameras[i]=true; + return; + } + } + } + DEBUG_INFO("No camera present with the given identifier: %d\n",uid); + /* handle the error */ + throw CFirewireCameraException(_HERE_,"No connected camera has the desired identifier"); +} + +void CFirewireServer::get_ladybug_camera(int id,CLadyBug **camera) +{ + if ( *camera != NULL ) + { + DEBUG_INFO("Camera already initialized.\n"); + /* handle the error */ + throw CFirewireCameraException(_HERE_,"The camera object has already been created. Please supply an unitialized CFirewireCamera object."); + } + DEBUG_INFO("Creating a new firewire camera with index %d\n",id); + if ( id < 0 || id >= this->num_cameras ) + { + DEBUG_INFO("Invalid camera index %d\n",id); + /* handle the error */ + throw CFirewireCameraException(_HERE_,"The supplied camera index is outside the valid range. Check the number of available cameras first."); + } + if(this->active_cameras[id]==true) + { + DEBUG_INFO("The camera %d is already in use.\n",id); + /* handle the error */ + throw CFirewireCameraException(_HERE_,"The desired camera is already in use."); + } + *camera = new CLadyBug(this->dc1394_handle,this->camera_list->ids[id].guid); + this->active_cameras[id]=true; +} + +void CFirewireServer::get_ladybug_camera_guid(uint64_t uid,CLadyBug **camera) +{ + int i=0; + + if ( *camera != NULL ) + { + DEBUG_INFO("Camera already initialized.\n"); + /* handle the error */ + throw CFirewireCameraException(_HERE_,"The camera object has already been created. Please supply an unitialized CFirewireCamera object."); + } + DEBUG_INFO("Creating a new firewire camera with identifier %d\n",uid); + for(i = 0; i < this->num_cameras ; i++) + { + if(this->camera_list->ids[i].guid==uid) + { + if(this->active_cameras[i]==true) + { + DEBUG_INFO("The camera with guid %d is already in use.\n",uid); + /* handle the error */ + throw CFirewireCameraException(_HERE_,"The desired camera is already in use."); + } + else + { + (*camera) = new CLadyBug(this->dc1394_handle,uid); this->active_cameras[i]=true; return; } diff --git a/src/firewireserver.h b/src/firewireserver.h index 12662c15b06995c00da84385ade0c2bf79437e06..a0d0f2d9c1dcb8fa2ed695c645e52adbab8bc147 100644 --- a/src/firewireserver.h +++ b/src/firewireserver.h @@ -4,7 +4,9 @@ #include <dc1394/dc1394.h> #include "firewireexceptions.h" #include "firewirecamera.h" -#include "pgr_stereo_camera.h" +#include "ptg_camera.h" +#include "bumblebee.h" +#include "ladybug.h" /** * \brief Firewire camera server @@ -259,13 +261,38 @@ class CFirewireServer * * */ - void get_pgr_stereo_camera(int id, CPGRStereoCamera **camera); + void get_ptg_camera(int id, CPTGCamera **camera); /** * \brief * * */ - void get_pgr_stereo_camera_guid(uint64_t uid, CPGRStereoCamera **camera); + void get_ptg_camera_guid(uint64_t uid, CPTGCamera **camera); + /** + * \brief + * + * + */ + void get_bumblebee_camera(int id, CBumblebee **camera); + /** + * \brief + * + * + */ + void get_bumblebee_camera_guid(uint64_t uid, CBumblebee **camera); + /** + * \brief + * + * + */ + void get_ladybug_camera(int id, CLadyBug **camera); + /** + * \brief + * + * + */ + void get_ladybug_camera_guid(uint64_t uid, CLadyBug **camera); + /** * \brief Function to free a camera * diff --git a/src/ladybug.cpp b/src/ladybug.cpp new file mode 100755 index 0000000000000000000000000000000000000000..8bc0eadc39a0fff734adfe030bb738a7a84a9e98 --- /dev/null +++ b/src/ladybug.cpp @@ -0,0 +1,271 @@ +#include "ladybug.h" +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <fcntl.h> +#include <math.h> + +CLadyBug::CLadyBug(dc1394_t *firewire,uint64_t camera_id):CPTGCamera(firewire,camera_id) +{ + unsigned int left_off=0,top_off=0,rows=4608,cols=1024; + float framerate=3.75; + dc1394error_t error; + + if(strncmp(this->camera_handle->model,"Compressor",strlen("Compressor"))!=0) + { + /* handle exceptions */ + throw CFirewireCameraException(_HERE_,"The camera is not a Ladybug2"); + } + this->set_ISO_speed(800); + // configure the camera by default + this->multi_depth=DEPTH24; + this->multi_coding=RGB; + this->multi_width=1024; + this->multi_height=768; + error=dc1394_set_control_register(this->camera_handle,0x1E88,0xFFFFFF); + if(error!=DC1394_SUCCESS) + { + /* handle exceptions */ + throw CFirewireInternalException(_HERE_,error); + } + CPTGCamera::set_config(&left_off,&top_off,&cols,&rows,&framerate,DEPTH8,MONO); + this->get_bayer_pattern(&this->bayer_pattern); +} + +void CLadyBug::set_config(unsigned int *left_off,unsigned int *top_off,unsigned int *width,unsigned int *height, float *framerate, depths_t depth, codings_t coding) +{ + /* do nothing, just avoid the base class function to be called */ + if(coding==RGB || coding==MONO) + this->multi_coding=coding; + else + { + /* handle exceptions */ + } +} + +void CLadyBug::get_images(char **front, char **front_right, char **rear_right, char **rear_left, char **front_left, char **top) +{ + int depth; + dc1394error_t error; + dc1394video_frame_t *frame; + unsigned char *RGB_image; + + if ( *front != NULL || *front_right != NULL || *rear_right != NULL || *rear_left != NULL || *front_left != NULL || *top != NULL) + { + DEBUG_INFO("Invalid image buffer.\n"); + /* handle error */ + throw CFirewireCameraException(_HERE_,"Invalid image buffer. Please provide an unallocated memory buffer."); + } + DEBUG_INFO("Capturing a new image ... "); + if ( this->one_shot_mode == DC1394_ON ) + { + /* set the one shot mode */ + DEBUG_INFO("Setting the one shot mode ... "); + error = dc1394_video_set_one_shot(this->camera_handle,DC1394_ON); + if ( error != DC1394_SUCCESS ) + { + DEBUG_INFO("failed\n"); + /* handle the error */ + throw CFirewireInternalException(_HERE_,error); + } + DEBUG_INFO("ok\n"); + DEBUG_INFO("Dequeuing a DMA buffer ... "); + error = dc1394_capture_dequeue(this->camera_handle,DC1394_CAPTURE_POLICY_WAIT,&frame); + if ( error != DC1394_SUCCESS ) + { + DEBUG_INFO("failed\n"); + /* handle error */ + throw CFirewireInternalException(_HERE_,error); + } + if(this->multi_coding==RGB) + { + depth = (int)ceil((float)this->multi_depth/8.0); + RGB_image=new unsigned char[this->width*this->height*depth]; + // extract color from the bayer tile image + // note: this will alias colors on the top and bottom rows + dc1394_bayer_decoding_8bit( (unsigned char *)frame->image, + RGB_image, + this->width, + this->height, + this->bayer_pattern, + DC1394_BAYER_METHOD_NEAREST); + + *front = new char[this->multi_width*this->multi_height*depth]; + *front_right = new char[this->multi_width*this->multi_height*depth]; + *rear_right = new char[this->multi_width*this->multi_height*depth]; + *rear_left = new char[this->multi_width*this->multi_height*depth]; + *front_left = new char[this->multi_width*this->multi_height*depth]; + *top = new char[this->multi_width*this->multi_height*this->depth]; + memcpy(*front,RGB_image,this->multi_width*this->multi_height*depth); + memcpy(*front_right,RGB_image+this->multi_height*this->multi_width*depth,this->multi_width*this->multi_height*depth); + memcpy(*rear_right,RGB_image+2*(this->multi_height*this->multi_width*depth),this->multi_width*this->multi_height*depth); + memcpy(*rear_left,RGB_image+3*(this->multi_height*this->multi_width*depth),this->multi_width*this->multi_height*depth); + memcpy(*front_left,RGB_image+4*(this->multi_height*this->multi_width*depth),this->multi_width*this->multi_height*depth); + memcpy(*top,RGB_image+5*(this->multi_height*this->multi_width*depth),this->multi_width*this->multi_height*depth); + delete[] RGB_image; + } + else + { + depth = (int)ceil((float)this->depth/8.0); + *front = new char[this->width*this->height*depth]; + *front_right = new char[this->multi_width*this->multi_height*depth]; + *rear_right = new char[this->multi_width*this->multi_height*depth]; + *rear_left = new char[this->multi_width*this->multi_height*depth]; + *front_left = new char[this->multi_width*this->multi_height*depth]; + *top = new char[this->multi_width*this->multi_height*this->depth]; + memcpy(*front,(unsigned char *)frame->image,this->multi_width*this->multi_height*depth); + memcpy(*front_right,(unsigned char *)frame->image+this->multi_height*this->multi_width*depth,this->multi_width*this->multi_height*depth); + memcpy(*rear_right,(unsigned char *)frame->image+2*(this->multi_height*this->multi_width*depth),this->multi_width*this->multi_height*depth); + memcpy(*rear_left,(unsigned char *)frame->image+3*(this->multi_height*this->multi_width*depth),this->multi_width*this->multi_height*depth); + memcpy(*front_left,(unsigned char *)frame->image+4*(this->multi_height*this->multi_width*depth),this->multi_width*this->multi_height*depth); + memcpy(*top,(unsigned char *)frame->image+5*(this->multi_height*this->multi_width*depth),this->multi_width*this->multi_height*depth); + } + if(this->frame_buffer!=NULL) + delete[] this->frame_buffer; + depth = (int)ceil((float)this->depth/8.0); + this->frame_buffer = new char[this->width*this->height*depth]; + memcpy(this->frame_buffer,frame->image,this->width*this->height*this->depth/8.0); + DEBUG_INFO("ok\n"); + DEBUG_INFO("Freeing the DMA buffer ... "); + error = dc1394_capture_enqueue(this->camera_handle,frame); + if ( error != DC1394_SUCCESS ) + { + DEBUG_INFO("failed\n"); + /* handle error */ + throw CFirewireInternalException(_HERE_,error); + } + DEBUG_INFO("ok\n"); + } + else + { + this->image_access.enter(); + if(this->multi_coding==RGB) + { + depth = (int)ceil((float)this->multi_depth/8.0); + RGB_image=new unsigned char[this->width*this->height*depth]; + // extract color from the bayer tile image + // note: this will alias colors on the top and bottom rows + dc1394_bayer_decoding_8bit( (unsigned char *)this->frame_buffer, + RGB_image, + this->width, + this->height, + this->bayer_pattern, + DC1394_BAYER_METHOD_NEAREST); + + *front = new char[this->multi_width*this->multi_height*depth]; + *front_right = new char[this->multi_width*this->multi_height*depth]; + *rear_right = new char[this->multi_width*this->multi_height*depth]; + *rear_left = new char[this->multi_width*this->multi_height*depth]; + *front_left = new char[this->multi_width*this->multi_height*depth]; + *top = new char[this->multi_width*this->multi_height*this->depth]; + memcpy(*front,RGB_image,this->multi_width*this->multi_height*depth); + memcpy(*front_right,RGB_image+this->multi_height*this->multi_width*depth,this->multi_width*this->multi_height*depth); + memcpy(*rear_right,RGB_image+2*(this->multi_height*this->multi_width*depth),this->multi_width*this->multi_height*depth); + memcpy(*rear_left,RGB_image+3*(this->multi_height*this->multi_width*depth),this->multi_width*this->multi_height*depth); + memcpy(*front_left,RGB_image+4*(this->multi_height*this->multi_width*depth),this->multi_width*this->multi_height*depth); + memcpy(*top,RGB_image+5*(this->multi_height*this->multi_width*depth),this->multi_width*this->multi_height*depth); + delete[] RGB_image; + } + else + { + depth = (int)ceil((float)this->depth/8.0); + *front = new char[this->multi_width*this->multi_height*depth]; + *front_right = new char[this->multi_width*this->multi_height*depth]; + *rear_right = new char[this->multi_width*this->multi_height*depth]; + *rear_left = new char[this->multi_width*this->multi_height*depth]; + *front_left = new char[this->multi_width*this->multi_height*depth]; + *top = new char[this->multi_width*this->multi_height*this->depth]; + memcpy(*front,(unsigned char *)this->frame_buffer,this->multi_width*this->multi_height*depth); + memcpy(*front_right,(unsigned char *)this->frame_buffer+this->multi_height*this->multi_width*depth,this->multi_width*this->multi_height*depth); + memcpy(*rear_right,(unsigned char *)this->frame_buffer+2*(this->multi_height*this->multi_width*depth),this->multi_width*this->multi_height*depth); + memcpy(*rear_left,(unsigned char *)this->frame_buffer+3*(this->multi_height*this->multi_width*depth),this->multi_width*this->multi_height*depth); + memcpy(*front_left,(unsigned char *)this->frame_buffer+4*(this->multi_height*this->multi_width*depth),this->multi_width*this->multi_height*depth); + memcpy(*top,(unsigned char *)this->frame_buffer+5*(this->multi_height*this->multi_width*depth),this->multi_width*this->multi_height*depth); + } + this->image_access.exit(); + } +} + +void CLadyBug::save_images(std::string &filename,char *front, char *front_right, char *rear_right, char *rear_left, char *front_left, char *top) +{ + std::string header,name; + std::stringstream text; + int file_front,file_front_right,file_rear_right,file_rear_left,file_front_left,file_top,depth=0; + unsigned int i=0; + + if(filename.size()==0) + { + DEBUG_INFO("Invalid filename for the image\n"); + /* handle the error */ + throw CFirewireCameraException(_HERE_,"Invalid filename for the image."); + } + name="front_" + filename; + file_front = open(name.c_str(),O_RDWR | O_CREAT,S_IRWXU | S_IRWXG | S_IRWXO); + name="front_right_" + filename; + file_front_right = open(name.c_str(),O_RDWR | O_CREAT,S_IRWXU | S_IRWXG | S_IRWXO); + name="rear_right_" + filename; + file_rear_right = open(name.c_str(),O_RDWR | O_CREAT,S_IRWXU | S_IRWXG | S_IRWXO); + name="rear_left_" + filename; + file_rear_left = open(name.c_str(),O_RDWR | O_CREAT,S_IRWXU | S_IRWXG | S_IRWXO); + name="front_left_" + filename; + file_front_left = open(name.c_str(),O_RDWR | O_CREAT,S_IRWXU | S_IRWXG | S_IRWXO); + name="top_" + filename; + file_top = open(name.c_str(),O_RDWR | O_CREAT,S_IRWXU | S_IRWXG | S_IRWXO); + if ( this->multi_coding == RGB ) + { + header="P6\n"; + text << this->multi_width; + header+=text.str(); + text.str(""); + text << this->multi_height; + header+=" "; + header+=text.str(); + header+='\n'; + if ( this->multi_depth == DEPTH48 ) + header+="65535\n"; + else + header+="255\n"; + } + else + { + header="P5\n"; + text << this->multi_width; + header+=text.str(); + text.str(""); + text << this->multi_height; + header+=" "; + header+=text.str(); + header+='\n'; + if ( this->multi_depth == DEPTH16 ) + header+="65535\n"; + else + header+="255\n"; + } + depth = (int)ceil((float)this->multi_depth/8.0); + write(file_front,header.c_str(),header.size()); + write(file_front_right,header.c_str(),header.size()); + write(file_rear_right,header.c_str(),header.size()); + write(file_rear_left,header.c_str(),header.size()); + write(file_front_left,header.c_str(),header.size()); + write(file_top,header.c_str(),header.size()); + for( i = 0 ; i < this->multi_height ; i++ ) + { + write(file_front,&front[i*this->multi_width*depth],this->multi_width*depth); + write(file_front_right,&front_right[i*this->multi_width*depth],this->multi_width*depth); + write(file_rear_right,&rear_right[i*this->multi_width*depth],this->multi_width*depth); + write(file_rear_left,&rear_left[i*this->multi_width*depth],this->multi_width*depth); + write(file_front_left,&front_left[i*this->multi_width*depth],this->multi_width*depth); + write(file_top,&top[i*this->multi_width*depth],this->multi_width*depth); + } + close(file_front); + close(file_front_right); + close(file_rear_right); + close(file_rear_left); + close(file_front_left); + close(file_top); +} + +CLadyBug::~CLadyBug() +{ + +} diff --git a/src/ladybug.h b/src/ladybug.h new file mode 100755 index 0000000000000000000000000000000000000000..a81c4e1e495e48a27cdb3faffeb2187b8502f7d7 --- /dev/null +++ b/src/ladybug.h @@ -0,0 +1,57 @@ +#ifndef _LADYBUG_H +#define _LADYBUG_H + +#include "ptg_camera.h" + +class CLadyBug : public CPTGCamera +{ + protected: + /** + * \brief + * + */ + depths_t multi_depth; + /** + * \brief + * + */ + codings_t multi_coding; + /** + * \brief + * + */ + unsigned int multi_width; + /** + * \brief + * + */ + unsigned int multi_height; + public: + /** + * \brief + * + */ + CLadyBug(dc1394_t *firewire,uint64_t camera_id); + /** + * \brief + * + */ + void set_config(unsigned int *left_off,unsigned int *top_off,unsigned int *width,unsigned int *height, float *framerate, depths_t depth, codings_t coding); + /** + * \brief + * + */ + void get_images(char **front, char **front_right, char **rear_right, char **rear_left, char **front_left, char **top); + /** + * \brief + * + */ + void save_images(std::string &filename,char *front, char *front_right, char *rear_right, char *rear_left, char *front_left, char *top); + /** + * \brief + * + */ + ~CLadyBug(); +}; + +#endif diff --git a/src/pgr_stereo_camera.cpp b/src/pgr_stereo_camera.cpp deleted file mode 100755 index ff3ff571128ad6c518c062c589f0dd819c9e1d54..0000000000000000000000000000000000000000 --- a/src/pgr_stereo_camera.cpp +++ /dev/null @@ -1,437 +0,0 @@ -#include "pgr_stereo_camera.h" -#include <sys/types.h> -#include <sys/stat.h> -#include <string.h> -#include <fcntl.h> -#include <math.h> - -CPGRStereoCamera::CPGRStereoCamera(dc1394_t *firewire,uint64_t camera_id):CFirewireCamera(firewire,camera_id) -{ - this->bayer_pattern=(dc1394color_filter_t)-1; - this->stereo_depth=(depths_t)-1; - this->stereo_coding=(codings_t)-1; - this->stereo_framerate=0.0; - this->left_camera_enabled=true; - this->right_camera_enabled=true; - if(strncmp(this->camera_handle->model,"Bumblebee2",strlen("Bumblebee2"))!=0) - { - throw CFirewireCameraException(_HERE_,"The camera is not a bumblebee2"); - } - this->set_ISO_speed(400); - this->select_cameras(LEFT_CAM|RIGHT_CAM); -} - -// overloaded functions from the base class -void CPGRStereoCamera::set_config(unsigned int *left_off,unsigned int *top_off,unsigned int *width,unsigned int *height, float *framerate, depths_t depth, codings_t coding) -{ - uint64_t total_bytes; - dc1394color_coding_t dc1394_coding; - dc1394error_t error; - unsigned int bpp; - - if(this->left_camera_enabled && this->right_camera_enabled) - { - // set the operation mode - error=dc1394_video_set_mode(this->camera_handle,DC1394_VIDEO_MODE_FORMAT7_3); - if(error!=DC1394_SUCCESS) - { - /* handle exceptions */ - throw CFirewireInternalException(_HERE_,error); - } - this->mode=DC1394_VIDEO_MODE_FORMAT7_3; - // configure the camera - if(coding==MONO) - dc1394_coding=DC1394_COLOR_CODING_MONO16; - else - dc1394_coding=DC1394_COLOR_CODING_RAW16; - error=dc1394_format7_set_roi(this->camera_handle, - this->mode, - dc1394_coding, - DC1394_USE_MAX_AVAIL, - 0, - 0, - *width, - *height); - if(error!=DC1394_SUCCESS) - { - // handle exceptions - throw CFirewireInternalException(_HERE_,error); - } - this->left_offset=*left_off; - this->top_offset=*top_off; - this->width=*width; - this->height=*height; - this->coding=coding; - this->depth=depth; - // compute the actual framerate - error = dc1394_format7_get_total_bytes(this->camera_handle,this->mode,&total_bytes); - if ( error != DC1394_SUCCESS ) - { - DEBUG_INFO("failed.\n"); - /* handle the error */ - throw CFirewireInternalException(_HERE_,error); - } - error = dc1394_format7_get_packet_size(this->camera_handle,this->mode,&bpp); - if ( error != DC1394_SUCCESS ) - { - DEBUG_INFO("failed.\n"); - /* handle the error */ - throw CFirewireInternalException(_HERE_,error); - } - this->framerate=this->iso_rate*bpp*2/total_bytes; - this->set_num_DMA_buffers(4); - } - else - CFirewireCamera::set_config(left_off,top_off,width,height,framerate, depth, coding); -} - -void CPGRStereoCamera::get_sensor_info(bool *color,unsigned int *rows, unsigned int *cols) -{ - unsigned char sensor_info; - unsigned int value; - dc1394error_t error; - - // This register is an advanced PGR register called SENSOR_BOARD_INFO - error=dc1394_get_control_register(this->camera_handle,SENSOR_BOARD_INFO_REGISTER,&value); - if(error!=DC1394_SUCCESS) - { - /* handle exceptions */ - throw CFirewireInternalException(_HERE_,error); - } - sensor_info=value&0x0F; - - switch( sensor_info ) - { - default: - // unknown sensor! - throw CFirewireCameraException(_HERE_,"Illegal sensor board info detected"); - break; - case 0xA: // color 640x480 - *color=true; - *rows=480; - *cols=640; - break; - case 0xB: // mono 640x480 - *color=false; - *rows=480; - *cols=640; - break; - case 0xC: // color 1024x768 - *color=true; - *rows=768; - *cols=1024; - break; - case 0xD: // mono 1024x768 - *color=false; - *rows=768; - *cols=1024; - break; - case 0xE: // color 1280x960 - *color=true; - *rows=960; - *cols=1280; - break; - case 0xF: // mono 1280x960 - *color=false; - *rows=960; - *cols=1280; - break; - } -} - -// public functions -void CPGRStereoCamera::get_bayer_pattern(dc1394color_filter_t *pattern) -{ - unsigned int value; - dc1394error_t error; - - // query register 0x1040 - // This register is an advanced PGR register called BAYER_TILE_MAPPING - // For more information check the PGR IEEE-1394 Digital Camera Register Reference - error=dc1394_get_control_register(this->camera_handle,BAYER_TILE_MAPPING_REGISTER,&value); - if(error!=DC1394_SUCCESS) - { - /* handle exceptions */ - throw CFirewireInternalException(_HERE_,error); - } - // Ascii R = 52 G = 47 B = 42 Y = 59 - switch( value ) - { - default: - case 0x59595959: // YYYY - // no bayer - *pattern = (dc1394color_filter_t) 0; - break; - case 0x52474742: // RGGB - *pattern = DC1394_COLOR_FILTER_RGGB; - break; - case 0x47425247: // GBRG - *pattern = DC1394_COLOR_FILTER_GBRG; - break; - case 0x47524247: // GRBG - *pattern = DC1394_COLOR_FILTER_GRBG; - break; - case 0x42474752: // BGGR - *pattern = DC1394_COLOR_FILTER_BGGR; - break; - } -} - -void CPGRStereoCamera::select_cameras(unsigned char cameras) -{ - unsigned int left_off=0,top_off=0,rows,cols; - dc1394error_t error; - unsigned int value; - float framerate; - bool color; - - if(cameras&LEFT_CAM && cameras&RIGHT_CAM)// set the stereo system - { - this->left_camera_enabled=true; - this->right_camera_enabled=true; - // get the camera information - this->get_sensor_info(&color,&rows,&cols); - // configure the camera by default - if(color) - { - this->stereo_depth=DEPTH24; - this->stereo_coding=RGB; - } - else - { - this->stereo_depth=DEPTH8; - this->stereo_coding=MONO; - } - if(color) - this->set_config(&left_off,&top_off,&cols,&rows,&framerate,DEPTH16,RAW); - else - this->set_config(&left_off,&top_off,&cols,&rows,&framerate,DEPTH16,MONO); - this->get_bayer_pattern(&this->bayer_pattern); - } - else - { - this->set_config(&this->left_offset,&this->top_offset,&this->width,&this->height,&this->stereo_framerate,this->stereo_depth,this->stereo_coding); - if(cameras&LEFT_CAM) - { - this->left_camera_enabled=true; - this->right_camera_enabled=false; - value=2; - error=dc1394_set_control_register(this->camera_handle,PAN_REGISTER,value); - if(error!=DC1394_SUCCESS) - { - /* handle exceptions */ - throw CFirewireInternalException(_HERE_,error); - } - } - else - { - this->left_camera_enabled=false; - this->right_camera_enabled=true; - value=0; - error=dc1394_set_control_register(this->camera_handle,PAN_REGISTER,value); - if(error!=DC1394_SUCCESS) - { - /* handle exceptions */ - throw CFirewireInternalException(_HERE_,error); - } - } - } -} - -std::string CPGRStereoCamera::get_model(void) -{ - return this->camera_handle->model; -} - -void CPGRStereoCamera::get_stereo_image(char **left,char **right) -{ - int depth; - dc1394error_t error; - dc1394video_frame_t *frame; - unsigned char *de_interleaved,*RGB_image; - - if ( *left != NULL || *right != NULL) - { - DEBUG_INFO("Invalid image buffer.\n"); - /* handle error */ - throw CFirewireCameraException(_HERE_,"Invalid image buffer. Please provide an unallocated memory buffer."); - } - DEBUG_INFO("Capturing a new image ... "); - if ( this->one_shot_mode == DC1394_ON ) - { - /* set the one shot mode */ - DEBUG_INFO("Setting the one shot mode ... "); - error = dc1394_video_set_one_shot(this->camera_handle,DC1394_ON); - if ( error != DC1394_SUCCESS ) - { - DEBUG_INFO("failed\n"); - /* handle the error */ - throw CFirewireInternalException(_HERE_,error); - } - DEBUG_INFO("ok\n"); - DEBUG_INFO("Dequeuing a DMA buffer ... "); - error = dc1394_capture_dequeue(this->camera_handle,DC1394_CAPTURE_POLICY_WAIT,&frame); - if ( error != DC1394_SUCCESS ) - { - DEBUG_INFO("failed\n"); - /* handle error */ - throw CFirewireInternalException(_HERE_,error); - } - depth = (int)ceil((float)this->depth/8.0); - de_interleaved=new unsigned char[this->width*this->height*depth]; - // de-interlace the 16 bit data into 2 bayer tile pattern images - dc1394_deinterlace_stereo( (unsigned char *)frame->image, - de_interleaved, - this->width, - 2*this->height); - - if(this->stereo_coding==RGB) - { - RGB_image=new unsigned char[this->width*this->height*depth*3]; - // extract color from the bayer tile image - // note: this will alias colors on the top and bottom rows - dc1394_bayer_decoding_8bit( de_interleaved, - RGB_image, - this->width, - 2*this->height, - this->bayer_pattern, - DC1394_BAYER_METHOD_NEAREST); - - *left = new char[this->width*this->height*depth*this->stereo_depth/8]; - *right = new char[this->width*this->height*depth*this->stereo_depth/8]; - memcpy(*left,RGB_image,this->width*this->height*this->stereo_depth/8); - memcpy(*right,RGB_image+this->height*this->width*this->stereo_depth/8,this->width*this->height*this->stereo_depth/8); - delete[] RGB_image; - } - else - { - *left = new char[this->width*this->height*depth*this->stereo_depth/8]; - *right = new char[this->width*this->height*depth*this->stereo_depth/8]; - memcpy(*left,de_interleaved,this->width*this->height*this->stereo_depth/8); - memcpy(*right,de_interleaved+this->height*this->width*this->stereo_depth/8,this->width*this->height*this->stereo_depth/8); - } - if(this->frame_buffer!=NULL) - delete[] this->frame_buffer; - this->frame_buffer = new char[this->width*this->height*depth]; - memcpy(this->frame_buffer,frame->image,this->width*this->height*depth); - DEBUG_INFO("ok\n"); - DEBUG_INFO("Freeing the DMA buffer ... "); - error = dc1394_capture_enqueue(this->camera_handle,frame); - if ( error != DC1394_SUCCESS ) - { - DEBUG_INFO("failed\n"); - /* handle error */ - throw CFirewireInternalException(_HERE_,error); - } - DEBUG_INFO("ok\n"); - delete[] de_interleaved; - } - else - { - this->image_access.enter(); - depth = (int)ceil((float)this->depth/8.0); - de_interleaved=new unsigned char[this->width*this->height*depth]; - // de-interlace the 16 bit data into 2 bayer tile pattern images - dc1394_deinterlace_stereo( (unsigned char *)this->frame_buffer, - de_interleaved, - this->width, - 2*this->height); - - if(this->stereo_coding==RGB) - { - RGB_image=new unsigned char[this->width*this->height*depth*3]; - // extract color from the bayer tile image - // note: this will alias colors on the top and bottom rows - dc1394_bayer_decoding_8bit( de_interleaved, - RGB_image, - this->width, - 2*this->height, - this->bayer_pattern, - DC1394_BAYER_METHOD_NEAREST); - - *left = new char[this->width*this->height*depth*this->stereo_depth/8]; - *right = new char[this->width*this->height*depth*this->stereo_depth/8]; - memcpy(*left,RGB_image,this->width*this->height*this->stereo_depth/8); - memcpy(*right,RGB_image+this->width*this->height*this->stereo_depth/8,this->width*this->height*this->stereo_depth/8); - delete[] RGB_image; - } - else - { - *left = new char[this->width*this->height*depth*this->stereo_depth/8]; - *right = new char[this->width*this->height*depth*this->stereo_depth/8]; - memcpy(*left,de_interleaved,this->width*this->height*this->stereo_depth/8); - memcpy(*right,de_interleaved+this->height*this->width*this->stereo_depth/8,this->width*this->height*this->stereo_depth/8); - } - this->image_access.exit(); - delete[] de_interleaved; - } -} - -void CPGRStereoCamera::save_stereo_image(std::string &filename,char *left, char *right) -{ - std::string header,name; - std::stringstream text; - int file_left,file_right,depth=0; - unsigned int i=0; - - if(filename.size()==0) - { - DEBUG_INFO("Invalid filename for the image\n"); - /* handle the error */ - throw CFirewireCameraException(_HERE_,"Invalid filename for the image."); - } - name="left_" + filename; - file_left = open(name.c_str(),O_RDWR | O_CREAT,S_IRWXU | S_IRWXG | S_IRWXO); - name="right_" + filename; - file_right = open(name.c_str(),O_RDWR | O_CREAT,S_IRWXU | S_IRWXG | S_IRWXO); - if ( this->stereo_coding == RGB || this->stereo_coding == YUV ) - { - header="P6\n"; - text << this->width; - header+=text.str(); - text.str(""); - text << this->height; - header+=" "; - header+=text.str(); - header+='\n'; - if ( this->depth == DEPTH48 ) - header+="65535\n"; - else - header+="255\n"; - } - else - { - header="P5\n"; - text << this->width; - header+=text.str(); - text.str(""); - text << this->height; - header+=" "; - header+=text.str(); - header+='\n'; - if ( this->depth == DEPTH48 ) - header+="65535\n"; - else - header+="255\n"; - } - depth = (int)ceil((float)this->stereo_depth/8.0); - write(file_left,header.c_str(),header.size()); - write(file_right,header.c_str(),header.size()); - for( i = 0 ; i < this->height ; i++ ) - { - write(file_left,&left[i*this->width*depth],this->width*depth); - write(file_right,&right[i*this->width*depth],this->width*depth); - } - close(file_left); - close(file_right); -} - -CPGRStereoCamera::~CPGRStereoCamera() -{ - this->bayer_pattern=(dc1394color_filter_t)-1; - this->stereo_depth=(depths_t)-1; - this->stereo_coding=(codings_t)-1; - this->stereo_framerate=0.0; - this->left_camera_enabled=false; - this->right_camera_enabled=false; -} diff --git a/src/pgr_stereo_camera.h b/src/pgr_stereo_camera.h deleted file mode 100755 index 413ad615d095b7c2509c08f3e94286f476a7acac..0000000000000000000000000000000000000000 --- a/src/pgr_stereo_camera.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef _PGR_STEREO_CAMERA_H -#define _PGR_STEREO_CAMERA_H - -#include "firewirecamera.h" - -#define LEFT_CAM 0x01 -#define RIGHT_CAM 0x02 - -// Point grey specific registers -#define BAYER_TILE_MAPPING_REGISTER (0x1040) -#define SENSOR_BOARD_INFO_REGISTER (0x1f28) -#define IMAGE_DATA_FORMAT_REGISTER (0x1048) -#define PAN_REGISTER (0x0884) - -/** - * \brief - * - */ -class CPGRStereoCamera : public CFirewireCamera -{ - protected: - // stereo attributes - /** - * \brief - * - */ - dc1394color_filter_t bayer_pattern; - /** - * \brief - * - */ - depths_t stereo_depth; - /** - * \brief - * - */ - codings_t stereo_coding; - /** - * \brief - * - */ - float stereo_framerate; - /** - * \brief - * - */ - bool left_camera_enabled; - /** - * \brief - * - */ - bool right_camera_enabled; - // stereo functions - /** - * \brief - * - */ - void get_sensor_info(bool *color,unsigned int *rows, unsigned int *cols); - /** - * \brief - * - */ - void select_cameras(unsigned char cameras); - public: - /** - * \brief - * - */ - CPGRStereoCamera(dc1394_t *firewire,uint64_t camera_id); - // configuration functions - /** - * \brief - * - */ - void set_config(unsigned int *left_off,unsigned int *top_off,unsigned int *width,unsigned int *height, float *framerate, depths_t depth, codings_t coding); - /** - * \brief - * - */ - void get_bayer_pattern(dc1394color_filter_t *pattern); - /** - * \brief - * - */ - std::string get_model(void); - // stereo camera operation functions - /** - * \brief - * - */ - void get_stereo_image(char **left,char **right); - /** - * \brief - * - */ - void save_stereo_image(std::string &filename,char *left, char *right); - /** - * \brief - * - */ - ~CPGRStereoCamera(); - /** - * \brief - * - */ -}; - -#endif diff --git a/src/ptg_camera.cpp b/src/ptg_camera.cpp new file mode 100755 index 0000000000000000000000000000000000000000..bc15e119e8f47b8bb96695d23beedf88e0d00b05 --- /dev/null +++ b/src/ptg_camera.cpp @@ -0,0 +1,128 @@ +#include "ptg_camera.h" + +CPTGCamera::CPTGCamera(dc1394_t *firewire,uint64_t camera_id):CFirewireCamera(firewire,camera_id) +{ + this->bayer_pattern=(dc1394color_filter_t)-1; + this->selected_sensor=0; +} + +void CPTGCamera::get_sensor_info(bool *color,unsigned int *rows, unsigned int *cols) +{ + unsigned char sensor_info; + unsigned int value; + dc1394error_t error; + + // This register is an advanced PGR register called SENSOR_BOARD_INFO + error=dc1394_get_control_register(this->camera_handle,SENSOR_BOARD_INFO_REGISTER,&value); + if(error!=DC1394_SUCCESS) + { + /* handle exceptions */ + throw CFirewireInternalException(_HERE_,error); + } + sensor_info=value&0x0F; + + switch( sensor_info ) + { + default: + // unknown sensor! + throw CFirewireCameraException(_HERE_,"Illegal sensor board info detected"); + break; + case 0xA: // color 640x480 + *color=true; + *rows=480; + *cols=640; + break; + case 0xB: // mono 640x480 + *color=false; + *rows=480; + *cols=640; + break; + case 0xC: // color 1024x768 + *color=true; + *rows=768; + *cols=1024; + break; + case 0xD: // mono 1024x768 + *color=false; + *rows=768; + *cols=1024; + break; + case 0xE: // color 1280x960 + *color=true; + *rows=960; + *cols=1280; + break; + case 0xF: // mono 1280x960 + *color=false; + *rows=960; + *cols=1280; + break; + } +} + +void CPTGCamera::select_sensor(unsigned int sensor_id) +{ + dc1394error_t error; + + error=dc1394_set_control_register(this->camera_handle,PAN_REGISTER,sensor_id); + if(error!=DC1394_SUCCESS) + { + /* handle exceptions */ + throw CFirewireInternalException(_HERE_,error); + } + this->selected_sensor=sensor_id; +} + +unsigned int CPTGCamera::get_selected_sensor(void) +{ + return this->selected_sensor; +} + +void CPTGCamera::get_bayer_pattern(dc1394color_filter_t *pattern) +{ + unsigned int value; + dc1394error_t error; + + // query register 0x1040 + // This register is an advanced PGR register called BAYER_TILE_MAPPING + // For more information check the PGR IEEE-1394 Digital Camera Register Reference + error=dc1394_get_control_register(this->camera_handle,BAYER_TILE_MAPPING_REGISTER,&value); + if(error!=DC1394_SUCCESS) + { + /* handle exceptions */ + throw CFirewireInternalException(_HERE_,error); + } + // Ascii R = 52 G = 47 B = 42 Y = 59 + switch( value ) + { + default: + case 0x59595959: // YYYY + // no bayer + *pattern = (dc1394color_filter_t) 0; + break; + case 0x52474742: // RGGB + *pattern = DC1394_COLOR_FILTER_RGGB; + break; + case 0x47425247: // GBRG + *pattern = DC1394_COLOR_FILTER_GBRG; + break; + case 0x47524247: // GRBG + *pattern = DC1394_COLOR_FILTER_GRBG; + break; + case 0x42474752: // BGGR + *pattern = DC1394_COLOR_FILTER_BGGR; + break; + } +} + +std::string CPTGCamera::get_model(void) +{ + return this->camera_handle->model; +} + +CPTGCamera::~CPTGCamera() +{ + this->bayer_pattern=(dc1394color_filter_t)-1; + this->selected_sensor=0; +} + diff --git a/src/ptg_camera.h b/src/ptg_camera.h new file mode 100755 index 0000000000000000000000000000000000000000..3e7ddfc402a3f68164824aa037050be88cff57a6 --- /dev/null +++ b/src/ptg_camera.h @@ -0,0 +1,63 @@ +#ifndef _PTG_CAMERA_H +#define _PTG_CAMERA_H + +#include "firewirecamera.h" + +// Point grey specific registers +#define BAYER_TILE_MAPPING_REGISTER (0x1040) +#define SENSOR_BOARD_INFO_REGISTER (0x1f28) +#define IMAGE_DATA_FORMAT_REGISTER (0x1048) +#define PAN_REGISTER (0x0884) + +class CPTGCamera : public CFirewireCamera +{ + protected: + /** + * \brief + * + */ + dc1394color_filter_t bayer_pattern; + /** + * \brief + * + */ + unsigned int selected_sensor; + /** + * \brief + * + */ + void get_sensor_info(bool *color,unsigned int *rows, unsigned int *cols); + public: + /** + * \brief + * + */ + CPTGCamera(dc1394_t *firewire,uint64_t camera_id); + /** + * \brief + * + */ + void select_sensor(unsigned int sensor_id); + /** + * \brief + * + */ + unsigned int get_selected_sensor(void); + /** + * \brief + * + */ + void get_bayer_pattern(dc1394color_filter_t *pattern); + /** + * \brief + * + */ + std::string get_model(void); + /** + * \brief + * + */ + ~CPTGCamera(); +}; + +#endif