示例#1
0
 /// <summary>
 /// Produces an image in the ring buffer
 /// </summary>
 /// <param name="image">The image to write into the buffer</param>
 public void Produce(Image8 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_8u_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);
     }
 }
示例#2
0
 public void WriteFrame(Image8 frame)
 {
     //if this is the first frame of the current file
     //we have to create the file
     if (_firstFrame)
     {
         System.Diagnostics.Debug.Assert(_tiffFile == null, "Tried first write but tiffile not null");
         _pageIndex = 0;
         _tiffFile  = Tiff.Open(CurrentFileNameWithExtension, "w");
         //write first page
         WritePage(frame);
         //increment page index
         _pageIndex++;
         _firstFrame = false;
     }
     else
     {
         //TiffStream stream = _tiffFile.GetStream();
         if (new FileInfo(CurrentFileNameWithExtension).Length > 1900000000)//limit file size for MATLABs sake
         {
             _fileIndex++;
             _firstFrame = true;
             _tiffFile.Dispose();
             _tiffFile = null;
             WriteFrame(frame);
             return;
         }//if file size maxed out
         //write next page
         WritePage(frame);
         //increment page index
         _pageIndex++;
     }
 }
 protected virtual void Dispose(bool disposing)
 {
     if (_bgModel != null)
     {
         _bgModel.Dispose();
         _bgModel = null;
     }
     if (_calc != null)
     {
         _calc.Dispose();
         _calc = null;
     }
     if (_foreground != null)
     {
         _foreground.Dispose();
         _foreground = null;
     }
     if (_markerBuffer != null)
     {
         Marshal.FreeHGlobal((IntPtr)_markerBuffer);
         _markerBuffer = null;
     }
     if (_momentState != null)
     {
         ip.ippiMomentFree_64s(_momentState);
         _momentState = null;
     }
 }
示例#4
0
 protected override void Dispose(bool disposing)
 {
     base.Dispose(disposing);
     if (disposing)
     {
         if (_trackWriter != null)
         {
             _trackWriter.Dispose();
             _trackWriter = null;
         }
         if (_imageWriter != null)
         {
             _imageWriter.Dispose();
             _imageWriter = null;
         }
         if (_backgroundWriter != null)
         {
             _backgroundWriter.Dispose();
             _backgroundWriter = null;
         }
         if (_laser != null)
         {
             _laser.Dispose();
         }
         if (_scanner != null)
         {
             _scanner.Dispose();
         }
         if (_camRegion != null)
         {
             _camRegion.Dispose();
             _camRegion = null;
         }
     }
 }
示例#5
0
        public Replay(Queue <string> originalTrackData, Queue <string> originalInfoData, OriginalType originalType, int originalLength, int frameRate, int pxPERmm, string folder, string name, string fishID) :
            base(folder, name, fishID, originalLength, frameRate, pxPERmm)
        {
            if (FileSaver != null)
            {
                _trackWriter      = FileSaver.GetStreamWriter(".track");
                _imageWriter      = FileSaver.GetTiffWriter("_camImage.tif", true);
                _backgroundWriter = FileSaver.GetTiffWriter("_bgImage.tif", true);
                //Create 10x10 mm region image
                _camRegion = new Image8(Properties.Settings.Default.PixelsPermm * 10, Properties.Settings.Default.PixelsPermm * 10);
            }
            _laser = new SDLPS500Controller(Properties.Settings.Default.DAQ, Properties.Settings.Default.LaserAO);
            string xchannel = Properties.Settings.Default.DAQ + "/" + Properties.Settings.Default.ScannerX;
            string ychannel = Properties.Settings.Default.DAQ + "/" + Properties.Settings.Default.ScannerY;

            //Load scan lookup table from file
            try
            {
                TextReader reader    = File.OpenText("main.calib");
                var        scanTable = BLIScanLookupTable.LoadFromFile(reader);
                _scanner = new RandomAccessScanner(scanTable, xchannel, ychannel, -10, 10);
                reader.Dispose();
            }
            catch (IOException)
            {
                System.Diagnostics.Debug.WriteLine("Could not find calibration data. No targeting available");
            }
            //This is a closed-loop experiment - try to stay fully up-to-date
            SuggestedBufferSeconds = 0;
            _originalType          = originalType;
            _originalTrackData     = originalTrackData;
            _originalInfoData      = originalInfoData;
            _experimentPhase       = ExperimentPhase.Replay;
        }
