/********************************************************************* // created: 2013/10/25 - 19:36 // filename: DisparityMapComponent.cpp // // author: Danilo Alves de Lima and Students of SY27 // Copyright Heudiasyc UMR UTC/CNRS 6599 // // version: $Id: $ // // purpose: Disparity map calculation from stereo image data // // *********************************************************************/ #include "Flea3Component.h" #include #include #include #include #include "opencv2/objdetect/objdetect.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/calib3d/calib3d.hpp" #include "opencv2/core/core.hpp" #include #include // Includes, qt. #include #include "Pacpus/kernel/ComponentFactory.h" #include "Pacpus/kernel/DbiteException.h" #include "Pacpus/kernel/DbiteFileTypes.h" #include "Pacpus/kernel/Log.h" using namespace std; using namespace pacpus; DECLARE_STATIC_LOGGER("pacpus.base.Flea3Component"); // Construct the factory static ComponentFactory sFactory("Flea3Component"); const int kMaxFilepathLength = 512; // TODO: should be same for all images static const string Flea3MemoryName_img = "Flea3Image"; ////////////////////////////////////////////////////////////////////////// /// Constructor. Flea3Component::Flea3Component(QString name) : ComponentBase(name) { LOG_TRACE(Q_FUNC_INFO); //recording = 0; this->cam_serial = 0; // Camera serial to connect this->cam_FrameRate = FlyCapture2::FRAMERATE_7_5; // Frame rates in frames per second this->cam_video_mode = FlyCapture2::VIDEOMODE_FORMAT7; // DCAM video modes this->cam_mode = FlyCapture2::MODE_4; // Camera modes for DCAM formats as well as Format7 this->cam_PixelFormat = FlyCapture2::PIXEL_FORMAT_RAW8; // Pixel formats available for Format7 modes this->cam_ColorProcessingAlgorithm = FlyCapture2::NEAREST_NEIGHBOR; /** * Color processing algorithms. Please refer to our knowledge base at * article at http://www.ptgrey.com/support/kb/index.asp?a=4&q=33 for * complete details for each algorithm. */ this->cam_start_point_left = 0; // Image left point (for standard modes only) this->cam_start_point_top = 0; // Image top point (for standard modes only) this->cam_width = 2048; // Image width (for standard modes only) this->cam_height = 1080; // image height (for standard modes only) this->showdebug = false; // Show frame acquired if(this->cam_ColorProcessingAlgorithm == 1) this->cam_channels = 1; else this->cam_channels = 3; // Size of the image data sizeof(char)*width*height*channels this->mMaxImageOutputSize = sizeof(char)*this->cam_width*this->cam_height*this->cam_channels; // output data this->shmem_image = 0; // Shared memory control access to the image data } ////////////////////////////////////////////////////////////////////////// /// Destructor. Flea3Component::~Flea3Component() { LOG_TRACE(Q_FUNC_INFO); if(this->shmem_image) delete shmem_image; this->shmem_image = NULL; } ////////////////////////////////////////////////////////////////////////// /// Called by the ComponentManager to start the component void Flea3Component::startActivity() { LOG_TRACE(Q_FUNC_INFO); if( ((FlyCapture2::PixelFormat)this->cam_PixelFormat == FlyCapture2::PIXEL_FORMAT_MONO8)|| ((FlyCapture2::PixelFormat)this->cam_PixelFormat == FlyCapture2::PIXEL_FORMAT_MONO12)|| ((FlyCapture2::PixelFormat)this->cam_PixelFormat == FlyCapture2::PIXEL_FORMAT_MONO16) ) { this->cam_channels = 1; } else { if(this->cam_ColorProcessingAlgorithm == 1) { this->cam_channels = 1; } else { this->cam_channels = 3; } } // Create output files for recording if (this->isRecording()) { try { QString dbtFileName_ = this->mOutputDirectory.filePath(/*ComponentBase::componentName*/name() + ".dbt"); //std::cout << "Save file : " << dbtFileName_.toStdString() << std::endl; this->mDbtImage.open(dbtFileName_.toStdString(), WriteMode, FILE_IMAGE, kMaxFilepathLength); //this->mDbtImage.open(dbtFileName_.toStdString(), WriteMode, FILE_JPEG, kMaxFilepathLength); } catch (DbiteException & e) { cerr << "error opening dbt file: " << e.what() << endl; } } // Run thread /*ComponentBase::*/THREAD_ALIVE = true; start(); } ////////////////////////////////////////////////////////////////////////// /// Called by the ComponentManager to stop the component void Flea3Component::stopActivity() { LOG_TRACE(Q_FUNC_INFO); if(/*ComponentBase::*/THREAD_ALIVE) { // Stop thread /*ComponentBase::*/THREAD_ALIVE = false; while(is_running) { msleep(10); } } // Close DBT file if (this->isRecording()) { this->mDbtImage.close(); } LOG_INFO("stopped component '" << name() << "'"); } ////////////////////////////////////////////////////////////////////////// /// Called by the ComponentManager to pass the XML parameters to the /// component ComponentBase::COMPONENT_CONFIGURATION Flea3Component::configureComponent(XmlComponentConfig config) { LOG_TRACE(Q_FUNC_INFO); // Initialize with default values this->InitDefault(); if (config.getProperty("recording") != QString::null) setRecording(config.getProperty("recording").toInt()); if (config.getProperty("cam_serial") != QString::null) this->cam_serial = config.getProperty("cam_serial").toInt(); //---------------------------------------- Camera configuration -------------------------------------------- if (config.getProperty("auto_FrameRate") != QString::null) this->auto_FrameRate = (config.getProperty("auto_FrameRate") == "true" ? true : false); if (config.getProperty("cam_FrameRate") != QString::null) this->cam_FrameRate = config.getProperty("cam_FrameRate").toDouble(); if (config.getProperty("auto_Gain") != QString::null) this->auto_Gain = (config.getProperty("auto_Gain") == "true" ? true : false); if (config.getProperty("cam_Gain") != QString::null) this->cam_Gain = config.getProperty("cam_Gain").toDouble(); if (config.getProperty("auto_Exposure") != QString::null) this->auto_Exposure = (config.getProperty("auto_Exposure") == "true" ? true : false); if (config.getProperty("cam_Exposure") != QString::null) this->cam_Exposure = config.getProperty("cam_Exposure").toDouble(); if (config.getProperty("auto_Shutter") != QString::null) this->auto_Shutter = (config.getProperty("auto_Shutter") == "true" ? true : false); if (config.getProperty("cam_Shutter") != QString::null) this->cam_Shutter = config.getProperty("cam_Shutter").toDouble(); if (config.getProperty("auto_ExposurebyCode") != QString::null) this->auto_ExposurebyCode = (config.getProperty("auto_ExposurebyCode") == "true" ? true : false); if (config.getProperty("cam_ExposurebyCode_tshold") != QString::null) this->cam_ExposurebyCode_tshold = config.getProperty("cam_ExposurebyCode_tshold").toDouble(); //---------------------------------------------------------------------------------------------------------- if (config.getProperty("cam_video_mode") != QString::null) this->cam_video_mode = config.getProperty("cam_video_mode").toInt(); if (config.getProperty("cam_mode") != QString::null) this->cam_mode = config.getProperty("cam_mode").toInt(); if (config.getProperty("cam_PixelFormat") != QString::null) this->cam_PixelFormat = config.getProperty("cam_PixelFormat").toInt(); if (config.getProperty("cam_ColorProcessingAlgorithm") != QString::null) this->cam_ColorProcessingAlgorithm = config.getProperty("cam_ColorProcessingAlgorithm").toInt(); if (config.getProperty("cam_start_point_left") != QString::null) this->cam_start_point_left = config.getProperty("cam_start_point_left").toInt(); if (config.getProperty("cam_start_point_top") != QString::null) this->cam_start_point_top = config.getProperty("cam_start_point_top").toInt(); if (config.getProperty("cam_width") != QString::null) this->cam_width = config.getProperty("cam_width").toInt(); if (config.getProperty("cam_height") != QString::null) this->cam_height = config.getProperty("cam_height").toInt(); if (config.getProperty("image_compact") != QString::null) this->image_compact = config.getProperty("image_compact").toInt(); if (config.getProperty("showdebug") != QString::null) this->showdebug = (bool)config.getProperty("showdebug").toInt(); if (config.getProperty("outputdir") != QString::null) { if (this->isRecording()) { this->mOutputDirectory.mkdir(config.getProperty("outputdir")); this->mOutputDirectory.mkdir(config.getProperty("outputdir") + "/" + name()/*ComponentBase::componentName*/); this->mOutputDirectory.setPath(config.getProperty("outputdir")); } } else { if (this->isRecording()) { this->mOutputDirectory.mkdir(/*ComponentBase::componentName*/name()); this->mOutputDirectory.setPath(this->mOutputDirectory.currentPath()); } } LOG_INFO("configured component '" << name() << "'"); return ComponentBase::CONFIGURED_OK; } /** * Initialize default values */ void Flea3Component::InitDefault() { // Default //recording = 0; this->cam_serial = 0; // Camera index to connect // Camera configuration this->auto_FrameRate = false; // Set auto frame rate this->cam_FrameRate = 15.0; // Frame rates in frames per second = FlyCapture2::FRAMERATE_15 this->auto_Gain = false; // Set auto gain this->cam_Gain = 1.0; // Gain value in db this->auto_Exposure = true; // Set auto exposure this->cam_Exposure = 2.414; // Auto exposure in EV this->auto_Shutter = true; // Set auto shutter this->cam_Shutter = 66.639; // Shutter in miliseconds this->auto_ExposurebyCode = false; // Set auto exposure by pos processing method this->cam_ExposurebyCode_tshold = 20.0; // Pecentage of white pixels for threshold this->cam_video_mode = FlyCapture2::VIDEOMODE_FORMAT7; // DCAM video modes this->cam_mode = FlyCapture2::MODE_0; // Camera modes for DCAM formats as well as Format7 this->cam_PixelFormat = FlyCapture2::PIXEL_FORMAT_RAW8; // Pixel formats available for Format7 modes this->cam_ColorProcessingAlgorithm = FlyCapture2::NEAREST_NEIGHBOR; /** * Color processing algorithms. Please refer to our knowledge base at * article at http://www.ptgrey.com/support/kb/index.asp?a=4&q=33 for * complete details for each algorithm. */ this->cam_start_point_left = 0; // Image left point (for standard modes only) this->cam_start_point_top = 0; // Image top point (for standard modes only) this->cam_width = 4096; // Image width (for standard modes only) this->cam_height = 2160; // image height (for standard modes only) this->showdebug = false; // Show frame acquired if(this->cam_ColorProcessingAlgorithm == 1) this->cam_channels = 1; else this->cam_channels = 3; // Size of the image data sizeof(char)*width*height*channels this->mMaxImageOutputSize = sizeof(char)*this->cam_width*this->cam_height*this->cam_channels; this->image_compact = 0; // Don't compact the image data } // Thread loop void Flea3Component::run() { LOG_TRACE(Q_FUNC_INFO); this->is_running = true; //==================================== Camera initialization ================================================= // Check the number of cameras FlyCapture2::BusManager busMgr; unsigned int numCameras; FlyCapture2::Error error = busMgr.GetNumOfCameras(&numCameras); if (error != FlyCapture2::PGRERROR_OK) { LOG_ERROR( error.GetDescription() ); exit(0); } if ( numCameras < 1 ) { LOG_ERROR( "Insufficient number of cameras... exiting" ); exit(0); } // Get camera from serial (in this case first camera in the bus) FlyCapture2::PGRGuid guid; error = busMgr.GetCameraFromSerialNumber(this->cam_serial, &guid); if (error != FlyCapture2::PGRERROR_OK) { LOG_ERROR( error.GetDescription() ); exit(0); } FlyCapture2::Camera cam; // FlyCapture camera class // Connect to a camera error = cam.Connect(&guid); if (error != FlyCapture2::PGRERROR_OK) { LOG_ERROR( error.GetDescription() ); exit(0); } // Get the camera information FlyCapture2::CameraInfo camInfo; error = cam.GetCameraInfo(&camInfo); if (error != FlyCapture2::PGRERROR_OK) { LOG_ERROR( error.GetDescription() ); exit(0); } // Just for visualization printf( "\n*** CAMERA INFORMATION ***\n" "Serial number - %u\n" "Camera model - %s\n" "Camera vendor - %s\n" "Sensor - %s\n" "Resolution - %s\n" "Firmware version - %s\n" "Firmware build time - %s\n\n", camInfo.serialNumber, camInfo.modelName, camInfo.vendorName, camInfo.sensorInfo, camInfo.sensorResolution, camInfo.firmwareVersion, camInfo.firmwareBuildTime ); // Query for available Format 7 modes FlyCapture2::Format7Info fmt7Info; bool supported; fmt7Info.mode = (FlyCapture2::Mode)this->cam_mode; error = cam.GetFormat7Info( &fmt7Info, &supported ); if (error != FlyCapture2::PGRERROR_OK) { LOG_ERROR( error.GetDescription() ); exit(0); } if ( ((FlyCapture2::PixelFormat)this->cam_PixelFormat & fmt7Info.pixelFormatBitField) == 0 ) { // Pixel format not supported! LOG_ERROR("Pixel format is not supported\n"); exit(0); } // Configurate custom image FlyCapture2::Format7ImageSettings fmt7ImageSettings; fmt7ImageSettings.mode = (FlyCapture2::Mode)this->cam_mode; fmt7ImageSettings.offsetX = this->cam_start_point_left; fmt7ImageSettings.offsetY = this->cam_start_point_top; fmt7ImageSettings.width = this->cam_width; fmt7ImageSettings.height = this->cam_height; fmt7ImageSettings.pixelFormat = (FlyCapture2::PixelFormat)this->cam_PixelFormat; bool valid; FlyCapture2::Format7PacketInfo fmt7PacketInfo; // Validate the settings to make sure that they are valid error = cam.ValidateFormat7Settings( &fmt7ImageSettings, &valid, &fmt7PacketInfo ); if (error != FlyCapture2::PGRERROR_OK) { LOG_ERROR( error.GetDescription() ); exit(0); } if ( !valid ) { // Settings are not valid LOG_ERROR( "Format7 settings are not valid" ); exit(0); } // Set the settings to the camera error = cam.SetFormat7Configuration( &fmt7ImageSettings, fmt7PacketInfo.recommendedBytesPerPacket ); if (error != FlyCapture2::PGRERROR_OK) { LOG_ERROR( error.GetDescription() ); exit(0); } // Define the color algorithm FlyCapture2::Image::SetDefaultColorProcessing((FlyCapture2::ColorProcessingAlgorithm)this->cam_ColorProcessingAlgorithm); // Start capturing images error = cam.StartCapture(); if (error != FlyCapture2::PGRERROR_OK) { LOG_ERROR( error.GetDescription() ); exit(0); } // Set frame rate property FlyCapture2::Property cam_property; cam_property.type = (FlyCapture2::PropertyType)16; //FlyCapture2::PropertyType::FRAME_RATE; cam_property.absControl = true; cam_property.autoManualMode = this->auto_FrameRate; cam_property.onOff = true; cam_property.onePush = false; cam_property.absValue = (float)this->cam_FrameRate; error = cam.SetProperty( &cam_property ); if (error != FlyCapture2::PGRERROR_OK) { LOG_ERROR( error.GetDescription() ); exit(0); } // Set gain property cam_property.type = (FlyCapture2::PropertyType)13; //FlyCapture2::PropertyType::GAIN; cam_property.absControl = true; cam_property.autoManualMode = this->auto_Gain; cam_property.onOff = true; cam_property.onePush = false; cam_property.absValue = (float)this->cam_Gain; error = cam.SetProperty( &cam_property ); if (error != FlyCapture2::PGRERROR_OK) { LOG_ERROR( error.GetDescription() ); exit(0); } // Set exposure property cam_property.type = (FlyCapture2::PropertyType)1; //FlyCapture2::PropertyType::AUTO_EXPOSURE; cam_property.absControl = true; cam_property.onePush = false; cam_property.onOff = true; cam_property.autoManualMode = this->auto_Exposure; cam_property.absValue = (float)this->cam_Exposure; error = cam.SetProperty( &cam_property ); if (error != FlyCapture2::PGRERROR_OK) { LOG_ERROR( error.GetDescription() ); exit(0); } // Set shuttet property cam_property.type = (FlyCapture2::PropertyType)12; //FlyCapture2::PropertyType::SHUTTER; cam_property.absControl = true; cam_property.onePush = false; cam_property.onOff = true; cam_property.autoManualMode = this->auto_Shutter; cam_property.absValue = (float)this->cam_Shutter; error = cam.SetProperty( &cam_property ); if (error != FlyCapture2::PGRERROR_OK) { LOG_ERROR( error.GetDescription() ); exit(0); } //============================================================================================================ //---------------------------------- Recording parameters ------------------------------------ size_t imageCount = 0; // Timestamp road_time_t time = 0; road_timerange_t tr = 0; const char * const imagePrefix = "image"; const char * const imageNameDelimiter = "-"; const char * const imageExtension = this->image_compact ? ".jpg" : (((FlyCapture2::PixelFormat)this->cam_PixelFormat == FlyCapture2::PIXEL_FORMAT_MONO8)|| ((FlyCapture2::PixelFormat)this->cam_PixelFormat == FlyCapture2::PIXEL_FORMAT_MONO12)|| ((FlyCapture2::PixelFormat)this->cam_PixelFormat == FlyCapture2::PIXEL_FORMAT_MONO16)) ? ".pgm" : ".ppm"; const char kFillCharacter = '0'; const int kNumberWidth = 5; //-------------------------------------------------------------------------------------------- // Raw image FlyCapture2::Image rawImage; bool shmen_init = false; while (THREAD_ALIVE) { //LOG_INFO("Grab new image"); //std::cout << "Grab new image\n"; // Retrieve an image error = cam.RetrieveBuffer( &rawImage ); if (error != FlyCapture2::PGRERROR_OK) { LOG_ERROR( error.GetDescription() ); continue; } //std::cout << "Get timestamp\n"; // Image timestamp FlyCapture2::TimeStamp timeStamp = rawImage.GetTimeStamp(); // Time in seconds //double currTime = (double)timeStamp.cycleSeconds + (((double)timeStamp.cycleCount+((double)timeStamp.cycleOffset/3072.0))/8000.0); //unsigned long timeStampSeconds = timeStamp.seconds; //unsigned long timeStampMicroSeconds = timeStamp.microSeconds; //time = static_cast(timeStampSeconds) * 1000 * 1000 + timeStampMicroSeconds; time = road_time(); // Use the same time base of the other sensors //std::cout << "Time: " << time << " \n"; // Get the raw image dimensions /*FlyCapture2::PixelFormat pixFormat; unsigned int rows, cols, stride; rawImage.GetDimensions( &rows, &cols, &stride, &pixFormat );*/ // Create a converted image FlyCapture2::Image convertedImage; if(this->cam_channels == 1) { // Convert the raw image error = rawImage.Convert( FlyCapture2::PIXEL_FORMAT_MONO8, &convertedImage ); if (error != FlyCapture2::PGRERROR_OK) { LOG_ERROR( error.GetDescription() ); exit(0); } } else { // Convert the raw image error = rawImage.Convert( FlyCapture2::PIXEL_FORMAT_BGR, &convertedImage ); if (error != FlyCapture2::PGRERROR_OK) { LOG_ERROR( error.GetDescription() ); exit(0); } } //////////////////////////////////////////////////////////////////////////////////////// if(this->use_shmem) { //std::cout << "Create shared memory\n"; if(!shmen_init) { //---------------------------- Shared Memory Initialization -------------------------------------- this->mMaxImageOutputSize = sizeof(unsigned char)*this->cam_width*this->cam_height*this->cam_channels; this->img_mem_size = mMaxImageOutputSize; this->shmem_image = new ShMem(Flea3MemoryName_img.c_str(), this->img_mem_size); //------------------------------------------------------------------------------------------------ shmen_init = true; } //std::cout << "Share image created : " << this->img_mem_size << "\n"; // Copy images data to memory this->shmem_image->write(convertedImage.GetData(), this->img_mem_size); } //////////////////////////////////////////////////////////////////////////////////////// ///////////////////// // Write images to disk if (this->isRecording()) { // Save the image to file stringstream imageNameSs; imageNameSs << /*ComponentBase::componentName*/name().toStdString() << "/" << imagePrefix << imageNameDelimiter << setfill(kFillCharacter) << setw(kNumberWidth) << imageCount << imageExtension; string imageName = this->mOutputDirectory.filePath(imageNameSs.str().c_str()).toStdString(); // Save the image. If a file format is not passed in, then the file // extension is parsed to attempt to determine the file format. error = convertedImage.Save( const_cast(imageName.c_str()) ); if (error != FlyCapture2::PGRERROR_OK) { LOG_ERROR( error.GetDescription() ); exit(0); } try { this->mDbtImage.writeRecord(time, tr, this->mOutputDirectory.filePath(imageName.c_str()).toStdString().c_str(), kMaxFilepathLength); } catch (DbiteException & e) { cerr << "error opening dbt file: " << e.what() << endl; } } if(this->showdebug) { unsigned int rowBytes = (int)((double)convertedImage.GetReceivedDataSize()/(double)convertedImage.GetRows()); cv::Mat Img_BGR = cv::Mat(convertedImage.GetRows(), convertedImage.GetCols(), CV_MAKE_TYPE(CV_8U, this->cam_channels), convertedImage.GetData(), rowBytes); cv::namedWindow( "Flea3Component - Current Reference Frame", CV_WINDOW_KEEPRATIO ); cv::imshow("Flea3Component - Current Reference Frame", Img_BGR); cv::waitKey(10); } LOG_TRACE("image no. " << imageCount << " acquired successfully"); ++imageCount; } //====================================== Camera finalization ================================================= LOG_INFO("Finished grabbing images!"); // Stop capturing images error = cam.StopCapture(); if (error != FlyCapture2::PGRERROR_OK) { LOG_ERROR( error.GetDescription() ); exit(0); } // Disconnect the camera error = cam.Disconnect(); if (error != FlyCapture2::PGRERROR_OK) { LOG_ERROR( error.GetDescription() ); exit(0); } //============================================================================================================ if(shmen_init) { if(this->shmem_image) delete shmem_image; this->shmem_image = NULL; } this->is_running = false; }