user3501476
user3501476

Reputation: 1153

Reading pre-processed cr2 RAW image data in python

I am trying to read raw image data from a cr2 (canon raw image file). I want to read the data only (no header, etc.) pre-processed if possible (i.e pre-bayer/the most native unprocessed data) and store it in a numpy array. I have tried a bunch of libraries such as opencv, rawkit, rawpy but nothing seems to work correctly.

Any suggestion on how I should do this? What I should use? I have tried a bunch of things.

Thank you

Upvotes: -1

Views: 3331

Answers (2)

letmaik
letmaik

Reputation: 3500

Since libraw/dcraw can read cr2, it should be easy to do. With rawpy:

#!/usr/bin/env python

import rawpy
raw = rawpy.imread("/some/path.cr2")
bayer = raw.raw_image # with border
bayer_visible = raw.raw_image_visible # just visible area

Both bayer and bayer_visible are then a 2D numpy array.

Upvotes: 2

user1087001
user1087001

Reputation:

You can use rawkit to get this data, however, you won't be able to use the actual rawkit module (which provides higher level APIs for dealing with Raw images). Instead, you'll want to use mostly the libraw module which allows you to access the underlying LibRaw APIs.

It's hard to tell exactly what you want from this question, but I'm going to assume the following: Raw bayer data, including the "masked" border pixels (which aren't displayed, but are used to calculate various things about the image). Something like the following (completely untested) script will allow you to get what you want:

#!/usr/bin/env python

import ctypes

from rawkit.raw import Raw

with Raw(filename="some_file.CR2") as raw:

    raw.unpack()

    # For more information, see the LibRaw docs:
    # http://www.libraw.org/docs/API-datastruct-eng.html#libraw_rawdata_t
    rawdata = raw.data.contents.rawdata

    data_size = rawdata.sizes.raw_height * rawdata.sizes.raw_width
    data_pointer = ctypes.cast(
        rawdata.raw_image,
        ctypes.POINTER(ctypes.c_ushort * data_size)
    )
    data = data_pointer.contents

    # Grab the first few pixels for demonstration purposes...
    for i in range(5):
        print('Pixel {}: {}'.format(i, data[i]))

There's a good chance that I'm misunderstanding something and the size is off, in which case this will segfault eventually, but this isn't something I've tried to make LibRaw do before.

More information can be found in this question on the LibRaw forums, or in the LibRaw struct docs.

Storing in a numpy array I leave as an excersize for the user, or for a follow up answer (I have no experience with numpy).

Upvotes: 0

Related Questions