[HOW-TO] Set exposure measurement area with Raspberry Pi Camera

Open
#1,338 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
python, raspberry-pi

Research direction

Start by reproducing the posted Picamera2 script with imx477.json and the custom AeMeteringMode setup, then inspect the rpi.agc metering_modes configuration and the approach from issue #967. Compare the captured exposure when each side of the image is covered; done means confirming whether the custom weights are applied and documenting the required configuration or code change.

Written by the indexing model from the issue text.

Description

Hi there :)

I am trying to take images with a raspberry pi 2018 HQ Camera V1.0 / raspberry Pi 5 combination and I want to manually set the auto exposure metering so that it only meters the right hand side of the camera. As far as I know the tuning file for this camera is the imx477.json.

My question is how can I ensure that my custom metering array is used?

So far I have tried two approaches:

Approach 1:

I did try to directly edit the tuning file like this

"rpi.agc":
{
    "channels": [
        {
            "comment": "Channel 0 is normal AGC",
            "metering_modes":
            {
                "centre-weighted":
                {
                    "weights":
                    [
                        *Array*
                    ]
                },
                "spot":
                {
                    "weights":
                    [
                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                        0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
                        0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
                        0, 0, 0, 0, 0, 1, 2, 3, 2, 1, 0, 0, 0, 0, 0,
                        0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
                        0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

                    ]
                },
                "matrix":
                {
                    "weights":
                    [
                        *Array*
                    ]
                }
                "custom":
                {
                    "weights":
                    [
                        0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 4, 3, 2,
                        0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 5, 4, 3,
                        0, 0, 0, 0, 0, 0, 0, 3, 4, 5, 6, 7, 6, 5, 4,
                        0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 7, 6, 5,
                        0, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 8, 7, 6,
                        0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 9, 9, 8, 7,
                        0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 9, 9, 9, 9, 8,
                        0, 0, 0, 0, 0, 0, 0, 8, 9, 9, 9, 9, 9, 9, 8,
                        0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 9, 9, 9, 9, 8,
                        0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 9, 9, 8, 7,
                        0, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 8, 7, 6,
                        0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 7, 6, 5,
                        0, 0, 0, 0, 0, 0, 0, 3, 4, 5, 6, 7, 6, 5, 4,
                        0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 5, 4, 3,
                        0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 4, 3, 2
                    ]
                }
            },

And then take an image like this, where I select the AeMeteringMode to Custom

from picamera2 import Picamera2
from libcamera import controls
from PIL import Image
from datetime import datetime

tuning = Picamera2.load_tuning_file("imx477_edited.json")
picam2 = Picamera2(tuning=tuning)

picam2.configure(picam2.create_still_configuration())
picam2.start()

picam2.set_controls({"AeMeteringMode": controls.AeMeteringModeEnum.Custom})
img = picam2.capture_array()
Image.fromarray(img).save(f"capture_{datetime.now().strftime('%Y%m%d_%H%M%S')}.jpg")
picam2.stop()

and while this resulted in images being taken, the images did not suggest, that it was only metering the right hand side of the image.

Approach 2:

I then tried to set the array in code similar to the solution that I saw in issue https://github.com/raspberrypi/picamera2/issues/967?new_signup=true

[...]
tuning = Picamera2.load_tuning_file("imx477.json")
algo = Picamera2.find_tuning_algo(tuning, "rpi.agc")
algo["channels"][0]["metering_modes"]["custom"] = {
    "weights": [0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 5, 4, 3, 0, 0, 0, 0, 0, 0, 0, 3, 4, 5, 6, 7, 6, 5, 4, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 7, 6, 5, 0, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 8, 7, 6, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 9, 9, 8, 7, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 9, 9, 9, 9, 8, 0, 0, 0, 0, 0, 0, 0, 8, 9, 9, 9, 9, 9, 9, 8, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 9, 9, 9, 9, 8, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 9, 9, 8, 7, 0, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 8, 7, 6, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 7, 6, 5, 0, 0, 0, 0, 0, 0, 0, 3, 4, 5, 6, 7, 6, 5, 4, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 5, 4, 3, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 4, 3, 2]
}
picam2 = Picamera2(tuning=tuning)
[...

While here I again got no errors and images where taken these are not what I expect given my custom metering array.

Images

These are examples of the images that I took with these approaches.
For this one the left side was covered and here I expect a relatively normal exposure since the right hand side should anyway only be metered.
Image
For this image, however, where the right hand side is covered I would expect a lot of overexposure on the left side, since the metering should only be done for the right hand side.
Image

To me it seems like it then just defaults to a centre-weighted metering mode. How can I ensure that my custom metering array is used?

Any help is greatly appreciated!

Dominant language
Python
Stars
1.2k
Forks
258
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from raspberrypi/picamera2

All issues in raspberrypi/picamera2

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.