예제 #1
0
        /// <summary>
        /// Writes a serial command to the camera and returns the number of characters written
        /// </summary>
        /// <param name="command">The serial command to write including the appropriate termination char</param>
        /// <returns>The number of characters written to the interface</returns>
        public uint SerialWrite(string command)
        {
            uint written = (uint)command.Length;

            NIImaq.CheckError(NIImaq.imgSessionSerialWrite(_sid, command, ref written, 1000));
            return(written);
        }
예제 #2
0
        /// <summary>
        /// Reads up to the specified number of characters from the serial buffer
        /// </summary>
        /// <param name="charsToRead">The (maximum) number of characters to read on call and the number
        /// of characters actually read after the function call</param>
        /// <returns>The read string from the serial port</returns>
        public string SerialRead(ref uint charsToRead)
        {
            StringBuilder sb = new StringBuilder((int)charsToRead);

            NIImaq.CheckError(NIImaq.imgSessionSerialRead(_sid, sb, ref charsToRead, 1000));
            return(sb.ToString());
        }
예제 #3
0
        /// <summary>
        /// Extracts an 8-bit image reducing bit depth if necessary
        /// </summary>
        /// <param name="imageOut">The container to recieve the image</param>
        /// <param name="requestedFrame">The framenumber to request</param>
        /// <returns>The frame number actually retrieved from the buffer</returns>
        public uint Extract(Image8 imageOut, uint requestedFrame)
        {
            uint frameActual, indexActual;

            if (_bytesPerPixel == 2)
            {
                //this requires acquisition into our internal buffer first
                //followed by handing out a downsized copy
                frameActual = Extract(_imgDownsize, requestedFrame);
                //if our bit-depth is not 16 we have a problem - we need
                //to scale our image first to really fill the 16bits otherwise we run into
                //problems later...
                if (_bitsPerPixel < 16)
                {
                    ip.ippiMulC_16u_C1IRSfs(_scaleFactor, _imgDownsize.Image, _imgDownsize.Stride, _imgDownsize.Size, 0);
                }
                //we got handed 8 bits
                _imgDownsize.ReduceTo8U(imageOut);
            }
            else
            {
                NIImaq.CheckError(NIImaq.imgSessionCopyBufferByNumber(_sid, requestedFrame, (IntPtr)imageOut.Image, IMG_OVERWRITE_MODE.IMG_OVERWRITE_GET_NEWEST, out frameActual, out indexActual));
                if (frameActual != requestedFrame)
                {
                    System.Diagnostics.Debug.WriteLine("Requested frame {0}; obtained frame {1}", requestedFrame, frameActual);
                }
            }
            _acquiredFrames++;
            return(frameActual);
        }
예제 #4
0
 /// <summary>
 /// Constructs a new IMAQ camera on the
 /// specified camera link interface
 /// </summary>
 /// <param name="interfaceId">The interface name. Optionally followed by ::# identifying the port - 0 based</param>
 public CameraLinkCamera(string interfaceId)
 {
     //Attach to interface
     NIImaq.CheckError(NIImaq.imgInterfaceOpen(interfaceId, out _ifid));
     //Open session
     NIImaq.CheckError(NIImaq.imgSessionOpen(_ifid, out _sid));
     //Get image dimensions
     NIImaq.CheckError(NIImaq.imgGetAttribute(_sid, ImaqAttribute.IMG_ATTR_ROI_WIDTH, out _width));
     NIImaq.CheckError(NIImaq.imgGetAttribute(_sid, ImaqAttribute.IMG_ATTR_ROI_HEIGHT, out _height));
     NIImaq.CheckError(NIImaq.imgGetAttribute(_sid, ImaqAttribute.IMG_ATTR_BYTESPERPIXEL, out _bytesPerPixel));
     System.Diagnostics.Debug.WriteLine("Bytes per pixel {0}", _bytesPerPixel);
     NIImaq.CheckError(NIImaq.imgGetAttribute(_sid, ImaqAttribute.IMG_ATTR_BITSPERPIXEL, out _bitsPerPixel));
     if (_bytesPerPixel == 2 && _bitsPerPixel < 16)
     {
         _scaleFactor   = 1;
         _scaleFactor <<= (16 - (int)_bitsPerPixel);
     }
     else
     {
         _scaleFactor = 1;
     }
     System.Diagnostics.Debug.WriteLine("Bits per pixel {0}", _bitsPerPixel);
     System.Diagnostics.Debug.WriteLine("Frame width: {0}", _width);
     System.Diagnostics.Debug.WriteLine("Frame height: {0}", _height);
     //Unfortunately there is now way (?) to nicely align the camera buffers on 4-byte boundary for ipp
     //The user generated image wrappers will expect this however - so for now do NOT allow to
     //start acquisition with a width which is non-dividable by 4!!
     System.Diagnostics.Debug.Assert(Width % 4 == 0, "At the moment for memory alignment, the class requires an image width which is dividable by 4!!");
     //We also only allow images with either 1 or 2 bytes per pixel!
     if (BytesPerPixel < 1 || BytesPerPixel > 2)
     {
         System.Diagnostics.Debug.Assert(false, "Unknown pixel depth", "Currently a pixel depth of {0} bytes is not supported", BytesPerPixel);
     }
 }
예제 #5
0
        /// <summary>
        /// Ends acquisition and de-configures the session
        /// </summary>
        public void Stop()
        {
            if (!_captureRunning)
            {
                System.Diagnostics.Debug.WriteLine("Tried to stop non-running capture");
                return;
            }
            uint lastBuffNum;

            NIImaq.imgSessionAbort(_sid, out lastBuffNum);

            System.Threading.Thread.Sleep(500);
            if (_bufId != 0)
            {
                NIImaq.imgMemUnlock(_bufId);
            }
            //free buffers
            for (int i = 0; i < (uint)_ringBuffer.Length; i++)
            {
                if (_ringBuffer[i] != IntPtr.Zero)
                {
                    NIImaq.imgDisposeBuffer(_ringBuffer[i]);
                }
            }
            //close buffer list
            if (_bufId != 0)
            {
                NIImaq.imgDisposeBufList(_bufId, false);
            }
            _captureRunning = false;
            _configured     = false;
        }
예제 #6
0
        /// <summary>
        /// Configures the camera setting up required buffers.
        /// Allows separation of this time-intensive task from
        /// acquisition start.
        /// </summary>
        /// <param name="bufferCount">The number of frames requested as buffer</param>
        public void Configure(uint bufferCount)
        {
            //set up ring buffer pointers
            _ringBuffer = new IntPtr[bufferCount];
            //create buffer list
            NIImaq.CheckError(NIImaq.imgCreateBufList(bufferCount, out _bufId));
            //compute required buffer size
            uint bufSize = _width * _height * BytesPerPixel;

            //if this is a 16bit acquisition we pre-allocate an internal buffer
            //to allow us handing out 8bit images instead
            _imgDownsize = new Image16((int)Width, (int)Height);
            //Create our camera buffers and set up the buffer list
            //We set the list up as a ring buffer which means that the command
            //is NEXT for each buffer except the last one, where it will be loop
            for (uint i = 0; i < bufferCount; i++)
            {
                //Let imaq obtain the buffer memory
                NIImaq.CheckError(NIImaq.imgCreateBuffer(_sid, Buffer_Location.IMG_HOST_FRAME, bufSize, out _ringBuffer[i]));
                //assign buffer to our buffer list
                NIImaq.CheckError(NIImaq.imgSetBufferElement2(_bufId, i, BlItemType.IMG_BUFF_ADDRESS, _ringBuffer[i]));
                //tell the list about our buffer size
                NIImaq.CheckError(NIImaq.imgSetBufferElement2(_bufId, i, BlItemType.IMG_BUFF_SIZE, bufSize));
                //Set the appropriate buffer command
                var bufCmd = i < (bufferCount - 1) ? BuffCommands.IMG_CMD_NEXT : BuffCommands.IMG_CMD_LOOP;
                NIImaq.CheckError(NIImaq.imgSetBufferElement2(_bufId, i, BlItemType.IMG_BUFF_COMMAND, bufCmd));
            }
            //lock buffer list (supposed to be obsolote but example still does it...)
            NIImaq.CheckError(NIImaq.imgMemLock(_bufId));
            //configure the session to use this buffer list
            NIImaq.CheckError(NIImaq.imgSessionConfigure(_sid, _bufId));
            _configured = true;
        }
예제 #7
0
 /// <summary>
 /// Creates a new pulse that is triggered based on an internal event/signal
 /// </summary>
 /// <param name="timeBase">The timebase of the pulse</param>
 /// <param name="delay">The ticks of the off-phase</param>
 /// <param name="width">The ticks of the on-phase</param>
 /// <param name="signalType">The type of trigger signal line</param>
 /// <param name="triggerEvent">The internal trigger event</param>
 /// <param name="signalPolarity">The polarity of the trigger signal</param>
 /// <param name="outputType">The type of pulse output line</param>
 /// <param name="outputNumber">The output line identifier</param>
 /// <param name="outputPolarity">The polarity of the on-phase</param>
 /// <param name="pulseMode">The pulse generation mode</param>
 public IMGPulse(PulseTimebase timeBase, uint delay, uint width, IMG_SIGNAL_TYPE signalType, InternalSignalIdentifier triggerEvent, TriggerPolarity signalPolarity, IMG_SIGNAL_TYPE outputType, uint outputNumber, PulsePolarity outputPolarity, PulseMode pulseMode)
 {
     if (signalType != IMG_SIGNAL_TYPE.IMG_SIGNAL_STATUS)
     {
         throw new ArgumentException("signalType", "If an internal event is specified to trigger pulse generation, the signal type must be IMG_SIGNAL_STATUS!");
     }
     NIImaq.CheckError(NIImaq.imgPulseCreate2(timeBase, delay, width, signalType, triggerEvent, signalPolarity, outputType, outputNumber, outputPolarity, pulseMode, ref _plsId));
 }
