-
Notifications
You must be signed in to change notification settings - Fork 22
Method for exposing the raw data #104
Changes from 4 commits
23f4a82
6bf6de9
ae7876c
bed08b4
657a9b5
451f7dc
a2c8b90
e585b6d
e7b6c5a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -175,6 +175,57 @@ def save_thumb(self, filename=None): | |
self.libraw.libraw_dcraw_thumb_writer( | ||
self.data, filename.encode('ascii')) | ||
|
||
def get_4_col_raw(self): | ||
""" | ||
Read the 4 colour raw data | ||
The returned numpy array is (given colour RGGB) | ||
--------- | ||
R B R B ... | ||
G B G B ... | ||
R B R B .... | ||
. . . . . | ||
. . . . . | ||
. . . . . | ||
-------- | ||
|
||
|
||
Returns: | ||
array: 4 colour data of the image in unit16. (width x height) | ||
str : colour channel description (ie. RGGB, RGBG) | ||
""" | ||
# Unpack the data, so that rawdata is populated | ||
self.unpack() | ||
rawdata = self.data.contents.rawdata | ||
|
||
# Return None if the image isn't 4 colour, which will happen for some | ||
# cameras | ||
|
||
try: | ||
rawdata.color4_image.contents | ||
except: | ||
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. Ah, this makes sense, thanks! Let's catch the actual exception here though; bare excepts can have unintended side effects :) |
||
return None | ||
|
||
# Get image size | ||
iheight = rawdata.sizes.iheight | ||
iwidth = rawdata.sizes.iwidth | ||
|
||
# Make pointer to data | ||
|
||
data_pointer = ctypes.cast( | ||
rawdata.color4_image.contents, | ||
ctypes.POINTER(ctypes.c_ushort) | ||
) | ||
|
||
# make 2D list | ||
data = [[0 for i in range(iheight)] for j in range(iwidth)] | ||
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. This might be cleaner, no idea if there's a "standard" way to do this in Python: data = [None] * iheight * iwidth It might be a pre-mature optimization either way though. Or I may be completely wrong. Just thinking out loud. @campaul? 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. It needs to be 2D, or you'll have to pass height and width on, and let the calling function do the reshape. 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. Sounds good then. I think the above will make a 2d list too, but I could be mistaken. If we're going to have to iterate anyways though I think we might as well not preallocate. 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. A quick quick test gives it as a 1D. 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. If we're going to loop and append, 0's though we might as well just loop and append the data. I'm not sure this is actually an optimization, unless Python does some sort of optimization on simple list comprehensions that I don't know about. 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. This would probably be more efficient. I'll do some timings later and see for sure.
|
||
|
||
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[jj][ii] = data_pointer[ii * iwidth + jj] | ||
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. This still appears to be subscripting a 2D array; won't this be broken? 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. In my test run this works as intended. 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. Oh right, yah, I was misunderstanding a large chunk of our discussion, sorry. I think it's best to make this a 1D list to match the data that we get from LibRaw / elsewhere in rawkit. Not sure though; will consider the API implications of doing this and get back to you. It's not super important right now. |
||
|
||
# Return data and colour descriptor | ||
return data, self.data.contents.idata.cdesc | ||
|
||
def to_buffer(self): | ||
""" | ||
Convert the image to an RGB buffer. | ||
|
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.