Polarization

Polarization.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Itala;
using Itala.GenApi;

/// <summary>
///  "Polarization" example shows how to process images containing light polarization data.
///  Polarization images are similar to bayer color images since they need to be demosaiced and
///  processed to determine the state of polarized light.
///  The following example shows a complete workflow for monochrome polarization images including
///  polarization components and Stokes vector computation. To get images like AoLP, DoLP and
///  intensity directly, a dedicated overload set is available.
/// </summary>
internal class Program
{
  const int ACQUIRE_COUNT = 50;

  const string INDENT = "\t";

  const string PIXEL_FORMAT = "Polarized00Mono8";

  private static void Polarization_Sample()
  {
    Console.WriteLine("######## Polarization ########");
    ISystem system = SystemFactory.Create();
    List<DeviceInfo> deviceInfos = system.EnumerateDevices();

    if (deviceInfos.Count == 0)
      throw new ItalaRuntimeException("No devices found. Example canceled.");
    if (deviceInfos[0].AccessStatus != DeviceAccessStatus.AvailableReadWrite)
      throw new ItalaRuntimeException("Target device is unaccessible in RW mode. Example canceled.");
    IDevice device = system.CreateDevice(deviceInfos[0]);
    Console.WriteLine("First device initialized.");

    INodeMap deviceNodeMap = device.GetNodeMap();

    // Set the pixelformat to Polarized00Mono8 or whatever format is available on the camera.
    IEnumeration pixelFormat = deviceNodeMap.GetNode<IEnumeration>("PixelFormat");
    if (!pixelFormat.IsWritable)
      throw new ItalaRuntimeException("Unable to configure the pixel format. Aborting.");
    Int64 originalPixelFormat = pixelFormat.IntValue;
    pixelFormat.FromString(PIXEL_FORMAT);
    Console.WriteLine("PixelFormat se to " + PIXEL_FORMAT);


    // Start a default continuous acquisition. Internally, the runtime allocates a
    // queue of 16 image buffers thus a maximum of 16 images can be grabbed simultaneously
    // without being released. An additional overload function allows to set the
    // buffer and frame count.
    device.StartAcquisition();
    Console.WriteLine("Acquisition started.");

    IImage image = device.GetNextImage(1000);

    // Clone the grabbed image for convenience so that it can be returned to the library and the
    // acquisition can be stopped.
    IImage polarizationImage = image.Clone() as IImage;
    image.Dispose();
    device.StopAcquisition();
    Console.WriteLine("Acquisition stopped.");

    // Extract an image for each component (or angle) of the polarizer filter. Each resulting image
    // represents the captured light at 0, 45, 90 and 135 degrees respectively. Depending on the
    // demosaicing algorithm used, the pixel format of the resulting images can be of different types.
    // NearestNeighbour on Polarized00Mono8 produces Mono8 components.
    Console.WriteLine("Extracting all polarization components..");
    PolarComponents polarComponents = Polarization.ExtractAllPolarComponents(polarizationImage, PolarDemosaicingAlgorithm.NearestNeighbour);
    Console.WriteLine("P45 format is " + Pfnc.GetPixelFormatDescription(polarComponents.P45.PixelFormat));

    // display or process polarization components

    // Compute all the Stokes vectors to determine the polarization state of the light given the
    // intensities of the different polarizers on the sensor. Since we're dealing with linear
    // polarization data, only the first three (s0, s1 and s2) components of the vector are available.
    // Each resulting image represents the values of that particular component of the Stokes vector
    // across the whole sensor. For instance, the S0 image contains the s0 values of each pixel.
    Console.WriteLine("Computing all stokes vectors..");
    StokesVectors stokesVectors = Polarization.ComputeAllStokes(polarComponents);
    Console.WriteLine("S0 format is " + Pfnc.GetPixelFormatDescription(stokesVectors.S0.PixelFormat));

    // display or process the Stokes vectors

    // Given the stokes vectors, compute the linear polarization images.
    // The DoLP (Degree of Linear Polarization) image indicates the ratio of the intensity of the
    // polarized part of the light to the intensity of the unpolarized one. When the light is totally
    // polarized, this corresponds to the total intensity of the light. When the light is unpolarized,
    // this corresponds to zero.
    // The AoLP (Angle of Linear Polarization) image indicates the polarization direction of the
    // incoming light.
    // The intensity image simply indicate the total intensity of the incoming light.
    Console.WriteLine("Computing linear polarization images..");
    IImage dolpImage = Polarization.ComputeDoLP(stokesVectors);
    IImage aolpImage = Polarization.ComputeAoLP(stokesVectors);
    IImage intensityImage = Polarization.ComputeIntensity(stokesVectors, polarizationImage.PixelFormat);
    Console.WriteLine("DoLP format is " + Pfnc.GetPixelFormatDescription(dolpImage.PixelFormat));
    Console.WriteLine("AoLP format is " + Pfnc.GetPixelFormatDescription(aolpImage.PixelFormat));
    Console.WriteLine("Intensity format is " + Pfnc.GetPixelFormatDescription(intensityImage.PixelFormat));

    // display or process the images

    // From the source image, compute an image of the same size divided in four quadrants containing
    // the four polarization components.
    Console.WriteLine("Computing quadrants image..");
    IImage pQuadrantsImage = Polarization.ComputePolarQuadrantsImage(polarizationImage);
    Console.WriteLine("PolarQuadrants format is " + Pfnc.GetPixelFormatDescription(pQuadrantsImage.PixelFormat));

    // Display or process the quadrants image

    // If intermediate data like polar components or stokes vectors is not needed, monochrome AoLP,
    // DoLP and intensity can be directly computed with the dedicated functions given the polarized
    // image. For instance, DoLP:
    Console.WriteLine("Computing DoLP without intermediate steps..");
    IImage directDolpImage = Polarization.ComputeDoLP(polarizationImage, PolarDemosaicingAlgorithm.NearestNeighbour);
    Console.WriteLine("directDoLP format is " + Pfnc.GetPixelFormatDescription(directDolpImage.PixelFormat));

    // Display or process DoLP

    // Restore the original pixel format value
    pixelFormat.IntValue = originalPixelFormat;

    dolpImage.Dispose();
    aolpImage.Dispose();
    intensityImage.Dispose();
    polarizationImage.Dispose();
    pQuadrantsImage.Dispose();
    directDolpImage.Dispose();
    stokesVectors.S0.Dispose();
    stokesVectors.S1.Dispose();
    stokesVectors.S2.Dispose();
    polarComponents.P0.Dispose();
    polarComponents.P45.Dispose();
    polarComponents.P90.Dispose();
    polarComponents.P135.Dispose();

    device.Dispose();
    Console.WriteLine("Device instance disposed.");
    system.Dispose();
    Console.WriteLine("System instance disposed.");
  }

  private static void Main(string[] args)
  {
    try
    {
      Polarization_Sample();
    }
    catch (Exception ex)
    {
      Console.WriteLine(ex.ToString());
    }
  }
}