示例#6
0
        /// <summary>
        /// Safely copies region around given centroid
        /// </summary>
        /// <param name="centroid">The centroid around which image region should be copied</param>
        /// <param name="regionImage">The target of the copy</param>
        /// <param name="image">The source of the copy operation</param>
        public static void CopyRegionImage(IppiPoint centroid, Image8 regionImage, Image8 image)
        {
            IppiPoint copyStart = new IppiPoint(centroid.x - regionImage.Width / 2, centroid.y - regionImage.Height / 2);
            int       destX     = 0;
            int       destY     = 0;

            if (copyStart.x < 0)
            {
                destX      -= copyStart.x;
                copyStart.x = 0;
            }
            if (copyStart.y < 0)
            {
                destY      -= copyStart.y;
                copyStart.y = 0;
            }
            IppiSize copySize = new IppiSize(regionImage.Width - destX, regionImage.Height - destY);

            if (copyStart.x + copySize.width > image.Width)
            {
                copySize.width = image.Width - copyStart.x;
            }
            if (copyStart.y + copySize.height > image.Height)
            {
                copySize.height = image.Height - copyStart.y;
            }
            if (copySize.width > 0 && copySize.height > 0)
            {
                ip.ippiCopy_8u_C1R(image[copyStart], image.Stride, regionImage[destX, destY], regionImage.Stride, copySize);
            }
        }
示例#7
0
        /// <summary>
        /// Extract blobs from an image in which distinct contiguous regions are marked
        /// with distinct pixel values such as returned by ippiLabelMarkers
        /// </summary>
        /// <param name="imMarkers">The marker image</param>
        /// <param name="nMarkers">The number of expected markers</param>
        /// <param name="imOriginal">The original image. Used for pixel-intensity information</param>
        /// <param name="roi">The roi in which to perform blob extraction</param>
        /// <returns>An array of discovered blobs</returns>
        public static BlobWithMoments[] ExtractBlobs(Image8 imMarkers, int nMarkers, IppiROI roi)
        {
            if (nMarkers == 0)//no point to iterate over the image if no marker was found
            {
                return(null);
            }
            BlobWithMoments[] blobs = new BlobWithMoments[nMarkers];
            byte markerValue;

            //loop over ROI in marker image, adding pixels to their appropriate blob
            for (int i = roi.Y; i < roi.Y + roi.Height; i++)
            {
                for (int j = roi.X; j < roi.X + roi.Width; j++)
                {
                    markerValue = imMarkers.Image[i * imMarkers.Stride + j];
                    if (markerValue != 0) //it belongs to a blob!
                    {
                        //since the lowest marker has the value 1 we need to deduct 1 from markerValue for 0-index based array mapping!
                        if (blobs[markerValue - 1] == null)
                        {
                            blobs[markerValue - 1] = new BlobWithMoments();
                        }
                        blobs[markerValue - 1].AddPixel(j, i);
                    }
                }
            }
            return(blobs);
        }
