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

faster read of white balance and black level values for Basler acA2440-20gc & JAI FS-3200D-10GE #22

Conversation

tonyromarock
Copy link
Contributor

The white balance and black level values for the Basler acA2440-20gc & JAI FS-3200D-10GE can be read more efficiently by reading from the exact memory locations of the camera instead of using the Selector features.

I cannot confirm how stable these optimizations based on exact memory locations are in terms of firmware updates changing the memory location of the specific feature on the camera.

These optimizations are necessary to read out the white balance and black level values of the cameras at 10Hz (especially for the JAI prism camera).

@kledom
Copy link
Contributor

kledom commented Jul 12, 2022

Hi @tonyromarock,

We have discussed the pull request internally and are still a bit torn on how to proceed with it.

Could you give us some information about where the memory addresses come from? Are they mentioned in the camera's manual? Do you know if this is a bug in the camera's firmware or in aravis and might not occur in a newer version?

@tonyromarock
Copy link
Contributor Author

Hi @kledom,

thank you for looking into this PR.
I can understand how these changes are very specific and maybe not adequate for the driver, especially if the goal is to keep the driver as a general solution for many different genicam cameras.

So the memory addresses can be inferred from the genicam XML file found in each genicam camera:

arv-tool-0.6 --name="JAI Corporation-FS-3200D-10GE-U320553" genicam > ~/Desktop/JAI-Corporation-FS-3200D-10GE-U320553.xml

Within the genicam XML file you can find entries for different registers holding the camera feature values of interest.

I will go through the process using the JAI Fusion 3200D and its white balance values as example:

For the JAI Fusion 3200D we are interested in reading the DigitalRed and DigitalBlue values, that communicate the Gain settings used to color correct the images (effectively the white balance color adjustment). This is usually accessed by following theses steps:

  • changing the GainSelector camera feature to DigitalRed
  • reading the Gain value
  • changing the GainSelector camera feature to DigitalBlue
  • reading the Gain value

This translates to the following aravis code in the driver:

arv_device_set_string_feature_value(p_device_, "GainSelector", "DigitalRed");
white_balance_red = arv_device_get_float_feature_value(p_device_, "Gain");
arv_device_set_string_feature_value(p_device_, "GainSelector", "DigitalBlue");
white_balance_blue = arv_device_get_float_feature_value(p_device_, "Gain");

Unfortunately, this process is rather slow for certain camera features, preventing us from getting this information in time after the camera acquisition and still get the 10Hz frequency we want to achieve.

If we take a deeper look into the genicam XML file, we can find the following lines:

<IntSwissKnife Name="pGainRegAddr">
    <pVariable Name="SourceSelectorValue">SourceSelector</pVariable>
    <pVariable Name="GainSelectorValue">pGainSelectorReg</pVariable>
    <Formula>0x060014 + SourceSelectorValue * 32 + GainSelectorValue * 4</Formula>
</IntSwissKnife>

These lines explain, where we can find the gain values based on the selected stream channel and the selected gain value.
Here we have to consider that we can only obtain white balance values for the stream channel 0 (the RGB chip of the JAI cameras) and the GainSelectorValue is 1 for DigitalRed and 3 for DigitalBlue. This information of the enum values is also visible in the JAI user manual on page 65.

So if we calculate the <Formula> by hand, we get the memory addresses 0x00060018 and 0x00060020.

In aravis we can use arv_device_memory_read() and some ugly transformations to get the float values of interest:

arv_device_read_memory(p_device_, 0x00060018, n_bytes, &digital_red_register, NULL);
digital_red_big_endian = __builtin_bswap32 (digital_red_register);
std::copy(reinterpret_cast<char*>(&digital_red_big_endian), reinterpret_cast<char*>(&digital_red_big_endian) + 4, reinterpret_cast<char*>(&digital_red));

arv_device_read_memory(p_device_, 0x00060020, n_bytes, &digital_blue_register, NULL);
digital_blue_big_endian = __builtin_bswap32 (digital_blue_register);
std::copy(reinterpret_cast<char*>(&digital_blue_big_endian), reinterpret_cast<char*>(&digital_blue_big_endian) + 4, reinterpret_cast<char*>(&digital_blue));

So this not seem like a bug in the aravis code or camera firmware. There might be some issues with values being locked or not updated at the time of the memory read, but for additional acquisition parameters like the white balance values or the black level values this does not seem critical. I also have no experience on how much the genicam files change of a camera during firmware updates. These changes were necessary on our side to be able to read out the additional acquisition information, while still achieving the 10Hz frequency we want for our application.

There might be a nice way to refactor this into the existing codebase or to make the memory address accesses more modular, but this would require some more time cleaning up and re-designing the codebase.

Let me know what you guys think!

Thank you and best regards,
Peter

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

Successfully merging this pull request may close these issues.

None yet

3 participants