예제 #8
0
 protected virtual void Dispose(bool disposing)
 {
     if (IsDisposed)
     {
         return;
     }
     if (NIImaq.imgPulseDispose(_plsId) != 0)
     {
         System.Diagnostics.Debug.WriteLine("Could not dispose pulse");
     }
 }
예제 #9
0
        /// <summary>
        /// Extracts a 16-bit image
        /// </summary>
        /// <param name="imageOut">The container to recieve the image</param>
        /// <param name="requestedFrame">The framenumber to request</param>
        /// <returns>The frame number actually retrieved from the buffer</returns>
        public uint Extract(Image16 imageOut, uint requestedFrame)
        {
            uint frameActual, indexActual;

            if (_bytesPerPixel == 1)
            {
                System.Diagnostics.Debug.WriteLine("Acquired 8 bit image into 16bit structure");
            }
            NIImaq.CheckError(NIImaq.imgSessionCopyBufferByNumber(_sid, requestedFrame, (IntPtr)imageOut.Image, IMG_OVERWRITE_MODE.IMG_OVERWRITE_GET_NEWEST, out frameActual, out indexActual));
            if (frameActual != requestedFrame)
            {
                System.Diagnostics.Debug.WriteLine("Requested frame {0}; obtained frame {1}", requestedFrame, frameActual);
            }
            _acquiredFrames++;
            return(frameActual);
        }
예제 #10
0
 /// <summary>
 /// Starts acquisition on the camera and configures
 /// the session if necessary
 /// </summary>
 /// <param name="bufferCount">The number of frames requested as buffer</param>
 public void Start(int bufferCount)
 {
     if (_captureRunning)
     {
         System.Diagnostics.Debug.WriteLine("Tried to start already running capture");
         return;
     }
     if (!_configured)
     {
         Configure((uint)bufferCount);
     }
     //Start asynchronous acquisition - after this call the ring-buffer
     //will get filled with images!
     NIImaq.CheckError(NIImaq.imgSessionAcquire(_sid, true, null));
     _captureRunning = true;
     _acquiredFrames = 0;
 }
예제 #11
0
 protected virtual void Dispose(bool disposing)
 {
     if (IsDisposed)
     {
         return;
     }
     if (_captureRunning)
     {
         Stop();
     }
     //Close interface and session
     NIImaq.imgClose(_sid, true);
     NIImaq.imgClose(_ifid, true);
     if (_imgDownsize != null)
     {
         _imgDownsize.Dispose();
         _imgDownsize = null;
     }
 }
예제 #12
0
 /// <summary>
 /// Flushes the serial buffer. Call btw. consecutive writes and reads
 /// </summary>
 public void SerialFlush()
 {
     NIImaq.CheckError(NIImaq.imgSessionSerialFlush(_sid));
 }
예제 #13
0
 /// <summary>
 /// Stops pulse generation
 /// </summary>
 public void Stop()
 {
     NIImaq.CheckError(NIImaq.imgPulseStop(_plsId));
 }
예제 #14
0
 /// <summary>
 /// Arms a triggered pulse to be run on the
 /// configured session
 /// </summary>
 /// <param name="sessionId">The session to which the pulse should be associated</param>
 public void Start(uint sessionId)
 {
     NIImaq.CheckError(NIImaq.imgPulseStart(_plsId, sessionId));
 }
예제 #15
0
 /// <summary>
 /// Creates a new pulse that is triggered based on an external line
 /// </summary>
 /// <param name="timeBase">The timebase of the pulse</param>
 /// <param name="delay">The ticks of the off-phase</param>
 /// <param name="width">The ticks of the on-phase</param>
 /// <param name="signalType">The type of trigger signal line</param>
 /// <param name="signalIdentifier">The trigger signal line identifier</param>
 /// <param name="signalPolarity">The polarity of the trigger signal</param>
 /// <param name="outputType">The type of pulse output line</param>
 /// <param name="outputNumber">The output line identifier</param>
 /// <param name="outputPolarity">The polarity of the on-phase</param>
 /// <param name="pulseMode">The pulse generation mode</param>
 public IMGPulse(PulseTimebase timeBase, uint delay, uint width, IMG_SIGNAL_TYPE signalType, uint signalIdentifier, TriggerPolarity signalPolarity, IMG_SIGNAL_TYPE outputType, uint outputNumber, PulsePolarity outputPolarity, PulseMode pulseMode)
 {
     NIImaq.CheckError(NIImaq.imgPulseCreate2(timeBase, delay, width, signalType, signalIdentifier, signalPolarity, outputType, outputNumber, outputPolarity, pulseMode, ref _plsId));
 }