示例#8
0
        ///// <summary>
        ///// Computes the augmented rotation matrix for an augmented 2D point around the origin
        ///// </summary>
        ///// <param name="theta">The clockwise rotation angle in radians</param>
        ///// <returns>The augmented (3x3) 2D rotation matrix</returns>
        //public static Matrix<double> RotationMatrix(double theta)
        //{
        //    return DenseMatrix.OfArray(new double[,]
        //    {
        //        {Math.Cos(theta), Math.Sin(theta), 0 },
        //        {-1*Math.Sin(theta), Math.Cos(theta), 0 },
        //        {0, 0, 1 }
        //    });
        //}

        ///// <summary>
        ///// Computes the augmented translation matrix for an augmented 2D point
        ///// </summary>
        ///// <param name="dx">Translation amount in x direction</param>
        ///// <param name="dy">Translation amount in y direction</param>
        ///// <returns>The augmented (3x3) 2D translation matrix</returns>
        //public static Matrix<double> TranslationMatrix(double dx, double dy)
        //{
        //    return DenseMatrix.OfArray(new double[,]
        //    {
        //        {1, 0, dx },
        //        {0, 1, dy },
        //        {0, 0, 1 }
        //    });
        //}

        ///// <summary>
        ///// Augments a 2D coordinate point
        ///// </summary>
        ///// <param name="px">The x-coordinate</param>
        ///// <param name="py">The y-coordinate</param>
        ///// <returns>A 3 element vector comprising the point</returns>
        //public static Vector<double> Augment2DCoordinate(double px, double py)
        //{
        //    return DenseVector.OfArray(new double[] { px, py, 1 });
        //}

        ///// <summary>
        ///// Composes (multiplies) a list of transformation matrices in order
        ///// NOTE: List should be ordered in order of application which needs to be reversed for the composition!
        ///// </summary>
        ///// <param name="matrices">List of transformations to compose</param>
        ///// <returns>The composed matrix</returns>
        //public static Matrix<double> Compose(List<Matrix<double>> matrices)
        //{
        //    Matrix<double> m = DenseMatrix.CreateIdentity(3);
        //    for(int i = matrices.Count-1; i>=0; i--)
        //        m *= matrices[i];
        //    return m;
        //}

        ///// <summary>
        ///// Applies transformation to given point
        ///// </summary>
        ///// <param name="p"></param>
        ///// <param name="T"></param>
        ///// <returns></returns>
        //public static IppiPoint TransformPoint(IppiPoint p, Matrix<double> T)
        //{
        //    Vector<double> result = Augment2DCoordinate(p.x, p.y) * T;
        //    return new IppiPoint((int)result[0], (int)result[1]);
        //}

        ///// <summary>
        ///// Applies transformation to given point
        ///// </summary>
        ///// <param name="p"></param>
        ///// <param name="T"></param>
        ///// <returns></returns>
        //public static IppiPoint_32f TransformPoint(IppiPoint_32f p, Matrix<double> T)
        //{
        //    Vector<double> result =  T * Augment2DCoordinate(p.x, p.y);
        //    return new IppiPoint_32f((float)result[0], (float)result[1]);
        //}

        /// <summary>
        /// Method for creating image background
        /// </summary>
        /// <param name="frameNumber">The current camera frame number</param>
        /// <param name="camImage">The camera image</param>
        /// <param name="poi">A detected centroid (all null)</param>
        protected void BuildBackground(int frameNumber, Image8 camImage, out IppiPoint?poi)
        {
            _laser.LaserPower = 0;
            poi = null;
            if (frameNumber == 0 || _bgModel == null)
            {
                _bgModel = new DynamicBackgroundModel(camImage, 1.0f / Properties.Settings.Default.FrameRate);
                _fgModel = new DynamicBackgroundModel(camImage, 5.0f / Properties.Settings.Default.FrameRate);
                //Create image intermediates
                _calc       = new Image8(camImage.Size);
                _foreground = new Image8(camImage.Size);
                _strel3x3   = Morphology.Generate3x3Mask(camImage.Size);
                //Initialize buffer for label markers
                int bufferSize = 0;
                cv.ippiLabelMarkersGetBufferSize_8u_C1R(camImage.Size, &bufferSize);
                if (_markerBuffer != null)
                {
                    Marshal.FreeHGlobal((IntPtr)_markerBuffer);
                    _markerBuffer = null;
                }
                _markerBuffer = (byte *)Marshal.AllocHGlobal(bufferSize);
            }
            else
            {
                _bgModel.UpdateBackground(camImage);
            }
            if (frameNumber >= Properties.Settings.Default.FrameRate * 5)
            {
                _experimentPhase  = ExperimentPhases.ThreePoint;
                _threePointFrame  = 0;
                _threePointPoints = new CalibrationPoints();
            }
        }
示例#9
0
        public Tracker90mmDish(int imageWidth, int imageHeight, IppiPoint dishCenter)
        {
            _foreground   = new Image8(imageWidth, imageHeight);
            _bgSubtracted = new Image8(imageWidth, imageHeight);
            _calc         = new Image8(imageWidth, imageHeight);
            _dishCenter   = dishCenter;
            int bufferSize = 0;

            IppHelper.IppCheckCall(cv.ippiLabelMarkersGetBufferSize_8u_C1R(new IppiSize(imageWidth, imageHeight), &bufferSize));
            _markerBuffer = (byte *)Marshal.AllocHGlobal(bufferSize);
            int momentSize = 0;

            IppHelper.IppCheckCall(ip.ippiMomentGetStateSize_64f(IppHintAlgorithm.ippAlgHintNone, &momentSize));
            _momentState = (IppiMomentState_64f *)Marshal.AllocHGlobal(momentSize);
            //let ipp decide whether to give accurate or fast results
            IppHelper.IppCheckCall(ip.ippiMomentInit_64f(_momentState, IppHintAlgorithm.ippAlgHintNone));
            _frame = 0;
            //populate tracking parameters with default values
            _threshold        = 6;
            _minArea          = 11;
            _maxAllowedArea   = 120;
            _minEccentricity  = 0.3;
            _fullTrustMinArea = 20;
            _imageROI         = new IppiROI(0, 0, imageWidth, imageHeight);
            _searchRegionSize = 90;
            _removeCMOSISBrightLineArtefact = false;
            _strel3x3 = Morphology.Generate3x3Mask(_foreground.Size);
            //The following calculation for FramesInBackground means that after ~30s of movie
            //a stationary object will have dissappeared into the background (at 63% level)
            FramesInBackground      = (int)((30 * 250));
            FramesInitialBackground = 2 * 30 * 250;
            BGUpdateEvery           = 2;
        }
