Example #1
0
 public PointAnalysis(Bout bout, IppiPoint coordinate, IppiPoint_32f smoothenedCoordinate, float instantSpeed)
 {
     CompletedBout        = bout;
     OriginalCoordinate   = coordinate;
     SmoothenedCoordinate = smoothenedCoordinate;
     InstantSpeed         = instantSpeed;
 }
Example #2
0
        /// <summary>
        /// Detects bouts and returns summary information
        /// </summary>
        /// <param name="isb">The instant speed trace</param>
        /// <param name="speedThreshold">Speeds below this threshold will be set to 0</param>
        /// <param name="minFramesPerBout">For a movement to be called a bout we require at least this number of frames</param>
        /// <param name="maxFramesAtPeak">Bouts should have clearly defined peaks. Bouts with a peak longer than this number get rejected</param>
        /// <param name="frameRate">The framerate used for acquisition</param>
        /// <returns>A bout summary info structure</returns>
        public BoutSummary AnalyzeBouts(InstantSpeedBuffer isb, float speedThreshold, int minFramesPerBout, int maxFramesAtPeak, int frameRate)
        {
            if (IsDisposed)
            {
                throw new ObjectDisposedException(this.ToString());
            }

            if (_isCalc == null)
            {
                _isCalc = new InstantSpeedBuffer(isb.Size.width);
            }
            else if (_isCalc.Size.width != isb.Size.width)
            {
                _isCalc.Dispose();
                _isCalc = new InstantSpeedBuffer(isb.Size.width);
            }

            BoutSummary retval = new BoutSummary();
            Bout        b      = new Bout();

            int i = 0;

            //threshold the speed trace - copy result into our calculation buffer
            ip.ippiThreshold_LTVal_32f_C1R(isb.Buffer, isb.Stride, _isCalc.Buffer, _isCalc.Stride, isb.Size, speedThreshold, 0);

            while (i < _isCalc.Size.width)
            {
                if (_isCalc[i] == 0)
                {
                    i++;
                    continue;
                }
                else//found potential bout start since speed above threshold
                {
                    int peaklength = 0;
                    b.BoutStart         = i;
                    b.PeakSpeed         = _isCalc[i];
                    b.BoutPeak          = i;
                    b.TotalDisplacement = _isCalc[i] / frameRate;
                    //loop over following frames collecting all frames that belong to the bout
                    while (i < _isCalc.Size.width && _isCalc[i] > 0)
                    {
                        if (_isCalc[i] > b.PeakSpeed)
                        {
                            b.PeakSpeed = _isCalc[i];
                            b.BoutPeak  = i;
                            peaklength  = 0;                //new peakspeed found, reset peaklength
                        }
                        else if (_isCalc[i] == b.PeakSpeed) //another frame with the same speed as our peak
                        {
                            peaklength++;
                        }
                        b.TotalDisplacement += _isCalc[i] / frameRate;
                        i++;
                    }
                    b.BoutEnd = i - 1;
                    //check our bout criteria
                    if ((b.BoutEnd - b.BoutStart + 1) >= minFramesPerBout && peaklength <= maxFramesAtPeak)
                    {
                        //we have a valid bout
                        if (b.BoutStart == b.BoutPeak)
                        {
                            b.BoutStart--;
                        }
                        retval.NumberOfBouts++;
                        retval.AverageDisplacement += b.TotalDisplacement;
                        retval.AveragePeakSpeed    += b.PeakSpeed;
                        retval.AverageLength       += (b.BoutEnd - b.BoutStart + 1);
                    }
                }//found potential bout
            }
            retval.AverageDisplacement /= retval.NumberOfBouts;
            retval.AveragePeakSpeed    /= retval.NumberOfBouts;
            retval.AverageLength       /= retval.NumberOfBouts;
            return(retval);
        }
