/// <summary> /// Read a block of image file to a new image. /// </summary> /// <param name="filename"></param> /// <param name="start">Coordinates of the first pixel to read.</param> /// <param name="size">Size of the block to read.</param> /// <param name="dataType">Data type of the image. Used only if reading .raw images. Leave empty to guess data type based on file size.</param> /// <returns></returns> public Pi2Image ReadBlock(string filename, Vec3 start, Vec3 size, ImageDataType dataType = ImageDataType.Unknown) { string imageName = "image_" + RandomString(); PiLib.RunAndCheck(Handle, $"readblock({imageName}, {filename}, {(int)start.X}, {(int)start.Y}, {(int)start.Z}, {(int)size.X}, {(int)size.Y}, {(int)size.Z}, {dataType})"); return(new Pi2Image(this, imageName, true)); }
/// <summary> /// Returns the name and path to the file that has been mapped to the given image, or an empty string if no mapping has been made. /// </summary> /// <param name="image"></param> /// <returns></returns> public string GetMapFile(Pi2Image image) { Pi2Value str = NewString(); PiLib.RunAndCheck(Handle, $"getmapfile({image.Name}, {str.Name})"); return(str); }
/// <summary> /// Creates a new Pi2 string value. /// </summary> /// <param name="s">Value that will be assigned to the newly created object.</param> /// <returns>Pi2 object representing the value.</returns> public Pi2Value NewString(string s = "") { string name = "value_" + RandomString(); PiLib.RunAndCheck(Handle, $"newvalue({name}, \"string\", {s})"); return(new Pi2Value(this, name, true)); }
/// <summary> /// Read image file to a new image. /// </summary> /// <param name="filename"></param> /// <returns></returns> public Pi2Image Read(string filename) { string imageName = "image_" + RandomString(); PiLib.RunAndCheck(Handle, $"read({imageName}, {filename})"); return(new Pi2Image(this, imageName, true)); }
/// <summary> /// Get a value of a metadata item. /// </summary> /// <param name="img"></param> /// <param name="name"></param> /// <param name="defaultValue"></param> /// <param name="i"></param> /// <param name="j"></param> /// <returns></returns> public string GetMeta(Pi2Image img, string name, string defaultValue, int i = 0, int j = 0) { Pi2Value value = NewString(); PiLib.RunAndCheck(Handle, $"getmeta({img.Name}, {name}, {value.Name}, {i}, {j}, {defaultValue})"); return(value.AsString()); }
/// <summary> /// Creates a new Pi2 image object. /// </summary> /// <param name="width"></param> /// <param name="height"></param> /// <param name="depth"></param> /// <param name="dt"></param> /// <returns></returns> public Pi2Image NewImage(ImageDataType dt, int width = 1, int height = 1, int depth = 1) { string imageName = "image_" + RandomString(); PiLib.RunAndCheck(Handle, $"newimage({imageName}, {dt}, {width}, {height}, {depth})"); return(new Pi2Image(this, imageName, true)); }
/// <summary> /// Tests if the given file name or prefix can be used successfully in Read command. /// </summary> /// <param name="filename"></param> /// <returns></returns> public bool IsImageFile(string filename) { using (Pi2Image result = NewImage(ImageDataType.UInt8)) { PiLib.RunAndCheck(Handle, $"isimagefile({filename}, {result.Name})"); return(result.GetValue() != 0); } }
/// <summary> /// Get pointer to data of this image. /// The pointer is valid until this image object is modified in Pi2. /// </summary> /// <param name="width"></param> /// <param name="height"></param> /// <param name="depth"></param> /// <param name="dataType"></param> /// <returns></returns> public IntPtr GetData(out Int64 width, out Int64 height, out Int64 depth, out ImageDataType dataType) { IntPtr data = PiLib.GetImage(Pi.Handle, Name, out width, out height, out depth, out dataType); if (data == IntPtr.Zero || dataType == ImageDataType.Unknown) { throw new InvalidOperationException("Image " + Name + " is inaccessible because it has been deleted from the Pi system."); } return(data); }
/// <summary> /// Gets the value of this object as a string. /// Throws an exception if the value is not a string. /// </summary> /// <returns></returns> public string AsString() { string s = PiLib.GetString(Pi.Handle, Name); if (s == null) { throw new InvalidOperationException($"The object {Name} is not a string."); } return(s); }
/// <summary> /// Retrieves list of metadata item keys. /// </summary> /// <param name="img"></param> /// <returns></returns> public string[] ListMeta(Pi2Image img) { Pi2Value value = NewString(); PiLib.RunAndCheck(Handle, $"listmeta({img.Name}, {value.Name})"); string s = value.AsString(); if (String.IsNullOrEmpty(s)) { return(new string[0]); } return(s.Split(new string[] { ", " }, StringSplitOptions.None)); }
/// <summary> /// Reads dimensions and data type of given image file. /// </summary> /// <param name="filename">Name of file to examine.</param> /// <param name="dimensions">Dimension of the image. Returns zero dimensions if the image file could not be read.</param> /// <param name="dataType">Data type of the image. Returns Unknown if the image could not be read.</param> public void GetImageInfo(string filename, out Vec3 dimensions, out ImageDataType dataType) { dimensions = new Vec3(); dataType = ImageDataType.Unknown; using (Pi2Image result = NewImage(ImageDataType.UInt32, 4)) { PiLib.RunAndCheck(Handle, $"fileinfo({filename}, {result.Name})"); dimensions.X = result.GetValue(0); dimensions.Y = result.GetValue(1); dimensions.Z = result.GetValue(2); dataType = (ImageDataType)result.GetValue(3); } }
/// <summary> /// Disposes resources. /// </summary> /// <param name="disposing"></param> protected virtual void Dispose(bool disposing) { if (disposed) { return; } if (disposing) { // Free any other managed objects here. } if (OwnsHandle && Handle != IntPtr.Zero) { PiLib.DestroyPI(Handle); Handle = IntPtr.Zero; OwnsHandle = false; } disposed = true; }
/// <summary> /// Disposes resources. /// </summary> /// <param name="disposing"></param> protected virtual void Dispose(bool disposing) { if (disposed) { return; } if (disposing) { // Free any other managed objects here. } if (ImageName != String.Empty) { // Delete image from Pi ssytem PiLib.Run(Pi.Handle, $"clear({ImageName})"); ImageName = String.Empty; } disposed = true; }
/// <summary> /// Disposes resources. /// </summary> /// <param name="disposing"></param> protected virtual void Dispose(bool disposing) { if (disposed) { return; } if (disposing) { // Free any other managed objects here. } if (!String.IsNullOrEmpty(Name)) { // Delete image from Pi ssytem if (OwnsHandle) { PiLib.Run(Pi.Handle, $"clear({Name})"); } Name = String.Empty; } disposed = true; }
/// <summary> /// Scales input image and stores result to output image. /// </summary> /// <param name="inImg">Input image.</param> /// <param name="outImg">Output image. If scale factor is zero, the input image is scaled to the size of the output image.</param> /// <param name="scaleFactor">Scaling factor. If nonzero, the output image size is calculated from scaling factor and input image size. If zero, the input image is scaled to the size of the output image.</param> public void Scale(Pi2Image inImg, Pi2Image outImg, float scaleFactor = 0) { // TODO: Vector scaling factor, interpolation mode, boundary condition. PiLib.RunAndCheck(Handle, $"scale({inImg.Name}, {outImg.Name}, {scaleFactor.ToString(CultureInfo.InvariantCulture)})"); }
/// <summary> /// Generate a grayscale ramp. /// </summary> /// <param name="img">Target image. Existing pixel values will be lost.</param> /// <param name="dimension">Dimension where gray values increase.</param> public void Ramp(Pi2Image img, int dimension) { PiLib.RunAndCheck(Handle, $"ramp({img.Name}, {dimension})"); }
/// <summary> /// Generate additive Gaussian noise. /// </summary> /// <param name="img">Target image where noise will be added.</param> /// <param name="mean">Mean of the noise.</param> /// <param name="stddev">Standard deviation of the noise.</param> public void Noise(Pi2Image img, float mean = 0.0f, float stddev = 50.0f) { PiLib.RunAndCheck(Handle, $"noise({img.Name}, {mean.ToString(CultureInfo.InvariantCulture)}, {stddev.ToString(CultureInfo.InvariantCulture)})"); }
/// <summary> /// Divide img by img2 and place the result to img. /// </summary> /// <param name="img">The first image. The result will be placed to this image.</param> /// <param name="img2">The seconds image.</param> /// <param name="allowBroadcast">Set to true to allow size of parameter image differ from size of input image. If there is a need to access pixel outside of parameter image, the nearest value inside the image is taken instead.If set to false, dimensions of input and parameter images must be equal. If set to true, the parameter image is always loaded in its entirety in distributed processing mode.</param> public void Divide(Pi2Image img, Pi2Image img2, bool allowBroadcast = false) { PiLib.RunAndCheck(Handle, $"divide({img.Name}, {img2.Name}, {allowBroadcast.ToString(CultureInfo.InvariantCulture)})"); }
/// <summary> /// Set value of pixel at specified location. /// </summary> /// <param name="img"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="z"></param> /// <param name="value"></param> public void Set(Pi2Image img, int x, int y, int z, float value) { PiLib.RunAndCheck(Handle, String.Format(CultureInfo.InvariantCulture, "set({0}, [{1}, {2}, {3}], {4})", img.Name, x, y, z, value)); }
/// <summary> /// Subtract an image from a constant. /// </summary> /// <param name="img"></param> /// <param name="value"></param> public void InvSubtract(Pi2Image img, float value) { PiLib.RunAndCheck(Handle, $"invsubtract({img.Name}, {value.ToString(CultureInfo.InvariantCulture)})"); }
/// <summary> /// Divide image by a constant. /// </summary> /// <param name="img"></param> /// <param name="value"></param> public void Divide(Pi2Image img, float value) { PiLib.RunAndCheck(Handle, $"divide({img.Name}, {value.ToString(CultureInfo.InvariantCulture)})"); }
/// <summary> /// Add two images and place the result to the first one. /// </summary> /// <param name="img"></param> /// <param name="img2"></param> public void Add(Pi2Image img, Pi2Image img2) { PiLib.RunAndCheck(Handle, $"add({img.Name}, {img2.Name})"); }
/// <summary> /// Make pixels of img equal those of img2. /// </summary> /// <param name="img"></param> /// <param name="img2"></param> public void Set(Pi2Image img, Pi2Image img2) { PiLib.RunAndCheck(Handle, $"set({img.Name}, {img2.Name})"); }
/// <summary> /// Converts img to specified data type in-place. /// Does not scale pixel values. /// </summary> /// <param name="img"></param> /// <param name="dt"></param> public void Convert(Pi2Image img, ImageDataType dt) { PiLib.RunAndCheck(Handle, $"convert({img.Name}, {dt})"); }
/// <summary> /// Rotates input image 90 degrees clockwise. /// </summary> /// <param name="inImg"></param> /// <param name="outImg"></param> public void Rot90CW(Pi2Image inImg, Pi2Image outImg) { PiLib.RunAndCheck(Handle, $"rot90cw({inImg.Name}, {outImg.Name})"); }
/// <summary> /// Copies pixels of the source image to the target image to the specified location. /// Does not change the size of the target image. /// </summary> /// <param name="target"></param> /// <param name="source"></param> /// <param name="position"></param> public void Copy(Pi2Image source, Pi2Image target, Vec3 position) { PiLib.RunAndCheck(Handle, $"copy({source.Name}, {target.Name}, {ToIntVec(position)})"); }
/// <summary> /// Copies pixels of source image to target image. /// Converts data type if required. /// </summary> /// <param name="source"></param> /// <param name="target"></param> public void Copy(Pi2Image source, Pi2Image target) { PiLib.RunAndCheck(Handle, $"copy({source.Name}, {target.Name})"); }
/// <summary> /// Performs backprojection part of filtered backprojection reconstruction. /// </summary> /// <param name="preprocessed">Projections processed using FBPPreprocess command.</param> /// <param name="output">Reconstruction will be placed in this image.</param> /// <param name="settings"></param> public void FBP(Pi2Image preprocessed, Pi2Image output, string settings) { PiLib.RunAndCheck(Handle, $"fbp({preprocessed.Name}, {output.Name}, {settings})"); }
/// <summary> /// Crops the image into size of output. Set size of output before calling this command or pass size as an argument. /// NOTE: If the data type of target image is not correct, this function will change it! /// </summary> /// <param name="input">Input image.</param> /// <param name="output">Output image.</param> /// <param name="position">Position in input image where the top-left corner of the cropped image is placed.</param> /// <param name="size">Size of output image. Specify zeroes or nothing to crop to current size of output image.</param> public void Crop(Pi2Image input, Pi2Image output, Vec3 position, Vec3 size) { PiLib.RunAndCheck(Handle, $"crop({input.Name}, {output.Name}, {ToIntVec(position)}, {ToIntVec(size)})"); }
/// <summary> /// Create an wx1x1 image that contains values of filter for use in filtered backprojection. /// </summary> /// <param name="output">Output image.</param> /// <param name="size">Desired size or zero to use size of output image.</param> /// <param name="filterType">Type of filter. Supported values are Ideal ramp1, Ramp, Shepp-Logan, Cosine, Hamming, Hann, Blackman, Parzen.</param> /// <param name="cutoff">Filter cutoff frequency.</param> public void CreateFBPFilter(Pi2Image output, int size = 100, string filterType = "Ramp", float cutoff = 1.0f) { PiLib.RunAndCheck(Handle, $"createfbpfilter({output.Name}, {size}, {filterType}, {cutoff.ToString(CultureInfo.InvariantCulture)})"); }