示例#10
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);
        }
示例#11
0
 protected void Dispose(bool IsDisposing)
 {
     if (_background != null)
     {
         _background.Dispose();
         _background = null;
     }
     if (_foreground != null)
     {
         _foreground.Dispose();
         _foreground = null;
     }
     if (_thresholded != null)
     {
         _thresholded.Dispose();
         _thresholded = null;
     }
     if (_calc1 != null)
     {
         _calc1.Dispose();
         _calc1 = null;
     }
     if (_strel != null)
     {
         _strel.Dispose();
         _strel = null;
     }
     if (_angleStore != null)
     {
         System.Runtime.InteropServices.Marshal.FreeHGlobal((IntPtr)_angleStore);
         _angleStore = null;
     }
 }
示例#12
0
        public Tracker90mmDish(int imageWidth, int imageHeight)
        {
            _foreground   = new Image8(imageWidth, imageHeight);
            _calc         = new Image8(imageWidth, imageHeight);
            _labelMarkers = new Image8(imageWidth, imageHeight);
            int bufferSize = 0;

            IppHelper.IppCheckCall(cv.ippiLabelMarkersGetBufferSize_8u_C1R(new IppiSize(imageWidth, imageHeight), &bufferSize));
            _markerBuffer = (byte *)Marshal.AllocHGlobal(bufferSize);
            fixed(IppiMomentState_64s **ppState = &_momentState)
            {
                //let ipp decide whether to give accurate or fast results
                IppHelper.IppCheckCall(ip.ippiMomentInitAlloc_64s(ppState, IppHintAlgorithm.ippAlgHintNone));
            }

            _frame = 0;
            //populate tracking parameters with default values
            _threshold        = 5;
            _minArea          = 10;
            _maxArea          = 300;
            _fullTrustMinArea = 20;
            _imageROI         = new IppiROI(0, 0, imageWidth, imageHeight);
            //The following calculation for FramesInBackground means that after ~30s of movie
            //a stationary object will have dissappeared into the background (at 63% level)
            FramesInBackground      = (int)((30 * 240));
            FramesInitialBackground = 2 * FramesInBackground;
        }
示例#13
0
        public Image8 copy()
        {
            global::System.IntPtr cPtr = libPhotoAssistantImageProcessingPINVOKE.Image8_copy(swigCPtr);
            Image8 ret = (cPtr == global::System.IntPtr.Zero) ? null : new Image8(cPtr, false);

            return(ret);
        }
示例#14
0
        /// <summary>
        /// Generates a circular mask to use in morphological operations
        /// with the anchor in the center
        /// </summary>
        /// <param name="radius">The radius of the mask as maximum distance from center pixel (i.e. radius=0 would be 1-pixel mask)</param>
        /// <returns>The mask</returns>
        public static MorphologyMask GenerateDiskMask(int radius)
        {
            if (radius < 1)
            {
                throw new ArgumentOutOfRangeException("radius");
            }
            //Masks in ipps morphological functions don't really allow for stride
            //unless it is guaranteed, that the pixels within the stride are of value0
            //therefore we generate the mask with the minimum possible width and height
            //that is dividable by 4
            int       diameter   = 1 + 2 * radius;//center pixel is extra
            int       imageWidth = (int)(Math.Ceiling(diameter / 4.0) * 4);
            IppiPoint center     = new IppiPoint(radius, radius);
            Image8    mask       = new Image8(imageWidth, diameter);

            //Set all pixels to 0
            IppHelper.IppCheckCall(ip.ippiSet_8u_C1R(0, mask.Image, mask.Stride, mask.Size));
            //Loop over pixels, check distance and set to 1 if within circle
            for (int x = 0; x < mask.Width; x++)
            {
                for (int y = 0; y < mask.Width; y++)
                {
                    if (Distance.Euclidian(new IppiPoint(x, y), center) <= radius)
                    {
                        *mask[x, y] = 1;
                    }
                }
            }
            //default anchor is in the circle's center
            return(new MorphologyMask(mask, center));
        }