Example #3
0
        /// <summary>
        /// Processes the next point, filtering its position
        /// computing speeds and detecting bouts
        /// </summary>
        /// <param name="coordinate">The coordinate to analyze</param>
        /// <returns>The analysis of the given coordinate</returns>
        public PointAnalysis ProcessNextPoint(IppiPoint coordinate)
        {
            //set up locals for processing
            float x = coordinate.x;
            float y = coordinate.y;
            float xSmooth, ySmooth, speed;

            xSmooth = ySmooth = speed = 0;
            //optional filtered speed
            float spdSmooth = 0;

            //filter x-coordinate
            sp.ippsFIR_32f(&x, &xSmooth, 1, _filterStateX);
            //filter y-coordinate
            sp.ippsFIR_32f(&y, &ySmooth, 1, _filterStateY);
            //compute instant speed
            speed  = (float)Math.Sqrt((xSmooth - _lastX) * (xSmooth - _lastX) + (ySmooth - _lastY) * (ySmooth - _lastY));
            speed *= 240;
            //if requested, also filter the instant-speed value
            if (_spdTapLength > 0)
            {
                sp.ippsFIR_32f(&speed, &spdSmooth, 1, _filterStateSpd);
            }
            else
            {
                spdSmooth = speed;
            }
            //update last coordinates
            _lastX = xSmooth;
            _lastY = ySmooth;

            //Bout detection
            if (_boutDetectionState.InPutativeBout)                                                                                    //we are currently adding frames to a new putative bout
            {
                if (spdSmooth < _speedThreshold)                                                                                       //putative bout is finished
                {
                    _boutDetectionState.InPutativeBout = false;                                                                        //reset
                    if (_boutDetectionState.FramesInBout >= _minFramesPerBout && _boutDetectionState.FramesAtPeak <= _maxFramesAtPeak) //bout was valid, fill bout structure and return it
                    {
                        Bout bout = new Bout();
                        bout.BoutEnd   = _index - 1;
                        bout.BoutStart = _boutDetectionState.StartFrame;
                        bout.BoutPeak  = _boutDetectionState.PeakFrame;
                        if (bout.BoutPeak == bout.BoutStart)
                        {
                            bout.BoutStart--;//don't start bout on peakframe
                        }
                        bout.PeakSpeed          = _boutDetectionState.PeakSpeed;
                        bout.TotalDisplacement  = _boutDetectionState.TotalDisplacement;
                        bout.StartingCoordinate = _boutDetectionState.StartingCoordinate;
                        bout.FinishCoordinate   = new IppiPoint_32f(xSmooth, ySmooth);
                        //don't forget to update the index before we return
                        _index++;
                        return(new PointAnalysis(bout, coordinate, new IppiPoint_32f(xSmooth, ySmooth), spdSmooth));
                    }
                }
                else//putative bout continues
                {
                    _boutDetectionState.FramesInBout++;
                    _boutDetectionState.TotalDisplacement += spdSmooth / _frameRate;
                    if (spdSmooth > _boutDetectionState.PeakSpeed)//new peak-speed detected
                    {
                        _boutDetectionState.PeakSpeed    = spdSmooth;
                        _boutDetectionState.PeakFrame    = _index;
                        _boutDetectionState.FramesAtPeak = 1;            //reset
                    }
                    else if (spdSmooth == _boutDetectionState.PeakSpeed) //maybe not the best criterion - equality of float values very unlikely
                    {
                        _boutDetectionState.FramesAtPeak++;
                    }
                }
            }
            else//currently the fish is stationary
            {
                if (spdSmooth > _speedThreshold)//we should start a new putative bout
                {
                    _boutDetectionState.StartBout(spdSmooth, _index, _frameRate);
                    _boutDetectionState.StartingCoordinate.x = xSmooth;
                    _boutDetectionState.StartingCoordinate.y = ySmooth;
                }
            }
            //advance index
            _index++;
            //return our analysis
            return(new PointAnalysis(coordinate, new IppiPoint_32f(xSmooth, ySmooth), spdSmooth));
        }