/******************************************************************** ** Image Component Library (ICL) ** ** ** ** Copyright (C) 2006-2012 CITEC, University of Bielefeld ** ** Neuroinformatics Group ** ** Website: www.iclcv.org and ** ** http://opensource.cit-ec.de/projects/icl ** ** ** ** File : ICLIO/src/PylonGrabber.cpp ** ** Module : ICLIO ** ** Authors: Viktor Richter ** ** ** ** ** ** Commercial License ** ** ICL can be used commercially, please refer to our website ** ** www.iclcv.org for more details. ** ** ** ** GNU General Public License Usage ** ** Alternatively, this file may be used under the terms of the ** ** GNU General Public License version 3.0 as published by the ** ** Free Software Foundation and appearing in the file LICENSE.GPL ** ** included in the packaging of this file. Please review the ** ** following information to ensure the GNU General Public License ** ** version 3.0 requirements will be met: ** ** http://www.gnu.org/copyleft/gpl.html. ** ** ** ** The development of this software was supported by the ** ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** ** Forschungsgemeinschaft (DFG) in the context of the German ** ** Excellence Initiative. ** ** ** *********************************************************************/ #include #include #include #include #include using namespace icl; using namespace icl::pylon; // Constructor of PylonGrabberImpl PylonGrabberImpl::PylonGrabberImpl( const Pylon::CDeviceInfo &dev, const std::string args) : m_ImgMutex(), m_PylonEnv(), m_LastBuffer(NULL) { FUNCTION_LOG("args: " << args) icl::Mutex::Locker l(m_ImgMutex); // Initialization of the pylon Runtime Library m_Camera = Pylon::CTlFactory::GetInstance().CreateDevice(dev); unsigned int channel = channelFromArgs(args); if(m_Camera -> GetNumStreamGrabberChannels() == 0){ throw icl::ICLException("No stream grabber channels avaliable."); } else if(m_Camera -> GetNumStreamGrabberChannels() < channel){ DEBUG_LOG("From args='" << args << "' demanded channel=" << channel << "but available=" << m_Camera -> GetNumStreamGrabberChannels()) throw icl::ICLException("Demanded StreamGrabberChannel not avaliable."); } m_Camera -> Open(); cameraDefaultSettings(); // getting first Grabber m_Grabber = m_Camera -> GetStreamGrabber(channel); m_Grabber -> Open(); m_CameraOptions = new PylonCameraOptions(m_Camera, this); m_ColorConverter = new PylonColorConverter(); m_GrabberThread = new PylonGrabberThread( m_Grabber, m_ColorConverter, m_CameraOptions); // prepare grabbing grabbingStart(); // Let the camera acquire images m_CameraOptions -> acquisitionStart(); m_GrabberThread -> start(); } PylonGrabberImpl::~PylonGrabberImpl(){ FUNCTION_LOG(); // Stop acquisition acquisitionStop(); // deregister buffers grabbingStop(); // Close stream grabber m_Grabber -> Close(); // Close camera m_Camera -> Close(); ICL_DELETE(m_ColorConverter) ICL_DELETE(m_CameraOptions) ICL_DELETE(m_GrabberThread) // Free resources allocated by the pylon runtime system automated. } void PylonGrabberImpl::grabbingStart(){ FUNCTION_LOG() // Get the image buffer size const size_t imageSize = m_CameraOptions -> getNeededBufferSize(); DEBUG_LOG2("Buffer size: " << imageSize) // We won't use image buffers greater than imageSize setParameterValueOf (m_Grabber, "MaxBufferSize", imageSize); // We won't queue more than m_NumBuffers image buffers at a time setParameterValueOf (m_Grabber, "MaxNumBuffer", m_NumBuffers); // Allocate all resources for grabbing. Critical parameters like image // size now must not be changed until finishGrab() is called. m_Grabber -> PrepareGrab(); // Buffers used for grabbing must be registered at the stream grabber -> // The registration returns a handle to be used for queuing the buffer. for (int i = 0; i < m_NumBuffers; ++i){ PylonGrabberBuffer *pGrabBuffer = new PylonGrabberBuffer(imageSize); Pylon::StreamBufferHandle handle = m_Grabber -> RegisterBuffer(pGrabBuffer -> getBufferPointer(), imageSize); pGrabBuffer -> setBufferHandle(handle); // Put the grab buffer object into the buffer list m_BufferList.push_back(pGrabBuffer); // Put buffer into the grab queue for grabbing m_Grabber -> QueueBuffer(handle); } m_GrabberThread -> resetBuffer(); m_ColorConverter -> resetConversion( m_CameraOptions -> getWidth(), m_CameraOptions -> getHeight(), m_CameraOptions -> getCameraPixelSize(), m_CameraOptions -> getNeededBufferSize(), m_CameraOptions -> getCameraPixelType(), m_CameraOptions -> getFormatString() ); } void PylonGrabberImpl::grabbingStop(){ FUNCTION_LOG() m_Grabber -> CancelGrab(); Pylon::GrabResult result; while (m_Grabber -> GetWaitObject().Wait(0)) { if (!m_Grabber -> RetrieveResult(result)) { DEBUG_LOG("Failed to retrieve item from output queue") } } // deregister the buffers before freeing the memory while (!m_BufferList.empty()){ m_Grabber -> DeregisterBuffer(m_BufferList.back() -> getBufferHandle()); PylonGrabberBuffer* tmp = m_BufferList.back(); delete tmp; m_BufferList.pop_back(); } // Free all resources used for grabbing m_Grabber -> FinishGrab(); } void PylonGrabberImpl::acquisitionStart(){ FUNCTION_LOG() m_CameraOptions -> acquisitionStart(); m_GrabberThread -> start(); m_ImgMutex.unlock(); } void PylonGrabberImpl::acquisitionStop(){ FUNCTION_LOG() m_ImgMutex.lock(); m_GrabberThread -> stop(); m_CameraOptions -> acquisitionStop(); } void PylonGrabberImpl::cameraDefaultSettings(){ // activate timestamp-chunks setParameterValueOf (m_Camera, "ChunkModeActive", true); setParameterValueOf (m_Camera, "ChunkSelector", "Timestamp"); setParameterValueOf (m_Camera, "ChunkEnable", true); // set PacketSize //setParameterValueOf //(m_Camera, "GevSCPSPacketSize", 8192); } const icl::ImgBase* PylonGrabberImpl::acquireImage(){ ImgBase* ret = NULL; int counter = 0; while(1){ // lock image lock so buffers are safe till release. m_ImgMutex.lock(); // Get the image from the grabber thread ret = m_GrabberThread -> getCurrentImage(); if(m_CameraOptions-> omitDoubleFrames() && ret == m_LastBuffer && counter <= 1000) { // old frame release and sleep m_ImgMutex.unlock(); ret = NULL; ++counter; Thread::msleep(1); } else { m_ImgMutex.unlock(); break; } } m_LastBuffer = ret; return ret; } // setter function for video device properties void PylonGrabberImpl::setProperty( const std::string &property, const std::string &value) { m_CameraOptions -> setProperty(property, value); } // returns a list of properties, that can be set using setProperty std::vector PylonGrabberImpl::getPropertyList(){ return m_CameraOptions -> getPropertyList(); } // checks if property is returned, implemented, available and of processable GenApi::EInterfaceType bool PylonGrabberImpl::supportsProperty(const std::string &property){ return m_CameraOptions -> supportsProperty(property); } // get type of property std::string PylonGrabberImpl::getType(const std::string &name){ return m_CameraOptions -> getType(name); } // get information of a properties valid values std::string PylonGrabberImpl::getInfo(const std::string &name){ return m_CameraOptions -> getInfo(name); } // returns the current value of a property or a parameter std::string PylonGrabberImpl::getValue(const std::string &name){ return m_CameraOptions -> getValue(name); } // Returns whether this property may be changed internally. int PylonGrabberImpl::isVolatile(const std::string &propertyName){ return m_CameraOptions -> isVolatile(propertyName); }