using Itala;
using Itala.GenApi;
/// <summary>
/// DefectivePixelCorrection" example shows how to detect
/// defective pixels on the sensor given a set of images and how
/// to correct them via the functionality implemented in the nodemap
/// of the device. The procedure should be performed at max resolution.
/// </summary>
internal class Program
{
const int ACQ_COUNT = 10;
private static void CorrectDetectedPixels(List<DefectivePixel> defectivePixels, INodeMap nodeMap)
{
IInteger defectivePixelCount = nodeMap.GetNode<IInteger>("oeDefectivePixelCount");
if (!defectivePixelCount.IsWritable)
throw new ItalaRuntimeException("Unable to set the number of pixels to be corrected. Aborting.");
defectivePixelCount.Value = defectivePixels.Count;
Console.WriteLine("\tCorrection procedure started with " + defectivePixels.Count + " pixels.");
// Get the pixel selector to iterate over the amount of targeted pixels.
IInteger defectivePixelSelector = nodeMap.GetNode<IInteger>("oeDefectivePixelSelector");
if (!defectivePixelSelector.IsWritable)
throw new ItalaRuntimeException("Unable to set the pixel selector for correction. Aborting.");
// Get the features which allow to set the X and Y coordinate of the target pixel
// identified by the selector.
IInteger defectivePixelXCoordinate = nodeMap.GetNode<IInteger>("oeDefectivePixelXCoordinate");
if (!defectivePixelXCoordinate.IsWritable)
throw new ItalaRuntimeException("Unable to set the X coordinate of the target pixel. Aborting.");
IInteger defectivePixelYCoordinate = nodeMap.GetNode<IInteger>("oeDefectivePixelYCoordinate");
if (!defectivePixelYCoordinate.IsWritable)
throw new ItalaRuntimeException("Unable to set the Y coordinate of the target pixel. Aborting.");
// Set the coordinates of every targeted pixels.
for(int i = 0; i < defectivePixels.Count; i++)
{
defectivePixelSelector.Value = i;
defectivePixelXCoordinate.Value = (long)defectivePixels[i].X;
defectivePixelYCoordinate.Value = (long)defectivePixels[i].Y;
Console.WriteLine("\tPixel[" + defectivePixels[i].X + "," + defectivePixels[i].Y + "] registered for correction. Was " + defectivePixels[i].TypeString + ".");
}
// Once that the pixel map has been set (i.e. the amount of pixels to be corrected
// and their coordinates) the write function can be called to perform the
// correction.
ICommand defectivePixelWriteMap = nodeMap.GetNode<ICommand>("oeDefectivePixelWriteMap");
if (!defectivePixelWriteMap.IsWritable)
throw new ItalaRuntimeException("Unable to write the pixel map to device memory. Aborting.");
defectivePixelWriteMap.Execute();
Console.WriteLine("\tCorrection command sent, procedure completed.");
}
private static void DefectivePixelCorrection_Sample()
{
Console.WriteLine("######## DefectivePixelCorrection ########");
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.");
// Start by setting a full resolution Mono8 image to perform the
// correction on the whole sensor. Keep the original values to restore
// the initial camera state at the end of the program.
IInteger width = device.GetNodeMap().GetNode<IInteger>("Width");
if (!width.IsWritable)
throw new ItalaRuntimeException("Unable to configure the image width. Aborting.");
Int64 originalWidth = width.Value;
Int64 maxWidth = width.Max;
width.Value = maxWidth;
Console.WriteLine("\tImage width set to " + maxWidth);
IInteger height = device.GetNodeMap().GetNode<IInteger>("Height");
if (!height.IsWritable)
throw new ItalaRuntimeException("Unable to configure the image height. Aborting.");
Int64 originalHeight = height.Value;
Int64 maxHeight = height.Max;
height.Value = maxHeight;
Console.WriteLine("\tImage height set to " + maxHeight);
IEnumeration pixelFormat = device.GetNodeMap().GetNode<IEnumeration>("PixelFormat");
if (!pixelFormat.IsWritable)
throw new ItalaRuntimeException("Unable to configure the image pixel format. Aborting.");
Int64 originalPixelFormat = pixelFormat.IntValue;
IEnumEntry mono8Entry = pixelFormat.GetEntryByName("Mono8");
Int64 mono8Format = mono8Entry.Value;
pixelFormat.IntValue = mono8Format;
Console.WriteLine("\tPixelFormat set to Mono8.");
// Create a detection interface for the current image size and pixel depth.
IDefectDetection mono8Detection = DefectDetectionFactory.Create(maxWidth, maxHeight, PixelDepth.d8Bit);
device.StartAcquisition();
Console.WriteLine("\tAcquisition started.");
// Acquire the dark images needed for both leaky and hot/cold
// detection. The image data is accumulated thanks to the interface
// so that each image can be immediately disposed without wasting memory.
Console.WriteLine("\tAccumulating dark data...");
for(int i = 0; i < ACQ_COUNT; i++)
{
IImage darkImage = device.GetNextImage(500);
mono8Detection.AccumulateDark(darkImage.Data);
Console.WriteLine("\tImage "+(i+1)+" added. \r");
darkImage.Dispose();
}
// Acquire the gray images needed for hot/cold detection.
Console.WriteLine("\n\tAccumulating grey data...");
for (int i = 0; i < ACQ_COUNT; i++)
{
IImage grayImage = device.GetNextImage(500);
mono8Detection.AccumulateGray(grayImage.Data);
Console.WriteLine("\tImage "+(i+1)+" added. \r");
grayImage.Dispose();
}
device.StopAcquisition();
Console.WriteLine("\n\tAcquisition stopped.");
// Find and get the leaky pixels of the sensor.
List<DefectivePixel> leakyPixels = mono8Detection.FindLeaky(1024, 5);
//Same for hot/cold pixels.
List<DefectivePixel> hotNColdPixels = mono8Detection.FindHotNCold(1024, 5);
Console.WriteLine(leakyPixels.Count+" leaky pixels found.");
Console.WriteLine(hotNColdPixels.Count+" hot/cold pixels found.");
// Leaky and hot/cold pixels are equally defective for the purposes of
// the correction algorithm. Append the two vectors and perform the correction
// with the dedicated GenICam nodes.
leakyPixels.AddRange(hotNColdPixels);
CorrectDetectedPixels(leakyPixels, device.GetNodeMap());
// Dispose the detection interface when done.
mono8Detection.Dispose();
Console.WriteLine("Mono8 detection instance disposed.");
// Restore the original image size and format.
width.Value = originalWidth;
height.Value = originalHeight;
pixelFormat.IntValue = originalPixelFormat;
device.Dispose();
Console.WriteLine("Device instance disposed.");
system.Dispose();
Console.WriteLine("System instance disposed.");
}
private static void Main(string[] args)
{
try
{
DefectivePixelCorrection_Sample();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}