示例#15
0
 /// <summary>
 /// Initializes a new tracker instance
 /// </summary>
 /// <param name="imageWidth">The width of the images to track</param>
 /// <param name="imageHeight">The height of the images to track</param>
 public Tracker(int imageWidth, int imageHeight)
 {
     _currentImage = new Image8(imageWidth, imageHeight);
     _trackThread  = new Worker(TrackThreadRun, false, 500);
     _frames       = new PrCoImageRingBuffer(imageWidth, imageHeight, 100);
     _imageIndex   = 0;
 }
示例#16
0
        /// <summary>
        /// Finds the location of the laser beam in the camera image
        /// </summary>
        /// <param name="image">The current image in which to find the beam</param>
        /// <param name="background">The calculated background image</param>
        /// <param name="calc">Image buffer for intermediate calculations</param>
        /// <param name="foreground">Image buffer for foreground extraction</param>
        /// <returns></returns>
        private IppiPoint FindBeamLocation(Image8 image, Image8 background, Image8 calc, Image8 foreground)
        {
            IppiSize imageSize = new IppiSize(image.Width, image.Height);

            //Clear foreground and calc
            ip.ippiSet_8u_C1R(0, foreground.Image, foreground.Stride, imageSize);
            ip.ippiSet_8u_C1R(0, calc.Image, calc.Stride, imageSize);
            //Perform background subtraction
            cv.ippiAbsDiff_8u_C1R(image.Image, image.Stride, background.Image, background.Stride, calc.Image, calc.Stride, imageSize);
            //remove noise via 3x3 median filtering
            ip.ippiFilterMedianWeightedCenter3x3_8u_C1R(calc[2, 2], calc.Stride, foreground[2, 2], foreground.Stride, new IppiSize(image.Width - 4, image.Height - 4), 1);
            //threshold difference
            ip.ippiThreshold_LTVal_8u_C1IR(foreground.Image, foreground.Stride, imageSize, 111, 0);
            ip.ippiThreshold_GTVal_8u_C1IR(foreground.Image, foreground.Stride, imageSize, 110, 255);
            //perform closing operation - 2 step to put result back into foreground
            _strel3x3.Dilate(foreground, calc, imageSize);
            _strel3x3.Erode(calc, foreground, imageSize);
            //feature extraction
            int nMarkers = 0;

            cv.ippiLabelMarkers_8u_C1IR(foreground.Image, foreground.Stride, imageSize, 1, 254, IppiNorm.ippiNormInf, &nMarkers, _markerBuffer);
            BlobWithMoments[] blobsDetected = BlobWithMoments.ExtractBlobs(foreground, nMarkers, new IppiROI(0, 0, image.Width, image.Height));
            //re-threshold foreground for display
            ip.ippiThreshold_LTVal_8u_C1IR(foreground.Image, foreground.Stride, imageSize, 1, 0);   //6
            ip.ippiThreshold_GTVal_8u_C1IR(foreground.Image, foreground.Stride, imageSize, 0, 255); //5
            long maxArea  = 0;
            int  maxIndex = -1;

            if (blobsDetected != null)
            {
                for (int i = 0; i < blobsDetected.Length; i++)
                {
                    if (blobsDetected[i] == null)
                    {
                        break;
                    }
                    //Simply note down the largest blob
                    if (blobsDetected[i].Area > maxArea)
                    {
                        maxArea  = blobsDetected[i].Area;
                        maxIndex = i;
                    }
                }
                // System.Diagnostics.Debug.WriteLine("Area: {0}", blobsDetected[maxIndex].Area);
                // System.Diagnostics.Debug.WriteLine("Eccentricity: {0}", blobsDetected[maxIndex].Eccentricity);
                if (maxArea > 30)
                {
                    return(blobsDetected[maxIndex].Centroid);
                }
                else
                {
                    return(new IppiPoint(-1, -1));
                }
            }
            else
            {
                return(new IppiPoint(-1, -1));
            }
        }
