Пример #1
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;
        }
Пример #2
0
 /// <summary>
 /// Produces an image in the ring buffer
 /// </summary>
 /// <param name="image">The image to write into the buffer</param>
 public void Produce(Image16 image)
 {
     if (_isDisposed)
     {
         throw new ObjectDisposedException("PrCoImageRingBuffer");
     }
     if (image == null)
     {
         return;
     }
     if (image.Width != _imageWidth || image.Height != _imageHeight)
     {
         throw new ArgumentException("The produced image is not compatible with the buffer");
     }
     lock (_accessLock)
     {
         //advance our production buffer "pointer" to the next place in the ring buffer
         _lastProduce = (_lastProduce + 1) % _nImages;
         //increment _imageIndex internally
         var temp = _imageIndex + 1;
         //copy image over
         ip.ippiCopy_16u_C1R(image.Image, image.Stride, _buffers[_lastProduce], _imageStride, new IppiSize(_imageWidth, _imageHeight));
         //update the indices in the production place with the current image index
         _imageIndices[_lastProduce] = temp;
         //Image has been produced, update index and storage counter
         _imageIndex = temp;
         _storageCount++;
         //Signal waiting threads that we are about to release the lock
         Monitor.Pulse(_accessLock);
     }
 }
Пример #3
0
        public Image16 copy()
        {
            global::System.IntPtr cPtr = libPhotoAssistantImageProcessingPINVOKE.Image16_copy(swigCPtr);
            Image16 ret = (cPtr == global::System.IntPtr.Zero) ? null : new Image16(cPtr, false);

            return(ret);
        }
Пример #4
0
        /// <summary>
        /// Consumes an image from the ring buffer
        /// </summary>
        /// <param name="imageOut">The Image8 into which the consumed image should be copied</param>
        /// <param name="expectedIndex">The index we expect to recieve</param>
        /// <param name="stop">Wait handle to signal that the consumption thread is about to stop</param>
        /// <returns>True if the expected index could be consumed, false otherwise</returns>
        public bool Consume(Image16 imageOut, int expectedIndex, AutoResetEvent stop)
        {
            int indexRetrieved = Consume(imageOut, stop);

            if (indexRetrieved != expectedIndex)
            {
                System.Diagnostics.Debug.WriteLine("Ring buffer overflow. Expected image index {0} got image index {1}.", expectedIndex, indexRetrieved);
                return(false);
            }
            else
            {
                return(true);
            }
        }
Пример #5
0
 public void FromImage16(Image16 im, float cMax)
 {
     if (im.Width != Width || im.Height != Height)
     {
         throw new ArgumentException("Width and Height must match");
     }
     if (_scalingBuffer == null || _scalingBuffer.Length < im.Width * im.Height)
     {
         _scalingBuffer = new float[im.Width * im.Height];
         fixed(float *pScalingBuffer = _scalingBuffer)
         {
             ip.ippiConvert_16u32f_C1R(im.Image, im.Stride, pScalingBuffer, 4 * im.Width, im.Size);
             ip.ippiScale_32f8u_C1R(pScalingBuffer, 4 * im.Width, Image, Stride, Size, 0, cMax);
         }
 }
Пример #6
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);
        }
Пример #7
0
        public static void Main(string[] args)
        {
            long startTime;

            Image16 im  = new Image16(21000, 21000);
            Image16 im2 = new Image16(4096, 4096, 0x0);

            UIConsole.Log("Benchmark Draw");
            startTime = LLTools.TimestampMS();
            im.DrawImage(im2, 1024, 1024, true);
            UIConsole.Log($"Delta: {LLTools.TimestampMS() - startTime} ms");

            UIConsole.Log("Benchmark Save PGM");
            startTime = LLTools.TimestampMS();
            im.SavePGM("test.pgm");
            UIConsole.Log($"Delta: {LLTools.TimestampMS() - startTime} ms");
        }
Пример #8
0
        /// <summary>
        /// Consumes an image from the ring buffer
        /// </summary>
        /// <param name="imageOut">The Image8 into which the consumed image should be copied</param>
        /// <param name="stop">Wait handle to signal that the consumption thread is about to stop</param>
        /// <returns>The index of the retrieved image</returns>
        public int Consume(Image16 imageOut, AutoResetEvent stop)
        {
            int retval;

            if (_isDisposed)
            {
                throw new ObjectDisposedException("PrCoImageRingBuffer");
            }
            if (imageOut == null)
            {
                throw new ArgumentNullException("imageOut");
            }
            if (imageOut.Width != _imageWidth || imageOut.Height != _imageHeight)
            {
                throw new ArgumentException("The recieving image is not compatible with the buffer");
            }

            lock (_accessLock)
            {
                while (_storageCount < 1)
                {
                    //If we are told to stop then we throw an OperationCanceledException
                    if (stop.WaitOne(0))
                    {
                        throw new OperationCanceledException("Consume signaled to stop");
                    }
                    //We wait for a pulse for 100ms. After that we independently try to reacquire the lock.
                    //This way if the the producer has retired we are not indefinitely stuck on the wait and can listen
                    //for a stop signal
                    Monitor.Wait(_accessLock, 100);
                }
                //There is at least one image in storage, lets consume it
                //advance the consumption "pointer" to the next place in the buffer
                _lastConsume = (_lastConsume + 1) % _nImages;
                //copy image over
                ip.ippiCopy_16u_C1R(_buffers[_lastConsume], _imageStride, imageOut.Image, imageOut.Stride, new IppiSize(_imageWidth, _imageHeight));
                //we want to return the index of the consumed image
                retval = _imageIndices[_lastConsume];
                //decrement storage counter
                _storageCount--;
            }

            return(retval);
        }
Пример #9
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;
     }
 }
Пример #10
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(Image16 obj)
 {
     return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr);
 }