Message ID | CAMAFT9Utd9QxTma=_bMu1DkzHoS-J39H9rQcJ01oOVwcyg+cyA@mail.gmail.com |
---|---|
State | RFC |
Headers | show |
Series |
|
Related | show |
On Tue, 25 Apr 2023 at 05:24, David Plowman <david.plowman@raspberrypi.com> wrote: > > Hi > > It should also be possible to request a raw stream at the full sensor > resolution, but set the output size to the crop that you really want. > Initially you'll obviously find that the full image is being > downscaled to your output resolution. But then set the ScalerCrop to > match the output size that you asked for, and you should be able to > get a 1:1 crop from the full resolution image. Does that help? > > David This sounds similar to Laurent's idea below. It worked, thank you. For future reference, I spent some time figuring out that my dummy raw stream needed two properties to function as a sensor resolution setting, only: rawConfig.colorSpace = ColorSpace::Raw; rawConfig.bufferCount = 0; Without the colorSpace setting, Camera::configure fails even with a prior CameraConfiguration::validate. Without the bufferCount setting, you won't get any request callbacks. > > On Tue, 25 Apr 2023 at 07:34, Laurent Pinchart via libcamera-devel > <libcamera-devel@lists.libcamera.org> wrote: > > > > Hi Elias, > > > > On Mon, Apr 24, 2023 at 08:04:22PM -0600, Elias Naur via libcamera-devel wrote: > > > Hi, > > > > > > I'd like to squeeze out as much resolution as possible from my Raspberry Pi camera v1 > > > for scanning QR codes. The camera has a fixed focus at ~50cm from the lens, so the > > > resolution gain from moving the QR codes closer is lost to blur from the loss of focus. > > > > > > My current strategy is to scan codes at a distance, but use the considerable resolution > > > of the sensor (~2500x1900) to gain enough resolution for successful scans. > > > > > > However, I fail to find any way to achieve that with libcamera. I tried three options, all > > > suboptimal: > > > > > > 1. Configure the camera for full resolution and crop to a smaller section in my program. > > > That works surprisingly well, except that the white-balance etc. algorithms run on the full > > > image and not just the cropped part. > > > 2. Configure the camera for full resolution and set controls::ScalerCrop to the area > > > of interest. This seems to fix the white-balance algorithms, but results in the cropped > > > area being *upscaled* to full resolution when I receive them. Scanning for QR codes > > > at full resolution is way too slow on a RPi Zero. > > > 3. Configure the camera for the same resolution of the area of interest, and set > > > controls::ScalerCrop. This is efficient, but the sensor is configured for the low > > > resolution and thus ruins the resolution gain. > > > > > > Questions: > > > 1. Is there another way? > > > > How about capturing full resolution frames, without cropping in the > > capture pipeline, and scanning for the QR code in the area of interest > > only ? > > I believe this is my option 1. above. It works, except that auto-white balance etc. runs on the full field of view and not just the cropped subimage. > > > 2. The following hack works for me, > > > > > > diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp > > > b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp > > > index 00600441..6ed81dc1 100644 > > > --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp > > > +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp > > > @@ -842,7 +842,7 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config) > > > * request, and apply it to the sensor with the cached transform, if > > > * any. > > > */ > > > - V4L2SubdeviceFormat sensorFormat = findBestFormat(data->sensorFormats_, rawStream ? sensorSize : maxSize, bitDepth); > > > + V4L2SubdeviceFormat sensorFormat = findBestFormat(data->sensorFormats_, Size{2592,1944}, bitDepth); > > > const RPiCameraConfiguration *rpiConfig = static_cast<const RPiCameraConfiguration *>(config); > > > ret = data->sensor_->setFormat(&sensorFormat, rpiConfig->combinedTransform_); > > > if (ret) > > > > > > Would a similar change that *always* uses the full sensor resolution be acceptable? > > > I can't discern any performance issues between full resolution and lower resolution. > > > > You can't hardcode a specific resolution, as this wouldn't work properly > > with other sensors. Always selecting the sensor full resolution is also > > not acceptable, as that will limit the frame rate on high resolution > > sensors (e.g. the Raspberry Pi HQ camera will be limited to 15fps). > > I thought so. > > > 3. If the above fix is unacceptable, what is the right way to fix this > > > issue in libcamera? > > > > The current way to select the sensor resolution is a bit of a hack. You > > need to add a raw stream to your camera configuration, set to the full > > sensor resolution. You don't need to submit buffers for that stream when > > queuing requests, so you can just capture from the processed YUV stream > > as you do now. > > > > We will likely implement in the future an easier API to select the > > sensor resolution. > > This idea worked, thank you! As you may have expected it took me a while to figure out the right incantations, so a more intuitive way of setting the sensor resolution would be greatly appreciated. Elias
diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 00600441..6ed81dc1 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -842,7 +842,7 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config) * request, and apply it to the sensor with the cached transform, if * any. */ - V4L2SubdeviceFormat sensorFormat = findBestFormat(data->sensorFormats_, rawStream ? sensorSize : maxSize, bitDepth); + V4L2SubdeviceFormat sensorFormat =