How to get the "pixel" data values from a Photon Focus camera using the Pleora eBUS SDK c# or python?

417 views Asked by At

I have a 3D Photon Focus camera ( MV1-D2048x1088-3D06-760-G2-8) and I am using C# with the Pleora eBUS SDK version 5.1.1 on a Windows 10 machine. The camera is set to scan a laser line in LineFinder Mode, DataFormat3D = 2 and is returning the data (buffer Payload = 2 x 2048 = 4096 bytes). The payload seems correct. I want to save this data but I am having difficulty. How can I get the buffer into an array (or some structure) to save it to a file stream? My code is using the .DataPointer parameter from the Pleora eBUS SDK but I am not understanding what it is doing. The Manual I have included HERE - MAN075_PhotonFocus

enter image description here

private unsafe static void ThreadProc(object aParameters)
    {
        object[] lParameters = (object[])aParameters;
        MainForm lThis = (MainForm)lParameters[0];

        for (;;)
        {
            if (lThis.mIsStopping)
            {
                // Signaled to terminate thread, return.
                return;
            }

            PvBuffer lBuffer = null;
            PvResult lOperationResult = new PvResult(PvResultCode.OK);                
            // Retrieve next buffer from acquisition pipeline
            PvResult lResult = lThis.mStream.RetrieveBuffer(ref lBuffer, ref lOperationResult, 100);
            if (lResult.IsOK)
            {
                // Operation result of buffer is OK, display.
                if (lOperationResult.IsOK)
                {
                    //lThis.displayControl.Display(lBuffer);
                    uint bSize = lBuffer.GetPayloadSize();
                    PvImage image1 = lBuffer.Image;
                    uint height1 = image1.Height;
                    uint width1 = image1.Width;
                    uint offx1 = image1.OffsetX;
                    uint offy1 = image1.OffsetY;                        
                    PvPixelType imgpixtype = image1.PixelType;                                               
                    image1.Alloc(width1, (uint)2, imgpixtype);
                    byte *data_pnt = image1.DataPointer ;
                    byte[] MSB_array = new byte[(int)width1];
                    int buff_size = 2 * (int)width1;
                    byte[] pix_array = new byte[buff_size];                       
                    
                    ulong tStamp = lBuffer.Timestamp;
                    string msgOut = (bSize.ToString() + " TimeStamp " + tStamp.ToString() + " width " + width1.ToString());
                    Console.WriteLine(msgOut);
                    for (int i = 0; i < width1; i++)
                    {
                        data_pnt += 0;
                        Console.Write((uint)*data_pnt);
                        MSB_array[i] = *data_pnt;
                        data_pnt += 1;
                    }
                    data_pnt += 1;
                    Console.WriteLine(height1.ToString());
                    for (int i = 0; i < width1; i++)
                    {
                        ushort msb1 = MSB_array[i];
                        ushort last_4 = (ushort)(*data_pnt & 0x0F);
                        int integer1 = (msb1 << 4)+(ushort)(*data_pnt>>4);
                        double dec_part = (float)last_4 / (float)16;
                        double val1 = (float)integer1 + dec_part;
                        Console.WriteLine(val1.ToString());
                        data_pnt += 1;
                    }
                    Console.WriteLine(height1.ToString());
                }
                else
                {
                    uint bSize = lBuffer.GetPayloadSize();
                    ulong tStamp = lBuffer.Timestamp;
                    string msgOut = (bSize.ToString() + " BAD RESULT TimeStamp " + tStamp.ToString());
                    Console.WriteLine(msgOut);
                }

                // We have an image - do some processing (...) and VERY IMPORTANT,
                // re-queue the buffer in the stream object.
                lThis.mStream.QueueBuffer(lBuffer);
            }
        }
    }
1

There are 1 answers

1
Cary H On BEST ANSWER

My current solution is to loop through the buffer by incrementing the pointer and save the bytes into a new array (MSB_array). The way this data is packed (see the attached image in the question) I had to read the next line and bitshift it over and add it to the byte in the MSB_array to get a

    for (int i = 0; i < width1; i++)
        {
            data_pnt += 0;
            Console.Write((uint)*data_pnt);
            MSB_array[i] = *data_pnt;
            data_pnt += 1;
        }
        data_pnt += 1;
        Console.WriteLine(height1.ToString());
        for (int i = 0; i < width1; i++)
        {
            ushort msb1 = MSB_array[i];
            ushort last_4 = (ushort)(*data_pnt & 0x0F);
            int integer1 = (msb1 << 4)+(ushort)(*data_pnt>>4);
            double dec_part = (float)last_4 / (float)16;
            double val1 = (float)integer1 + dec_part;
            Console.WriteLine(val1.ToString());
            data_pnt += 1;
        }

I am only writing it out to the console now but the data is correct. There may be a better/faster way than the for loop using the pointer. That post would be appreciated.