Working with the the Dalsa Genie Nano Laser Line Extraction Firmware in CVB.NET

Teledyne Dalsa offers a special firmware version called Laser Line Extraction (LLE) firmware for Genie Nano cameras using the monochrome On-Semi Python P1 sensor, to directly extract laser lines on the camera board and only transmit the profile data to the PC. At the moment there are the following Models equipped: G3-GM10-M0640/M0800/M1280/M1930/M2590.
This post will show how to convert the datastream correctly in CVB.NET for further processing.

At first you will need to connect to your Genie Nano camera an upload the laser line extraction firmware.
This firmware version will allow you to use an additional “3D-Linescan” mode next to the standard “Areascan”-mode.
The main advantage is that 3D-profiles can directly be calculated on the camera board and the resulting bandwith for data transmission is much lower than transmitting full frames.
The LLE-firmware allows you to set basic parameters for the laserline extraction. The AOI can be determined and a threshold and search radius combination can be chosen for the laser line extraction.
There is only one algorithm available for the laser line extraction which is calculating a center of gravity from the pixels inside the search radius arround the highest peak. For detailed information have a look on the firmware manual.
The Output of the camera is a 64 bpp image of the size columns x 1 for each captured profile. Each pixel contains 4 components describing the extracted row-position of the laser line:

For the calculation of the laser line position use the following equation:

To acquire the data in CVB use the classic imagestream to receive the 64 bpp, columns x 1 image.
At the moment there is no direct function for the computation of the laserline available. The 64 bits need to be separated as shown in the grafic above. For this have a look on the following C#-Code:

              //Get linear access on transmitted pixels
              LinearAccessData<byte> linacc = image.Planes[0].GetLinearAccess<byte>();
              //Gate Basepointer on Image in memory
              IntPtr basePtr = linacc.BasePtr;              

              //Loop through each image pixel of the Laser-Profile-Data
              for (int j = 0; j < image.Width; j++)
                //Get Pointer on first address of Pixel j
                Int64* ptr = (Int64*)(basePtr + (j));
                //Get byte-Pointer on Antiscatter
                byte* ptrAS = (byte*)(basePtr + (j * 8));
                //Get byte-Pointer on Scatter
                byte* ptrS = (ptrAS + sizeof(byte));
                //Get byte-Pointer on Weighted Column Sum
                byte* ptrWCSb = (ptrAS + (2 * sizeof(byte)));
                //Convert byte-pointer on Weighted Clolumn Sum to UInt32-Pointer
                UInt32* ptrWCS = (UInt32*)ptrWCSb;
                //Get byte-Pointer on Pixel Sum
                byte* ptrPSb = (ptrAS + (6 * sizeof(byte)));
                //Convert byte-Pointer on Pixel sum to UInt16-Pointer
                UInt16* ptrPS = (UInt16*)ptrPSb;

                //Dereference Pointers
                byte valAntiScatter = *ptrAS;
                byte valScatter = *ptrS;
                UInt32 valWeightedColSum = *ptrWCS;
                UInt16 valPixSum = *ptrPS;

From the extracted variables the laser line position can be calculated for each column and written into a 16 bit image when adding multiple lines to generate a rangemap image.