Touseefelahi / GigeVision

Simple GigeVision implementation, GVSP, GVCP protocol implemented
103 stars 31 forks source link

16Bit Image Acquisition not Working in OpenCV StreamReceiver #121

Closed blauertee closed 2 months ago

blauertee commented 2 months ago

I think this

https://github.com/Touseefelahi/GigeVision/blob/e1f4e75202d111204336f6c6dc51be036abf0ec3/GigeVision.OpenCV/StreamReceiverParallelOpenCV.cs#L169-L172

cannot work since

 //
        // Summary:
        //     The method returns the number of array elements (a number of pixels if the array
        //     represents an image)
        public IntPtr Total
        {
            get;
        }

Which means in case of 16 Bit color depth it returns the number of words within the array which is #bytes / 2.

I think I can just use var l_Span = mat.GetSpan<byte>(); (which returns exactly width height bytesperpixel)

But even though this should fix that, I still get an overflow at the same place:

https://github.com/Touseefelahi/GigeVision/blob/e1f4e75202d111204336f6c6dc51be036abf0ec3/GigeVision.OpenCV/StreamReceiverParallelOpenCV.cs#L137

The Span is 4024 3036 2 = 24,433,728 bytes large, buffer_start is at 24,433,240 and buffer_length is 988.

Any idea what else could be wrong?

Touseefelahi commented 2 months ago

Can you check for the GvspInfo values after this line:https://github.com/Touseefelahi/GigeVision/blob/e1f4e75202d111204336f6c6dc51be036abf0ec3/GigeVision.OpenCV/StreamReceiverParallelOpenCV.cs#L46

Make sure the parameters that are detected are correct based on the camera resolution and pixel depth.

Touseefelahi commented 2 months ago

The base implementation is tested with 16bit camera. long time ago but I but I believe it will be fine. This implementation is new, and not tested for different cameras. You can also try with the base implementation, just check if it is getting the frame.

blauertee commented 2 months ago

Make sure the parameters that are detected are correct based on the camera resolution and pixel depth.

Yes, the Values that I mentioned here

The Span is 4024 3036 2 = 24,433,728 bytes large, buffer_start is at 24,433,240 and buffer_length is 988.

are the ones seen in the debugger that have been detected by DetectGvspType(); (GvspInfo.Height, GvspInfo.Width, GvspInfo.BytesPerPixel) and they are correct.

I've not used the Base class so far and i'm on the brach of my PR so there could be other stuff not working related to my changes. But what happes when starting the BaseReceiver as it is, is that every Frame is lost due to:

if (Math.Abs(packetRxCountClone - GvspInfo.FinalPacketID) <= MissingPacketTolerance) 

where

packetRxCountClone = 24711 GvspInfo.FinalPacketID = 12366 MissingPacketTolerance = 2

So I think the err above stems from: https://github.com/Touseefelahi/GigeVision/blob/e1f4e75202d111204336f6c6dc51be036abf0ec3/GigeVision.Core/Services/StreamReceiverBase.cs#L156

Shouldn't that be

var totalBytesExpectedForOneFrame = GvspInfo.Width * GvspInfo.Height * GvspInfo.BytesPerPixel;

If I change that, I can receive Frames with the Base class, but that still doesn't fix my problem with the OpenCV class which is the one I need :)

blauertee commented 2 months ago

If your fixing that on master I'd also throw out the Abs() in

if (Math.Abs(packetRxCountClone - GvspInfo.FinalPacketID) <= MissingPacketTolerance) 

If more Packages than expected are received the Receiver is probably in trouble and should throw an exception instead of just handeling the frame as lost.

Touseefelahi commented 2 months ago

where

packetRxCountClone = 24711 GvspInfo.FinalPacketID = 12366 MissingPacketTolerance = 2

This means that it missed the final packet. PacketRx counter should not be greater than the final packet. It must be reset to 0 if we past the FinalPacketID.

var totalBytesExpectedForOneFrame = GvspInfo.Width GvspInfo.Height GvspInfo.BytesPerPixel;

This will work if we check for block id as well. The data might not be in order, so there is a slight possibility that we may receive the next block id (frame) packet.

Touseefelahi commented 2 months ago

If your fixing that on master I'd also throw out the Abs() in

if (Math.Abs(packetRxCountClone - GvspInfo.FinalPacketID) <= MissingPacketTolerance) 

If more Packages than expected are received the Receiver is probably in trouble and should throw an exception instead of just handeling the frame as lost.

yes you are right this is a problem, I am not throwing because of assumption that the packet is missed, there was an event that published if the packet is missed.

There are few more things needs to be improved, if the packet is missed application should send the request the packet again by utilizing the packet resend command.

For application that requires 100% frame reception with no loss, this implementation might not be sufficient.

blauertee commented 2 months ago

I don't think it missed the FinalPacket the FinalPacketID is definitely to small for my image size * bytes per pixel / package size. Anyway my StreamReceiverOpenCv works now, not sure what changed maybe i just scrambled package reception by breakpoints, and did not notice.

Anyhow consider changing https://github.com/Touseefelahi/GigeVision/blob/e1f4e75202d111204336f6c6dc51be036abf0ec3/GigeVision.OpenCV/StreamReceiverParallelOpenCV.cs#L169-L172

to:

 private Span<byte> GetSpan(Mat mat)
        {
            return  mat.GetSpan<byte>();
        }

and https://github.com/Touseefelahi/GigeVision/blob/e1f4e75202d111204336f6c6dc51be036abf0ec3/GigeVision.Core/Services/StreamReceiverBase.cs#L156

to

var totalBytesExpectedForOneFrame = GvspInfo.Width * GvspInfo.Height * GvspInfo.BytesPerPixel;
Touseefelahi commented 2 months ago

Yes, these both changes are necessary, I will implement the change and then close the issue. Thank you for pointing out