Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PixelFormat name compatibility issue between pylablib/IMAQdx and Basler piA1600-35gm camera #63

Open
MangledPotat0 opened this issue Nov 7, 2023 · 0 comments

Comments

@MangledPotat0
Copy link

MangledPotat0 commented Nov 7, 2023

Code:

from pylablib.devices import IMAQdx as iqx
from pylablib.devices.IMAQdx.NIIMAQdx_lib import IMAQdxLibError
import cv2 as cv

def camera_auto():
    cameras = iqx.list_cameras()
    names = [camera.name for camera in cameras]
    print(names)
    camera = iqx.IMAQdxCamera(cameras[0].name)
    camera.set_attribute_value("AcquisitionAttributes/PacketSize", 1500)

    attr = camera.get_attribute("PixelFormat")

    camera.set_attribute_value("PixelFormat", "Mono8")
    frame = camera.snap()
    cv.imwrite("sadf.png", frame)
    camera.close()

if __name__ == "__main__":
    camera_auto()

Expected behavior:

Takes image using the camera, at 8-bit pixel format, and prints the shape of the image.

Actual behavior:

Camera fails to take the image upon calling cam.snap(). Error message:

['cam1', 'cam2', 'cam3', 'cam4']
Traceback (most recent call last):
  File "{CODEPATH}", line 20, in <module>
  File "{CODEPATH}", line 15, in camera_auto
    frame = camera.snap()
            ^^^^^^^^^^^^^
  File "{LIBRARYPATH}\pylablib\devices\interface\camera.py", line 682, in snap
    res=self.grab(frame_timeout=timeout,return_info=return_info)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{LIBRARYPATH}\pylablib\devices\interface\camera.py", line 673, in grab
    new_frames,rng=self.read_multiple_images(missing_frame=missing_frame,return_rng=True)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^
  File "{LIBRARYPATH}\pylablib\core\devio\interface.py", line 666, in wrapped
    res=func(**all_args)
        ^^^^^^^^^^^^^^^^
  File "{LIBRARYPATH}\pylablib\devices\interface\camera.py", line 568, in read_multiple_images
    frames_data=self._read_frames(rng,return_info=return_info)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{LIBRARYPATH}\pylablib\devices\IMAQdx\IMAQdx.py", line 470, in _read_frames
    frames=[self._parse_data(f,shape,pixel_format) for f in frames]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{LIBRARYPATH}\pylablib\devices\IMAQdx\IMAQdx.py", line 470, in <listcomp>
    frames=[self._parse_data(f,shape,pixel_format) for f in frames]
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{LIBRARYPATH}\pylablib\devices\IMAQdx\IMAQdx.py", line 434, in _parse_data
    raise IMAQdxError("pixel format {} is not supported, only [{}] are supported; raw data readout can be enabled via enable_raw_readout method".format(pixel_format,sf_string))
pylablib.devices.IMAQdx.NIIMAQdx_lib.IMAQdxError: pixel format Mono 8 is not supported, only [Mono8, Mono10, Mono12, Mono16, Mono32] are supported; raw data readout can be enabled via enable_raw_readout method

Further information

The choices for the enum "PixelFormat" for the camera was inspected:

attr = cam.get_attribute("PixelValue")
print(attr.values)

and it returns the following list:

['Mono 8', 'Mono 12 Packed', 'Mono 16', 'YUV 422 Packed', 'YUV 422 (YUYV) Packed']

(Temporary) Solution

I located where the currently supported pixel values are enumerated:

supported_formats=["Mono8","Mono10","Mono12","Mono16","Mono32"]
if pixel_format not in supported_formats:
sf_string=", ".join(supported_formats)
raise IMAQdxError("pixel format {} is not supported, only [{}] are supported; raw data readout can be enabled via enable_raw_readout method".format(pixel_format,sf_string))
if pixel_format=="Mono8":
return data.reshape(shape)

and added "Mono 8" to supported_formats on line 431, and modified line 435 to

if pixel_format=="Mono8" or pixel_format=="Mono 8":

and that fixes the problem. Note I could not test "Mono 16" because even though attr.values include "Mono 16" the camera doesn't actually support 16-bit image according to the camera spec sheet.

The temporary fix I attempted feels pretty hacky and since there are multiple possible ways to write the format name (uppercase, lowercase, capitalized, abbreviated, etc.), enumerating them all in if would quickly get overwhelming. This may be a single exception, but if it turns out to be a recurring issue, it may be appropriate to make PixelFormat objects that ensures any string representation of a given pixel format is supported, similar to how the path objects in python ensure compatibility between different OS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant