[libcamera-devel] [PATCH 3/3] utils: raspberrypi: ctt: dng_load_image: Work with DNG files from Picamera2
David Plowman
david.plowman at raspberrypi.com
Thu Jul 7 09:35:39 CEST 2022
Hi Laurent
Thanks for the review!
On Wed, 6 Jul 2022 at 19:32, Laurent Pinchart
<laurent.pinchart at ideasonboard.com> wrote:
>
> Hi David and William,
>
> Thank you for the patch.
>
> On Wed, Jul 06, 2022 at 11:18:36AM +0100, David Plowman via libcamera-devel wrote:
> > From: William Vinnicombe <william.vinnicombe at raspberrypi.com>
> >
> > The exif tags are different between raw files from libcamera-apps and
> > from Picamera2, causing issues loading data.
> >
> > Add code to identify which tags are being used, and then load the
> > metadata from the correct tags.
> >
> > Signed-off-by: William Vinnicombe <william.vinnicombe at raspberrypi.com>
> > ---
> > utils/raspberrypi/ctt/ctt_image_load.py | 26 ++++++++++++++++++-------
> > 1 file changed, 19 insertions(+), 7 deletions(-)
> >
> > diff --git a/utils/raspberrypi/ctt/ctt_image_load.py b/utils/raspberrypi/ctt/ctt_image_load.py
> > index 934db123..29c17581 100644
> > --- a/utils/raspberrypi/ctt/ctt_image_load.py
> > +++ b/utils/raspberrypi/ctt/ctt_image_load.py
> > @@ -301,17 +301,29 @@ def dng_load_image(Cam, im_str):
> > metadata.read()
> >
> > Img.ver = 100 # random value
> > - Img.w = metadata['Exif.SubImage1.ImageWidth'].value
> > + """
> > + libcamera-apps create a separate Exif.Subimage1 for the picture
> > + picamera2 stores everything under Exif.Image
>
> Is this valid according to the DNG specification ? Or is it that
> picamera2 produces TIFF/EP files instead of DNG ? Is there a reason not
> to use DNG in all cases ?
Actually DNG and EXIF are all really flavours of TIFF. I would say
that Picamera2, which uses the PiDNG library, does it properly. In C++
we use libtiff which, as far as I can tell, doesn't really support
"modern" flavours of DNG-style TIFF. For example, you can't include
exposure times in the main image which PiDNG can.
But they are all DNGs, and DarkTable, RawTherapee and dcraw support
all of them. Just there are some annoying implementation details...
David
>
> > + this code detects which one is being used, and therefore extracts the correct values
> > + """
> > + try:
> > + Img.w = metadata['Exif.SubImage1.ImageWidth'].value
> > + subimage = "SubImage1"
> > + photo = "Photo"
> > + except KeyError:
> > + Img.w = metadata['Exif.Image.ImageWidth'].value
> > + subimage = "Image"
> > + photo = "Image"
> > Img.pad = 0
> > - Img.h = metadata['Exif.SubImage1.ImageLength'].value
> > - white = metadata['Exif.SubImage1.WhiteLevel'].value
> > + Img.h = metadata[f'Exif.{subimage}.ImageLength'].value
> > + white = metadata[f'Exif.{subimage}.WhiteLevel'].value
> > Img.sigbits = int(white).bit_length()
> > Img.fmt = (Img.sigbits - 4) // 2
> > - Img.exposure = int(metadata['Exif.Photo.ExposureTime'].value*1000000)
> > - Img.againQ8 = metadata['Exif.Photo.ISOSpeedRatings'].value*256/100
> > + Img.exposure = int(metadata[f'Exif.{photo}.ExposureTime'].value*1000000)
> > + Img.againQ8 = metadata[f'Exif.{photo}.ISOSpeedRatings'].value*256/100
> > Img.againQ8_norm = Img.againQ8 / 256
> > Img.camName = metadata['Exif.Image.Model'].value
> > - Img.blacklevel = int(metadata['Exif.SubImage1.BlackLevel'].value[0])
> > + Img.blacklevel = int(metadata[f'Exif.{subimage}.BlackLevel'].value[0])
> > Img.blacklevel_16 = Img.blacklevel << (16 - Img.sigbits)
> > bayer_case = {
> > '0 1 1 2': (0, (0, 1, 2, 3)),
> > @@ -319,7 +331,7 @@ def dng_load_image(Cam, im_str):
> > '2 1 1 0': (2, (3, 2, 1, 0)),
> > '1 0 2 1': (3, (1, 0, 3, 2))
> > }
> > - cfa_pattern = metadata['Exif.SubImage1.CFAPattern'].value
> > + cfa_pattern = metadata[f'Exif.{subimage}.CFAPattern'].value
> > Img.pattern = bayer_case[cfa_pattern][0]
> > Img.order = bayer_case[cfa_pattern][1]
> >
>
> --
> Regards,
>
> Laurent Pinchart
More information about the libcamera-devel
mailing list