This repository has been archived by the owner on Oct 4, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 22
Method for exposing the raw data #104
Closed
Closed
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
23f4a82
Nealy getting the reading of the raw data to work
paalge 6bf6de9
Working raw data getter. Returns a numpy array
paalge ae7876c
Removed dependency on numpy
paalge bed08b4
Fixed the error handling for none 4 colour images
paalge 657a9b5
catch ValueError
paalge 451f7dc
Fixed line length in comment
paalge a2c8b90
Removed trailing whitespaces
paalge e585b6d
Added get_3_col_raw and fixed the returned image from get_4_col_raw
paalge e7b6c5a
Moved the common code into new function
paalge File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ | |
import random | ||
import string | ||
import tempfile | ||
import warnings | ||
|
||
from collections import namedtuple | ||
from libraw.bindings import LibRaw | ||
|
@@ -175,6 +176,179 @@ def save_thumb(self, filename=None): | |
self.libraw.libraw_dcraw_thumb_writer( | ||
self.data, filename.encode('ascii')) | ||
|
||
def get_4_col_raw(self): | ||
""" | ||
EXPERIMENTAL | ||
|
||
Read the 4 colour raw data, this does NOT include the data outside of | ||
the frame (calibration data, etc) | ||
|
||
Returns None if the input is not a 4 colour image | ||
|
||
The returned array is (given colour RGGB) | ||
--------- | ||
R B R B ... | ||
G B G B ... | ||
R B R B ... | ||
. . . . . | ||
. . . . . | ||
. . . . . | ||
-------- | ||
|
||
|
||
Returns: | ||
list of lists: 4 colour data of the image in unit16. | ||
(height x width) | ||
str : colour channel description (ie. RGGB, RGBG) | ||
""" | ||
# Unpack the data, so that rawdata is populated | ||
self.unpack() | ||
rawdata = self.data.contents.rawdata | ||
sizes = self.data.contents.sizes | ||
|
||
# Return None if the image isn't 4 colour, which will happen for some | ||
# cameras | ||
|
||
try: | ||
rawdata.color4_image.contents | ||
except ValueError: | ||
return None | ||
|
||
if sizes.pixel_aspect != 1: | ||
warnings.warn( | ||
"The pixel aspect is not unity, it is:" + sizes.pixel_aspect) | ||
|
||
if sizes.flip != 0: | ||
raise NotImplemented("Does not support rotations in the image") | ||
|
||
# Get colour cdesc | ||
cdesc = self.data.contents.idata.cdesc | ||
|
||
# Make pointer to data | ||
data_pointer = ctypes.cast( | ||
rawdata.color4_image.contents, | ||
ctypes.POINTER(ctypes.c_ushort) | ||
) | ||
|
||
iwidth = sizes.width | ||
|
||
# Get the data | ||
data = self.__get_raw_data(sizes, data_pointer, iwidth) | ||
# Return data and colour descriptor | ||
return data, cdesc | ||
|
||
def get_3_col_raw(self): | ||
""" | ||
EXPERIMENTAL | ||
|
||
Read the 3 colour raw data, this does NOT include the data outside of | ||
the frame (calibration data, etc) | ||
|
||
Returns None if the input is not a 3 colour image | ||
NB: most raw data is 4 colour, use get_4_col_raw for them | ||
|
||
The returned array is (given colour RGBG) | ||
--------- | ||
R G B 0 R ... | ||
R G B 0 R ... | ||
R G B 0 R ... | ||
. . . . . | ||
. . . . . | ||
. . . . . | ||
-------- | ||
|
||
Returns: | ||
list of lists: 3 colour data of the image in unit16. | ||
( height x 4 width) | ||
str : colour channel description (ie. RGBG) | ||
|
||
|
||
""" | ||
# Unpack the data, so that rawdata is populated | ||
self.unpack() | ||
rawdata = self.data.contents.rawdata | ||
sizes = self.data.contents.sizes | ||
|
||
# Return None if the image isn't 3 colour, which will happen for some | ||
# cameras and for most raw images | ||
|
||
try: | ||
rawdata.color3_image.contents | ||
except ValueError: | ||
return None | ||
|
||
if sizes.pixel_aspect != 1: | ||
warnings.warn( | ||
"The pixel aspect is not unity, it is:" + sizes.pixel_aspect) | ||
|
||
if sizes.flip != 0: | ||
raise NotImplemented("Does not support rotations in the image") | ||
|
||
# Make pointer to data | ||
data_pointer = ctypes.cast( | ||
rawdata.color3_image.contents, | ||
ctypes.POINTER(ctypes.c_ushort) | ||
) | ||
# Get colour cdesc | ||
cdesc = self.data.contents.idata.cdesc | ||
num_col = len(cdesc) | ||
# The width needs to be num_col (4) times this due to the way the image | ||
# is saved | ||
iwidth = sizes.width * num_col | ||
|
||
# Get the data | ||
data = self.__get_raw_data(sizes, data_pointer, iwidth) | ||
|
||
# Return data and colour descriptor | ||
return data, cdesc | ||
|
||
def __get_raw_data(self, sizes, data_pointer, iwidth): | ||
""" | ||
Internal method for getting raw data. Should not be called outside | ||
|
||
Parameters | ||
---------- | ||
sizes : Sizes variable | ||
|
||
data_pointer : c-pointer to the data | ||
|
||
iwidth : image width | ||
|
||
|
||
Returns | ||
---------- | ||
data : 2D matrix of the raw data | ||
""" | ||
|
||
# Get raw image size | ||
raw_width = sizes.raw_width | ||
# raw_height = sizes.raw_height | ||
|
||
# Get margins | ||
left_margin = sizes.left_margin | ||
top_margin = sizes.top_margin | ||
|
||
# Get row pitch (returned in bytes, therefore we divide it in two | ||
# since we are using 16 bit (2 bytes) per pixel | ||
|
||
pitch = int(sizes.raw_pitch / 2) | ||
|
||
# Get frame height size | ||
iheight = int(sizes.height) | ||
|
||
# Compute first | ||
first = raw_width * top_margin + left_margin | ||
|
||
# make 2D list | ||
data = [[0 for i in range(iwidth)] for j in range(iheight)] | ||
|
||
for ii in range(iheight): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we change There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These aren't actually coordinates on the image though since there are multiple indexes per pixel. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They will be coordinates, though you have to interpolate the image first, as in that loop they change between different colour channels. |
||
for jj in range(iwidth): | ||
data[ii][jj] = data_pointer[first + ii * pitch + jj] | ||
|
||
# Return data and colour descriptor | ||
return data | ||
|
||
def to_buffer(self): | ||
""" | ||
Convert the image to an RGB buffer. | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another thing I'm thinking (though this doesn't have to be done right now by any means, I just wanted to comment while I was thinking about it so that it was documented somewhere) is that the public facing API method for this should just work for all types of raws (regardless of how many channels there are). @campaul and I will probably sit down sometime this weekend and figure out a more unified API (including return values and types) for all methods that return image data like this. Will advise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi.
It is easy to change this to the other case (with only 3 colours), as the data then is in
color3_image
and not incolor4_image
. Though before I modify this I would like to know what the return types should be. In my mind we should return something that is 2D, as this removes the need to pass along height and width.