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

[HOW-TO] get current value of Brightness, Contrast, etc #168

Closed
shineworld opened this issue Jun 10, 2022 · 3 comments
Closed

[HOW-TO] get current value of Brightness, Contrast, etc #168

shineworld opened this issue Jun 10, 2022 · 3 comments

Comments

@shineworld
Copy link

shineworld commented Jun 10, 2022

I'm using Raspberry Pi4 Bullseye with PiCamera2 (IMX219) which is used as a remote camera and receive commands
from TCP socket and send back frames using UDP to another computer.

I was able to change camera controls with TCP Commands using camera.set_controls() but I was not able to
understand how to retrieve the actual value for example of Brightness necessary to update a trackbar which
regulate the current value of Brightness, Contrast, and Sharpness.

`
def command_set_cap(data):

        def control_value_set(name, value):
            controls = {name: value}
            self.__camera.set_controls(controls)
            
        response = [ERROR]
        if len(data) == 9:
            cap_id = int_read(data, 1)
            cap_value = int_read(data, 5)
            if   cap_id == PROP_ID_BACKLIGHT:
                # TODO
            elif cap_id == PROP_ID_BRIGHTNESS:
                control_value_set('Brightness', cap_value / 100.0)
                response = [OK]
            elif cap_id == PROP_ID_CONTRAST:
                control_value_set('Contrast', cap_value * 2 / 100.0)
                response = [OK]
		...
		..
		.

`
Reading back camera.controls I can have ONLY the limits and default for needed camera options:

`
print(self.__camera.camera_controls)

{
'FrameDurationLimits': (1000, 1000000000, 0),
'ColourCorrectionMatrix': (-16.0, 16.0, 0),
'NoiseReductionMode': (0, 4, 0),
'Contrast': (0.0, 32.0, 1.0),
'AwbMode': (0, 7, 0),
'ScalerCrop': ((0, 0, 0, 0), (65535, 65535, 65535, 65535), (0, 0, 0, 0)),
'AwbEnable': (False, True, 0),
'ExposureValue': (-8.0, 8.0, 0.0),
'ColourGains': (0.0, 32.0, 0),
'AeExposureMode': (0, 3, 0),
'Sharpness': (0.0, 16.0, 1.0),
'Brightness': (-1.0, 1.0, 0.0),
'AeConstraintMode': (0, 3, 0),
'AeMeteringMode': (0, 3, 0),
'AnalogueGain': (1.0, 32.0, 0),
'Saturation': (0.0, 32.0, 1.0),
'ExposureTime': (0, 999999, 0),
'AeEnable': (False, True, 0)
}
`

@davidplowman
Copy link
Collaborator

These are runtime controls and so they apply to particular images from the camera. The trouble is that there's quite a long pipeline between sending values, the camera or ISP seeing them, doing something about them, and then you getting frames back which reflect them (and are all sat in a queue waiting to be read).

If you want to monitor the settings every second, for example, you could do

from picamera2 import Picamera2
import time

picam2 = Picamera2()
picam2.configure(picam2.preview_configuration())
picam2.start()
while True:
    time.sleep(1)
    print(picam2.capture_metadata())

You can also capture an entire "request" which includes all the images and settings from the camera, for example you'd amend the example above with

while True:
    time.sleep(1)
    request = picam2.capture_request()
    image = request.make_array("main")  # this is the image from the "main" stream
    metadata = request.get_metadata()  # this is the metadata which applies to all images in the request
    request.release()  # requests must always be returned to the camera system!

Picamera2 itself doesn't keep track of all the most recent values you sent. If that's what you wanted, you'd have to do it yourself:

last_controls_sent = last_controls_sent | controls_being_sent_now

Hope that helps!

@shineworld
Copy link
Author

shineworld commented Jun 10, 2022

Help was appreciated!

I'm converting an already existing IP camera based on raspberry, which went from USB camera device
and OpenCV: cap=cv2.VideoCapture() to a native raspberry Aducam B0393 with motorized focus.

I'm new to PiCamera2 and overall in libcamera lib so I need to learn step by step how to migrate
the old cap.get(prop_id) cap.set(prop_id, value) to PiCamera2 framework.

I don't need to read continuously the cap properties but:

  • start the camera (I guess there are always default values for Contrast, Brightness, etc).
  • get the oldest settings from a JSON file.
  • get the current cap (camera controls states)
  • apply only different values to camera.set_controls(controls)

Then when a cap (camera controls states) is necessary to change (human activity on UI)
change the camera control and eventually get active value to confirm the change.

@shineworld
Copy link
Author

Solved keeping local dict of applied properties

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