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

[BUG] DNG image generation segmentation fault monochrome sensor. #1186

Open
joshuasv opened this issue Jan 2, 2025 · 2 comments
Open

[BUG] DNG image generation segmentation fault monochrome sensor. #1186

joshuasv opened this issue Jan 2, 2025 · 2 comments

Comments

@joshuasv
Copy link

joshuasv commented Jan 2, 2025

Describe the bug
Unable to save a DNG image with the monochrome image sensor OV9281. Missing ColourCorrectionMatrix from metadata.

To Reproduce

#!/usr/bin/python3

# Capture a DNG.

import time
from pprint import pprint

from picamera2 import Picamera2, Preview

SENSOR_MODE = 5

tuning = Picamera2.load_tuning_file("ov9281_mono.json")
tuning["algorithms"].append(
    {
        "rpi.awb":
        {
            "use_derivatives": 0,
            "bayes": 0
        }
    }
)
tuning["algorithms"].append(
    {
        "rpi.ccm":
        {
            "ccms": 
            {
                "cs": 3000,
                "ccm": [1, 0, 0, 0, 1, 0, 0, 0, 1]
            }
        }
    }
)
print("Tuning file:")
pprint(tuning)


picam2 = Picamera2()
picam2.start_preview(Preview.QT)

sensor_modes = picam2.sensor_modes
pprint(sensor_modes)
selected_mode = sensor_modes[SENSOR_MODE]
print(f"Selected sensor mode: {SENSOR_MODE}")
pprint(selected_mode)

preview_config = picam2.create_preview_configuration()
capture_config = picam2.create_still_configuration(
    raw=dict(format=selected_mode["unpacked"], size=selected_mode["size"]),
    sensor=dict(output_size=selected_mode["size"], bit_depth=selected_mode["bit_depth"]),
    # controls=dict(ColourCorrectionMatrix=[1, 0, 0, 0, 1, 0, 0, 0, 1])
)
picam2.configure(preview_config)

picam2.start()
time.sleep(2)

picam2.switch_mode_and_capture_file(capture_config, "full.dng", name="raw")

Expected behaviour
DNG file full.dng is generated.

Console Output, Screenshots

Traceback (most recent call last):
  File "/home/pi5/rpi-data-acquisition-v2/ov9281-test.py", line 58, in <module>
    picam2.switch_mode_and_capture_file(capture_config, "full.dng", name="raw")
  File "/usr/lib/python3/dist-packages/picamera2/picamera2.py", line 1467, in switch_mode_and_capture_file
    return self.dispatch_functions(functions, wait, signal_function, immediate=True)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/picamera2/picamera2.py", line 1363, in dispatch_functions
    return job.get_result(timeout=timeout) if wait else job
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/picamera2/job.py", line 79, in get_result
    return self._future.result(timeout=timeout)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/concurrent/futures/_base.py", line 456, in result
    return self.__get_result()
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/concurrent/futures/_base.py", line 401, in __get_result
    raise self._exception
  File "/usr/lib/python3/dist-packages/picamera2/job.py", line 48, in execute
    done, result = self._functions[0]()
                   ^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/picamera2/picamera2.py", line 1457, in capture_and_switch_back_
    done, result = self.capture_file_(file_output, name, format=format, exif_data=exif_data)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/picamera2/picamera2.py", line 1401, in capture_file_
    request.save_dng(file_output)
  File "/usr/lib/python3/dist-packages/picamera2/request.py", line 178, in save_dng
    return self.picam2.helpers.save_dng(self.make_buffer(name), self.get_metadata(), self.config[name], file_output)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/picamera2/request.py", line 320, in save_dng
    camera = Picamera2Camera(config, metadata)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/pidng/camdefs.py", line 42, in __init__
    self.__settings__()
  File "/usr/lib/python3/dist-packages/pidng/camdefs.py", line 69, in __settings__
    ccm = self.metadata["ColourCorrectionMatrix"]
          ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
KeyError: 'ColourCorrectionMatrix'
QObject::startTimer: Timers can only be used with threads started with QThread
Segmentation fault

Hardware :

Raspberry Pi 5 Model B Rev 1.0

$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 12 (bookworm)
Release:        12
Codename:       bookworm
$ rpicam-hello --list-cameras
Available cameras
-----------------
0 : ov9281 [1280x800 10-bit MONO] (/base/axi/pcie@120000/rp1/i2c@80000/ov9281@60)
    Modes: 'R8' : 640x400 [325.52 fps - (0, 0)/1280x800 crop]
                  1280x720 [180.51 fps - (0, 0)/1280x720 crop]
                  1280x800 [150.97 fps - (0, 0)/1280x800 crop]
           'R10_CSI2P' : 640x400 [260.42 fps - (0, 0)/1280x800 crop]
                         1280x720 [144.40 fps - (0, 0)/1280x720 crop]
                         1280x800 [120.76 fps - (0, 0)/1280x800 crop]

Additional context
Add any other context about the problem here.

@joshuasv joshuasv changed the title [BUG] [BUG] DNG image generation segmentation fault monochrome sensor. Jan 2, 2025
@davidplowman
Copy link
Collaborator

Hi, and thanks for the report. As has been commented elsewhere, we don't make any monochrome sensors ourselves, so this kind of thing is a bit hard for us to write code for and to test. Nonetheless, if you wanted a quick workaround, you might try the following:

import time
from picamera2 import Picamera2

picam2 = Picamera2()
still_config = picam2.create_still_configuration()
picam2.start()

time.sleep(1)

request = picam2.switch_mode_and_capture_request(still_config)

md = request.get_metadata()
md['ColourCorrectionMatrix'] = (1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0)
md['ColourGains'] = (1.0, 1.0)
picam2.helpers.save_dng(request.make_buffer("raw"), md, request.config["raw"], "full.dng")

Whilst that might "work", I'm not sure it's really correct. It's still masquerading as a (colour) Bayer image when it's not, and we should really be reflecting that. We save DNGs using PiDNG which is a third party library, but I can reach out to the author and see if they know anything about this topic.

Finally, the segfault is almost certainly caused by Qt. It really objects to not being the main application thread, and causes nasty errors like this. I expect turning of any Qt-based previews would probably make it go away (but disclaimer: I know nothing about GUI toolkits).

@davidplowman
Copy link
Collaborator

I believe if you do the following

sudo apt update
sudo apt install python3-pidng

this should be fixed.

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

2 participants