示例#17
0
 /// <summary>
 /// Multiplies the mask with the image effectively removing
 /// parts outside the mask
 /// </summary>
 /// <param name="image">The image to mask</param>
 public void MaskImage(Image8 image)
 {
     if (!_maskValid)
     {
         GenerateMask();
     }
     IppHelper.IppCheckCall(ip.ippiMul_8u_C1IRSfs(_mask.Image, _mask.Stride, image.Image, image.Stride, image.Size, 0));
 }
示例#18
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="im">The initial background image</param>
 /// <param name="fUpdate">The fraction of the current image to use for updating the background</param>
 public DynamicBackgroundModel(Image8 im, float fUpdate) : base(im)
 {
     if (0 > fUpdate || 1 < fUpdate)
     {
         throw new ArgumentOutOfRangeException("fUpdate", "The update fraction has to be bigger than 0 and smaller than 1");
     }
     FractionUpdate = fUpdate;
 }
示例#19
0
 public override void UpdateBackground(Image8 im)
 {
     if (im.Width != width || im.Height != height)
     {
         throw new ArgumentException("The supplied image must have the same dimensions as the background");
     }
     IppHelper.IppCheckCall(cv.ippiAddWeighted_8u32f_C1IR(im.Image, im.Stride, background.Image, background.Stride, im.Size, FractionUpdate));
 }
示例#20
0
 /// <summary>
 /// Disposes the mask image
 /// </summary>
 public void Dispose()
 {
     if (_mask != null)
     {
         _mask.Dispose();
         _mask = null;
     }
 }
示例#21
0
        /// <summary>
        /// Performs an opening operation in the specified ROI using the specified
        /// neighborhood mask
        /// </summary>
        /// <param name="imIn">The image to perform the opening operation on</param>
        /// <param name="imOpened">The image after the opening operation</param>
        /// <param name="imCalc">Intermediate buffer for processing</param>
        /// <param name="neighborhood">The mask for the opening operation</param>
        /// <param name="region">The image region in which to perform the operation</param>
        public static void Open(Image8 imIn, Image8 imOpened, Image8 imCalc, MorphologyMask neighborhood, IppiROI roi)
        {
            //Modify region we operate on to allow mask overhang
            var inner = new IppiROI(roi.X + neighborhood.Anchor.x, roi.Y + neighborhood.Anchor.y, roi.Width - neighborhood.Mask.Width, roi.Height - neighborhood.Mask.Height);

            IppHelper.IppCheckCall(ip.ippiErode_8u_C1R(imIn[inner.TopLeft], imIn.Stride, imCalc[inner.TopLeft], imCalc.Stride, inner.Size, neighborhood.Mask.Image, neighborhood.Mask.Size, neighborhood.Anchor));
            IppHelper.IppCheckCall(ip.ippiDilate_8u_C1R(imCalc[inner.TopLeft], imCalc.Stride, imOpened[inner.TopLeft], imOpened.Stride, inner.Size, neighborhood.Mask.Image, neighborhood.Mask.Size, neighborhood.Anchor));
        }
示例#22
0
 /// <summary>
 /// Uses multiplication to draw a mask onto an image
 /// </summary>
 /// <param name="maskImage">The mask image to draw</param>
 /// <param name="image">The camera image to draw the mask on</param>
 public static void DrawMask(Image8 maskImage, Image8 image)
 {
     if (maskImage.Size.width != image.Size.width || maskImage.Size.height != image.Size.height)
     {
         throw new ArgumentException("Both images need to have the same dimensions");
     }
     ip.ippiMul_8u_C1IRSfs(maskImage.Image, maskImage.Stride, image.Image, image.Stride, image.Size, 0);
 }
