public void WriteFrame(Image16 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++; } }
/// <summary> /// Creates a new accumulation buffer /// </summary> /// <param name="accumulationWindow">The number of images to accumulate across</param> /// <param name="width">The width of each image</param> /// <param name="height">The height of each image</param> public AccumulationBuffer16(uint accumulationWindow, int width, int height) { if (accumulationWindow < 1) { throw new ArgumentOutOfRangeException(nameof(accumulationWindow), "Has to be larger than 0"); } if (width < 1) { throw new ArgumentOutOfRangeException(nameof(width), "Has to be larger than 0"); } if (height < 1) { throw new ArgumentOutOfRangeException(nameof(height), "Has to be larger than 0"); } _images = new Image16[accumulationWindow]; for (int i = 0; i < accumulationWindow; i++) { //create images and set pixels to 0 _images[i] = new Image16(width, height); ip.ippiSet_16u_C1R(0, _images[i].Image, _images[i].Stride, _images[i].Size); } //create our cumulant image and set to 0 _accumulated = new Image16(width, height); ip.ippiSet_16u_C1R(0, _accumulated.Image, _accumulated.Stride, _accumulated.Size); }
/// <summary> /// Adds a new image to the rolling cumulant /// </summary> /// <param name="im">The image to add</param> /// <returns>The new accumulated image after the addition</returns> public Image16 AppendImage(Image16 im) { if (im.Width != _accumulated.Width || im.Height != _accumulated.Height) { throw new ArgumentOutOfRangeException(nameof(im), "Dimensions of added image must match dimensions of buffer."); } uint ixIn = (uint)(_counter % _images.Length);//new image gets added in this position //add the new image and subtract the image that is currently at ixIn from _accumulated //note that these operations can lead to saturation ip.ippiSub_16u_C1IRSfs(_images[ixIn].Image, _images[ixIn].Stride, _accumulated.Image, _accumulated.Stride, _accumulated.Size, 0); ip.ippiAdd_16u_C1IRSfs(im.Image, im.Stride, _accumulated.Image, _accumulated.Stride, _accumulated.Size, 0); //copy new image into buffer ip.ippiCopy_16u_C1R(im.Image, im.Stride, _images[ixIn].Image, _images[ixIn].Stride, im.Size); _counter++; return(_accumulated); }
/// <summary> /// Writes a 16-bit greyscale image to a multipage tiff file. /// </summary> /// <param name="frame">The 16-bit greyscale image to write</param> void WritePage(Image16 frame) { _tiffFile.SetField(TiffTag.IMAGEWIDTH, frame.Width); _tiffFile.SetField(TiffTag.IMAGELENGTH, frame.Height); _tiffFile.SetField(TiffTag.BITSPERSAMPLE, 16); _tiffFile.SetField(TiffTag.SAMPLESPERPIXEL, 1); _tiffFile.SetField(TiffTag.ROWSPERSTRIP, frame.Height); _tiffFile.SetField(TiffTag.SUBFILETYPE, FileType.PAGE); if (_buffer == null || _buffer.Length != frame.Height * frame.Stride) { _buffer = new byte[frame.Height * frame.Stride]; } Marshal.Copy((IntPtr)frame.Image, _buffer, 0, frame.Stride * frame.Height); for (int row = 0; row < frame.Height; row++) { _tiffFile.WriteScanline(_buffer, row * frame.Stride, row, 0); } _tiffFile.WriteDirectory(); }
/// <summary> /// Free resources /// </summary> public void Dispose() { if (_images != null) { for (int i = 0; i < _images.Length; i++) { if (_images[i] != null) { _images[i].Dispose(); } } _images = null; } if (_accumulated != null) { _accumulated.Dispose(); _accumulated = null; } }