// Include ItalaApi
#include <stdio.h>
#include <stdlib.h>
#include "ItalaApiC/ItalaC.h"
#ifdef _WIN32
#include <windows.h>
#define SLEEP_MS(ms) Sleep(ms)
#else
#include <unistd.h>
#define SLEEP_MS(ms) usleep(ms * 1000)
#endif
#define INDENT "\t"
#define PIXEL_FORMAT "Polarized00Mono8"
ItalaError ErrorManager(ItalaError e) {
size_t sizeMessage = 255;
char* message = (char*)malloc(sizeof(char) * sizeMessage);
ERR_GetLastErrorMessage(message, &sizeMessage);
printf("\nITALA ERROR (%d):\t%s, %zu char", ERR_GetLastErrorCode(), message, sizeMessage);
free(message);
return e;
}
int main(int argc, char** argv) {
printf("***** Polarization example started. *****\n");
ItalaError error = ItalaErrorSuccess;
error = SYS_Initialize();
if (error) return ErrorManager(error);
size_t devicesInfoSize = 0;
error = SYS_EnumerateDevices(700);
if (error) return ErrorManager(error);
error = SYS_GetDeviceCount(&devicesInfoSize);
if (error) return ErrorManager(error);
if (devicesInfoSize == 0) {
printf("No devices found. Example canceled.\n");
return ItalaErrorError;
}
DeviceInfo deviceInfo;
error = SYS_GetDeviceByIndex(0, &deviceInfo);
if (error) return ErrorManager(error);
if (deviceInfo.AccessStatus != AvailableReadWrite) {
printf("Target device is unaccessible in RW mode. Example canceled.\n");
return ItalaErrorError;
}
H_DEVICE hDevice = NULL;
error = SYS_CreateDevice(deviceInfo, &hDevice);
if (error) return ErrorManager(error);
printf("First device found is initialized.\n\n");
H_NODEMAP hNodeMap = NULL;
error = DEV_GetNodeMap(hDevice, &hNodeMap);
if (error) return ErrorManager(error);
H_NODE hNodePixelFormat = NULL;
error = NODEMAP_GetNode(hNodeMap, "PixelFormat", &hNodePixelFormat);
if (error) return ErrorManager(error);
bool isReadable = false;
error = IsNodeReadable(hNodePixelFormat, &isReadable);
if (error) return ErrorManager(error);
if (!isReadable) {
printf("PixelFormat feature not available. Aborting.\n");
return ItalaErrorError;
}
// Set the pixelformat to Polarized00Mono8 or whatever format is available on the camera.
int64_t originalPixelFormat = 0;
error = NODE_EnumerationGetIntValue(hNodePixelFormat, &originalPixelFormat);
if (error) return ErrorManager(error);
error = NODE_FromString(hNodePixelFormat, PIXEL_FORMAT);
printf("PixelFormat set to %s\n", PIXEL_FORMAT);
error = DEV_StartAcquisition(hDevice);
if (error) return ErrorManager(error);
printf("Acquisition started.\n\n");
H_IMAGE hImage = NULL, hPolarizationImage = NULL;
error = DEV_GetNextImage(hDevice, 1000, &hImage);
if (error) return ErrorManager(error);
// Clone the grabbed image for convenience so that it can be returned to the library and the
// acquisition can be stopped.
error = IMG_Clone(hImage, &hPolarizationImage);
if (error) return ErrorManager(error);
error = IMG_Dispose(hImage);
hImage = NULL;
if (error) return ErrorManager(error);
error = DEV_StopAcquisition(hDevice);
if (error) return ErrorManager(error);
// 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
// (unsigned monochrome 8-bit or float).
printf("Extracting all polarization components..\n");
PolarComponents polarComponents;
error = ExtractAllPolarComponents(hPolarizationImage, NearestNeighbour, &polarComponents);
if (error) return ErrorManager(error);
PfncFormat format;
error = IMG_GetPixelFormat(polarComponents.P45, &format);
if (error) return ErrorManager(error);
printf("P45 format is %s\n", GetPixelFormatDescription(format));
// 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.
printf("Computing all stokes vectors..\n");
StokesVectors stokesVectors;
error = ComputeAllStokes(&polarComponents, &stokesVectors);
if (error) return ErrorManager(error);
error = IMG_GetPixelFormat(stokesVectors.S0, &format);
if (error) return ErrorManager(error);
printf("S0 format is %s\n", GetPixelFormatDescription(format));
// 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.
printf("Computing linear polarization images..\n");
H_IMAGE hAolpImage = NULL, hDolpImage = NULL, hIntensityImage = NULL;
error = ComputeAoLP(&stokesVectors, &hAolpImage);
if (error) return ErrorManager(error);
error = IMG_GetPixelFormat(hAolpImage, &format);
if (error) return ErrorManager(error);
printf("AoLP format is %s\n", GetPixelFormatDescription(format));
error = ComputeDoLP(&stokesVectors, &hDolpImage);
if (error) return ErrorManager(error);
error = IMG_GetPixelFormat(hDolpImage, &format);
if (error) return ErrorManager(error);
printf("DoLP format is %s\n", GetPixelFormatDescription(format));
error = IMG_GetPixelFormat(hPolarizationImage, &format);
if (error) return ErrorManager(error);
error = ComputeIntensity(&stokesVectors, Polarized00Mono8, &hIntensityImage);
if (error) return ErrorManager(error);
error = IMG_GetPixelFormat(hIntensityImage, &format);
if (error) return ErrorManager(error);
printf("Intensity format is %s\n", GetPixelFormatDescription(format));
// 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.
printf("Computing quadrants image..\n");
H_IMAGE hQuadrantsImage = NULL;
error = ComputePolarQuadrantsImage(hPolarizationImage, &hQuadrantsImage);
if (error) return ErrorManager(error);
error = IMG_GetPixelFormat(hQuadrantsImage, &format);
if (error) return ErrorManager(error);
printf("PolarQuadrants format is %s\n", GetPixelFormatDescription(format));
// 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:
printf("Computing DoLP without intermediate steps..\n");
H_IMAGE hDirectDolp = NULL;
error = InstantComputeDoLP(hPolarizationImage, NearestNeighbour, &hDirectDolp);
if (error) return ErrorManager(error);
error = IMG_GetPixelFormat(hDirectDolp, &format);
if (error) return ErrorManager(error);
printf("DoLP format is %s\n", GetPixelFormatDescription(format));
// Display or process DoLP
// Restore the original pixel format value
error = NODE_EnumerationSetIntValue(hNodePixelFormat, originalPixelFormat);
if (error) return ErrorManager(error);
// Each image MUST be disposed so that its memory is released. In real scenarios it's a good idea
// to release the images as long as they're no longer required to keep the memory footprint low.
// To prevent leaks, a dedicated set of functions is available in the Smart.h header.
error = IMG_Dispose(hPolarizationImage);
hPolarizationImage = NULL;
if (error) return ErrorManager(error);
error = IMG_Dispose(polarComponents.P0);
polarComponents.P0 = NULL;
if (error) return ErrorManager(error);
error = IMG_Dispose(polarComponents.P45);
polarComponents.P45 = NULL;
if (error) return ErrorManager(error);
error = IMG_Dispose(polarComponents.P90);
polarComponents.P90 = NULL;
if (error) return ErrorManager(error);
error = IMG_Dispose(polarComponents.P135);
polarComponents.P135 = NULL;
if (error) return ErrorManager(error);
error = IMG_Dispose(stokesVectors.S0);
stokesVectors.S0 = NULL;
if (error) return ErrorManager(error);
error = IMG_Dispose(stokesVectors.S1);
stokesVectors.S1 = NULL;
if (error) return ErrorManager(error);
error = IMG_Dispose(stokesVectors.S2);
stokesVectors.S2 = NULL;
if (error) return ErrorManager(error);
error = IMG_Dispose(hAolpImage);
hAolpImage = NULL;
if (error) return ErrorManager(error);
error = IMG_Dispose(hDolpImage);
hDolpImage = NULL;
if (error) return ErrorManager(error);
error = IMG_Dispose(hIntensityImage);
hIntensityImage = NULL;
if (error) return ErrorManager(error);
error = IMG_Dispose(hQuadrantsImage);
hQuadrantsImage = NULL;
if (error) return ErrorManager(error);
error = IMG_Dispose(hDirectDolp);
hDirectDolp = NULL;
if (error) return ErrorManager(error);
printf("\nImage istances disposed.\n");
error = DEV_Dispose(hDevice);
hDevice = NULL;
if (error) return ErrorManager(error);
printf("Device instance disposed.\n");
error = SYS_Dispose();
if (error) return ErrorManager(error);
printf("System instance disposed.\n");
}