示例#23
0
        /// <summary>
        /// Performs a 3x3 opening operation on an image - removes speckles
        /// </summary>
        /// <param name="imIn">The image to perform an opening operation on</param>
        /// <param name="imOpened">The image after the opening operation</param>
        /// <param name="imCalc">Intermediate image for semi-processed version</param>
        /// <param name="region">The ROI in which to perform the operation</param>
        public static void Open3x3(Image8 imIn, Image8 imOpened, Image8 imCalc, IppiROI roi)
        {
            //Modify region we operate on to allow mask overhang
            var inner = new IppiROI(roi.X + 1, roi.Y + 1, roi.Width - 3, roi.Height - 3);

            IppHelper.IppCheckCall(ip.ippiErode3x3_8u_C1R(imIn[inner.TopLeft], imIn.Stride, imCalc[inner.TopLeft], imCalc.Stride, inner.Size));
            IppHelper.IppCheckCall(ip.ippiDilate3x3_8u_C1R(imCalc[inner.TopLeft], imCalc.Stride, imOpened[inner.TopLeft], imOpened.Stride, inner.Size));
        }
示例#24
0
 public void Dispose()
 {
     if (_mask != null)
     {
         _mask.Dispose();
         _mask = null;
     }
     IsDisposed = true;
 }
示例#25
0
        /// <summary>
        /// Process the next frame
        /// </summary>
        /// <param name="frameNumber">The frame index</param>
        /// <param name="camImage">The camera image</param>
        /// <param name="poi">The fish location</param>
        /// <returns>Whether experiment should continue or not</returns>
        public override bool ProcessNext(int frameNumber, Image8 camImage, out IppiPoint?poi)
        {
            base.ProcessNext(frameNumber, camImage, out poi);
            if (_scanner == null)
            {
                System.Diagnostics.Debug.WriteLine("Scanner was not initialized. Terminating experiment");
                return(false);
            }
            int writeEvery = Properties.Settings.Default.FrameRate * 4;

            if (frameNumber % writeEvery == writeEvery - 1)
            {
                _laser.LaserPower = Properties.Settings.Default.LaserCalibPowermW;
            }
            else
            {
                _laser.LaserPower = 0;
            }
            _lastFrame = frameNumber;
            if (frameNumber >= _totalFrames)
            {
                return(false);
            }
            BlobWithMoments fish = null;

            // Every 4s we turn on the laser - those frames won't be tracked but the image will be saved
            if (frameNumber % writeEvery != 0)
            {
                fish = Tracker.Track(camImage);
            }
            if (fish != null)
            {
                poi = new IppiPoint(fish.Centroid.x, fish.Centroid.y);
                if (_scanner != null)
                {
                    _scanner.Hit(poi.GetValueOrDefault());
                }
            }
            if (_trackWriter != null)
            {
                if (fish != null)
                {
                    _trackWriter.WriteLine("{0}\t{1}\t{2}\t{3}", frameNumber, fish.Centroid.x, fish.Centroid.y, fish.Angle);
                }
                else
                {
                    _trackWriter.WriteLine("NaN\tNaN\tNaN\tNaN");
                }
                // Write image of Laser On frames and the two surrounding frames on each side to file
                if (frameNumber % writeEvery <= 2 || frameNumber % writeEvery >= writeEvery - 2)
                {
                    _imageWriter.WriteFrame(camImage);
                }
            }
            return(true);
        }
