LUT#

/***********************************************************************************
*
* Itala API - Copyright (C) 2022 Opto Engineering
*
* THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY SUFFERED BY LICENSE AS
* A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
***********************************************************************************/

/**
 * @example LUT.cpp
 * 
 * @brief "LUT" example shows how to configure the LUT functionality,
 * available as set of GenICam features. LUTs allow to map pixel values
 * of an image to new specific values. In the following example the LUT
 * functionality is demonstrated by configuring a LUT which inverts
 * the acquired image.
 *
 * @see DefectivePixelCorrection.cpp
 * @see LiquidLens.cpp
 *
 */

 // Include Itala API 
#include "ItalaApi/Itala.h"

// Include the GenICam library
#include "GenICam.h"

#include <thread>
#include <chrono>

#define INDENT "\t"

void LUT_Sample()
{
  std::cout << "LUT example started." << std::endl << std::endl;

  Itala::ISystem* pSystem = Itala::CreateSystem();
  Itala::DeviceInfoList deviceInfos = pSystem->EnumerateDevices(700);

  if (deviceInfos.size() == 0)
    throw GENERIC_EXCEPTION("No devices found. Example canceled.");

  if (deviceInfos[0].AccessStatus() != Itala::DeviceAccessStatus::AvailableReadWrite)
    throw GENERIC_EXCEPTION("Target device is unaccessible in RW mode. Example canceled.");

  Itala::IDevice* pDevice = pSystem->CreateDevice(deviceInfos[0]);

  std::cout << "First device found is initialized." << std::endl;

  std::cout << "Configuring the LUT.." << std::endl;

  // Sets the LUT mode. In this case, the LUT is applied to the image luminance.
  GenApi::CEnumerationPtr pLUTSelector = pDevice->GetNodeMap().GetNode("LUTSelector");
  if (!IsWritable(pLUTSelector))
    throw GENERIC_EXCEPTION("Unable to select the LUT mode. Aborting.");
  pLUTSelector->FromString("Luminance");

  // Every different luminance value of the image pixel is also an index of
  // the LUT. This way, it's possible to map every luminance value by iterating
  // through the indexes.
  GenApi::CIntegerPtr pLUTIndex = pDevice->GetNodeMap().GetNode("LUTIndex");
  if (!IsWritable(pLUTIndex))
    throw GENERIC_EXCEPTION("Unable to configure the LUT index. Aborting.");
  int64_t maxIndex = pLUTIndex->GetMax();
  int64_t indexInc = pLUTIndex->GetInc();

  // Gets the maximum and minimum luminance value allowed. 
  GenApi::CIntegerPtr pLUTValue = pDevice->GetNodeMap().GetNode("LUTValue");
  if (!IsWritable(pLUTValue))
    throw GENERIC_EXCEPTION("Unable to get the allowed LUT values. Aborting.");
  int64_t maxValue = pLUTValue->GetMax();

  // Iterate through all indexes, i.e. through all possible luminance values and
  // set them their inverted counterpart (e.g. 242 becomes 255 - 242 = 13 in Mono8).
  // The increment is also defined by the LUTIndex node.
  for (int64_t i = 0; i <= maxIndex; i += indexInc)
  {
    pLUTIndex->SetValue(i);
    pLUTValue->SetValue(maxValue - i); 
    std::cout << INDENT << i << " becomes " << maxValue - i << std::endl;
  }

  std::cout << std::endl;
  std::cout << "LUT values set." << std::endl;

  // Once all values are mapped, enable the LUT.
  GenApi::CBooleanPtr pLUTEnable = pDevice->GetNodeMap().GetNode("LUTEnable");
  if (!IsWritable(pLUTEnable))
    throw GENERIC_EXCEPTION("Unable to activate the LUT. Aborting.");
  pLUTEnable->SetValue(true);

  std::cout << "LUT functionality enabled." << std::endl << std::endl;


  pDevice->Dispose();
  pDevice = nullptr;
  std::cout << "Device instance disposed." << std::endl;
  pSystem->Dispose();
  pSystem = nullptr;
  std::cout << "System instance disposed." << std::endl;
}

int main(int /*argc*/, char** /*argv*/)
{
  try
  {
    LUT_Sample();
  }
  catch (GenICam::GenericException& e)
  {
    std::cout << e.what() << std::endl;
  }
}