samuelpowell / Spinnaker.jl

A Julia interface to the FLIR/PointGrey Spinnaker SDK
MIT License
15 stars 7 forks source link

Win64 library and packed formats #64

Open rguerrab opened 4 years ago

rguerrab commented 4 years ago

Hello, The latest version of the package (v0.1.10) failed to compile on a 64bit installation of Julia in Windows. Changing the path to path = joinpath(ENV["ProgramFiles"], "Point Grey Research", "Spinnaker", "bin64", "vs2015") solved the problem. Having options for 32 and 64bit installations may be helpfull.

Also, I have not been able to convert Mono12p/Mono12Packed SpinImages to Julia arrays using CameraImage, and have not found a way to access the raw binary data. Is there a way to access this data to convert it to (U)Int or Float type?

Thanks

samuelpowell commented 4 years ago

Can I ask what version of Spinnaker SDK you installed? I wonder if they have changed their paths (I rarely use Windows but would only ever have been using 64-bit installs in any case, so something has changed). I will check on my end too.

Regarding Mono12p/Mono12Packed this has not been implemented. In general the overhead of unpacking the data (compared to the bandwidth loss of transmitting in Mono16) was such that I never bothered. Perhaps a method to get the raw data is not a bad idea though. If you want to use this mode then a PR is welcome.

rguerrab commented 4 years ago

I'm stuck with Spinnaker SDK v1.20.0.15 because of compatibility issues with micromanager, but I've been thinking about dumping that in favor of a Julia interface now that I know that I found your package.

As far as raw data, all I need would be for SpinImage/CameraImage/whatever to spit out a uint8 array that was 1.5 larger than the image itself. The SpinView GUI that comes with the SDK already lets me save raw binary files in these packed formats, but I don't know how to get at these data directly using your library.

rguerrab commented 4 years ago

Sorry, I guess I was being a bit dense. Got the Mono12p unpacking to work by dumping the entire buffer as a 1.5widthheight long UInt8 vector using unsafe_wrap and bit-shifting appropriately.

samuelpowell commented 4 years ago

I assume you mean you are dumping the raw buffer from a SpinImage? This part should indeed be straightforward as this is just an opaque pointer to the underlying Spinnaker data. It's only when we make the promise that this is a 'normal' Julia array (e.g. by requesting a CameraImage) that we have to deal with the nature of the underlying data. A contribution to support this conversion by unpacking the data would be welcome.

With regards to supporting the old version of Spinnaker, again, if you want to submit a PR that enables support and are able to test on your version, I'm happy to check that it still works on the latest version.

rguerrab commented 4 years ago

A pull-request for something this small seems excessive. Here are code snippets to handle Mono10p/Mono12p packed formats.

Mono10p

# dump raw buffer and define output array
packed = unsafe_wrap(Array,  Ptr{UInt8}(rawptr[]), (Int64(ceil(1.25*width*height)),1))
data=zeros(UInt16, width*height)

# Unpack the data and copy it to the output array
for p=1:Int64(floor(width*height/4))
    data[4*p-3] = UInt16(packed[5*p-4]) + 256*UInt16(packed[5*p-3] & 0x03)
    data[4*p-2] = UInt16(packed[5*p-3] >> 2) + 64*UInt16(packed[5*p-2]  & 0x0f)
    data[4*p-1] = UInt16(packed[5*p-2] >> 4) + 16*UInt16(packed[5*p-1]  & 0x3f)
    data[4*p]   = UInt16(packed[5*p-1] >> 6) + 4*UInt16(packed[5*p])
end

# reshape the data
data=reshape(data,(width, height))

Mono12p

packed = unsafe_wrap(Array,  Ptr{UInt8}(rawptr[]), (Int64(ceil(1.5*width*height)),1))
data=zeros(UInt16, width*height)

for p=1:Int64(floor(width*height/2))
    data[2*p-1] = UInt16(packed[3*p-2]) + 256*UInt16(packed[3*p-1] & 0x0f)
        data[2*p] = 16*UInt16(packed[3*p]) + UInt16(packed[3*p-1] >> 4)
end

# reshape the data
data=reshape(data,(width, height))

Mono10/12Packed formats are both packed as 3 bytes per pixel, so they would look the same as Mono12p, except for the body of the for loop. Those should be replaced with

Mono10Packed

for p=1:Int64(floor(width*height/2))
    data[2*p-1] = 4*UInt16(packed[3*p-2]) + UInt16(packed[3*p-1] & 0x03)
    data[2*p] = 4*UInt16(packed[3*p]) + UInt16((packed[3*p-1] >> 4) & 0x03)
end

Mono12Packed

for p=1:Int64(floor(width*height/2))
    data[2*p-1] = 16*UInt16(packed[3*p-2]) + UInt16(packed[3*p-1] & 0x0f)
    data[2*p] = 16*UInt16(packed[3*p]) + UInt16(packed[3*p-1] >> 4)
end

I'm not using a color camera, but the Technical Reference manual for my camera says that the same packing format applies for 10/12 bit Bayer image formats.

samuelpowell commented 4 years ago

Thanks @rguerrab, I misunderstood - I thought you wanted this to be integrated into the package. I'm pleased this is working for you.

rguerrab commented 4 years ago

Yes, it would be nice if format unpacking became part of the package, but this approach works fine for me.

One additional snag re the path. FLIR released version 2.0.0.146 and they changed their installation directory from "Point Grey Research" to "FLIR Systems", still with bin and bin64 subdirectories that contain the appropriate dlls.

Best, Rodrigo

samuelpowell commented 4 years ago

I don't have easy access to Windows right now, if you're able to produce a PR that fixes Windor x64 for the most recent SDK (without breaking whatever was happening before) that would be appreciated. I'm only concerned with supporting 64-bit versions (both Julia and external libraries) so whatever works on the latest SDK is fine.

@ianshmean do you happen to know if the MacOS/Linux installation has also changed?

rguerrab commented 3 years ago

Sorry to necropost, but version 0.1.12 now fails in Windows not just because of the path set on line 52 of Spinnaker.jl -- though that should still read: paths = [joinpath(ENV["ProgramFiles"], "FLIR Systems", "Spinnaker", "bin64", "vs2015")] presumably with an option for "bin32" if appropriate (not running 32bit OS so can't confirm).

Lines 54 and 72 of Spinnaker.jl are now mutually exclusive. It's not totally clear to me what libSpinVideo_C is required for, but line 54 sets its path to empty, while line 72 requires a valid path to set both libSpinVideo_C[] and libSpinnaker_C[]. Plugging "SpinVideoC_v140.dll" into line 54 solves this problem, but attempts to load the library crash with exactly the same error message found in #71.

IanButterworth commented 3 years ago

I'm overdue fixing the build progress on the current release/master.

If you can find an older version that works for now, I recommend using that, and I will do my best to fix this this week

rguerrab commented 3 years ago

Yeah, no rush. v0.1.11 works quite well once the path to libSpinVideo_C is set correctly.

EntPyle commented 2 years ago

I'm still seeing this issue in 2022. @samuelpowell if you're still maintaining, this I can put together a PR to fix the issue on windows at least. image image image

IanButterworth commented 2 years ago

PR welcome!

EntPyle commented 2 years ago

I'll spin that up in the next couple days then.