示例#26
0
        /*
         *
         * /// <summary>
         * /// Extract the next image
         * /// </summary>
         * /// <returns></returns>
         * public Image8 Extract() {
         *  var image = new Image8(width, height);
         *  var bufferLength = (uint)(width * height);
         *  uint frameIndex;
         *  CheckError(IMAQdx.IMAQdxGetImageData(session, image.Image, bufferLength, IMAQdx.IMAQdxBufferNumberMode.IMAQdxBufferNumberModeNext, 0, out frameIndex));
         *  return image;
         * }
         *
         * /// <summary>
         * /// Extract the next image and return its index
         * /// </summary>
         * /// <param name="frameIndex"></param>
         * /// <returns></returns>
         * public Image8 Extract(out uint frameIndex) {
         *  var image = new Image8(width, height);
         *  var bufferLength = (uint)(width * height);
         *  CheckError(IMAQdx.IMAQdxGetImageData(session, image.Image, bufferLength, IMAQdx.IMAQdxBufferNumberMode.IMAQdxBufferNumberModeNext, 0, out frameIndex));
         *  return image;
         * }
         *
         * /// <summary>
         * /// Extract the image with the specified index
         * /// </summary>
         * /// <param name="frameIndex"></param>
         * /// <returns></returns>
         * public Image8 Extract(uint frameIndex) {
         *  var image = new Image8(width, height);
         *  uint actualFrameIndex;
         *  CheckError(IMAQdx.IMAQdxGetImageData(session, image.Image, bufferLength, IMAQdx.IMAQdxBufferNumberMode.IMAQdxBufferNumberModeBufferNumber, frameIndex, out actualFrameIndex));
         *  if (actualFrameIndex != frameIndex)
         *      System.Diagnostics.Debug.WriteLine("Warning: Expected frameIndex " + frameIndex + ", got frameIndex " + actualFrameIndex);
         *  return image;
         * }
         *
         * /// <summary>
         * /// Extract the next image into an existing Image8
         * /// </summary>
         * /// <param name="imageToReuse"></param>
         * public void Extract(Image8 imageToReuse) {
         *  if (imageToReuse.Width != width || imageToReuse.Height != height)
         *      throw new Exception("Cannot reuse image, dimensions should be " + width + " x " + height + ", not " + imageToReuse.Width + " x " + imageToReuse.Height);
         *  uint frameIndex;
         *  CheckError(IMAQdx.IMAQdxGetImageData(session, imageToReuse.Image, bufferLength, IMAQdx.IMAQdxBufferNumberMode.IMAQdxBufferNumberModeNext, 0, out frameIndex));
         * }
         *
         * /// <summary>
         * /// Extract the next image into an existing Image8 and return its index
         * /// </summary>
         * /// <param name="frameIndex"></param>
         * /// <returns></returns>
         * public void Extract(Image8 imageToReuse, out uint frameIndex) {
         *  if (imageToReuse.Width != width || imageToReuse.Height != height)
         *      throw new Exception("Cannot reuse image, dimensions should be " + width + " x " + height + ", not " + imageToReuse.Width + " x " + imageToReuse.Height);
         *  CheckError(IMAQdx.IMAQdxGetImageData(session, imageToReuse.Image, bufferLength, IMAQdx.IMAQdxBufferNumberMode.IMAQdxBufferNumberModeNext, 0, out frameIndex));
         * }*/

        /// <summary>
        /// Extract the image with the specified index into an existing Image8
        /// </summary>
        /// <param name="frameIndex"></param>
        /// <returns></returns>
        public void Extract(Image8 imageToReuse, uint frameIndex)
        {
            uint actualFrameIndex;

            CheckError(IMAQdx.IMAQdxGetImageData(session, imageToReuse.Image, bufferLength, IMAQdx.IMAQdxBufferNumberMode.IMAQdxBufferNumberModeBufferNumber, frameIndex, out actualFrameIndex));
            if (actualFrameIndex != frameIndex)
            {
                System.Diagnostics.Debug.WriteLine("Warning: Expected frameIndex " + frameIndex + ", got frameIndex " + actualFrameIndex);
            }
        }
示例#27
0
 public override bool ProcessNext(int frameNumber, Image8 camImage, out IppiPoint?poi)
 {
     //create tracker if necessary
     if (Tracker == null)
     {
         Tracker = CreateFishTracker(camImage.Width, camImage.Height, new IppiPoint(camImage.Width / 2, camImage.Height / 2));
     }
     poi = null;
     return(true);
 }
示例#28
0
 /// <summary>
 /// Initializes all internal buffers based on the
 /// size of the current tracking region
 /// </summary>
 protected virtual void InitializeImageBuffers()
 {
     //create images
     _background  = new Image8(_imageSize);
     _foreground  = new Image8(_imageSize);
     _thresholded = new Image8(_imageSize);
     _calc1       = new Image8(_imageSize);
     //blank foreground - to ensure that the border is always black!
     ip.ippiSet_8u_C1R(0, _foreground.Image, _foreground.Stride, _imageSize);
 }
示例#29
0
 public Graph(int width, int height)
 {
     Width  = width;
     Height = height;
     //Initialize our color placeholder
     _color = (byte *)Marshal.AllocHGlobal(3).ToPointer();
     //Initialize new canvas for the bgr pixels (hence width*3)
     _canvas = new Image8(width * 3, height);
     ClearImage();
 }
示例#30
0
 //Construct 32F image using an 8-bit unsigned image as input
 public Image32F(Image8 im)
 {
     Width  = im.Width;
     Height = im.Height;
     Size   = new IppiSize(Width, Height);
     Stride = 4 * Width;
     Image  = (float *)Marshal.AllocHGlobal(Stride * Height).ToPointer();
     //convert image
     IppHelper.IppCheckCall(ip.ippiConvert_8u32f_C1R(im.Image, im.Stride, Image, Stride, Size));
 }