Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rawpy questions (white balance; dcraw -A option) #12

Closed
Steve8650 opened this issue Feb 23, 2016 · 15 comments
Closed

rawpy questions (white balance; dcraw -A option) #12

Steve8650 opened this issue Feb 23, 2016 · 15 comments

Comments

@Steve8650
Copy link

Maik

I hope you don't mind me contacting you again, but I have some questions about the use of rawpy. I'm used to using dcraw directly, and often use the command line option -A , which calculates the white balance from a selected area of the image, and then returns the white balance multipliers on STDERR, ready for use with the option -r for similar images. Rawpy seems to be able to use the -r option, via the user_wb parameter, but I can't find an equivalent of the -A option, nor a means of obtaining the multipliers for future use.

Have I missed something, or are these facilities not present (yet?) in rawpy?

Best wishes

Steve Morton

@letmaik letmaik changed the title rawpy questions rawpy questions (white balance; dcraw -A option) Feb 23, 2016
@letmaik
Copy link
Owner

letmaik commented Feb 23, 2016

Sure, no problem.

The -A option seems to be supported by libraw (libraw_output_params_t greybox[4];) but only when running postprocess / dcraw_process, so I doubt that it is possible to read back the calculated white balance values. But I'm not fully sure, they may get stored somewhere. I will do some tests and check if this is possible, but this will have to wait a few weeks since I'm busy with other work related things currently.

@junaway
Copy link

junaway commented Apr 6, 2016

Any news about this issue?

@Steve8650
Copy link
Author

I've developed a work around that seems OK. It works like this:

  1. Extract the raw image:
    with rawpy.imread(setUpDng) as raw: inImageArray = raw.postprocess(output_color=rawpy.ColorSpace.raw, gamma=(1, 1), use_camera_wb=False, output_bps=8, user_wb=[1.0, 1.0,1.0, 1.0], no_auto_bright=True, bright=1.0, demosaic_algorithm=rawpy.DemosaicAlgorithm.LINEAR)

Important points here are that the user_wb multipliers are all set to 1.0, so no colour balancing will take place. The brightness is also set to 1, with no auto-brightness. I choose the LINEAR demosiac algorithm as it claims to be quickest.
2) Examine the extracted image, and identify the area that you wish to be grey. I temporarily crop the image to that area.
3) From that area only, extract the average R, G and B values
avgR = np.average(cropImageArray[..., 0])
avgG = np.average(cropImageArray[..., 1])
avgB = np.average(cropImageArray[..., 2])

  1. Then scale the R and B average values to the G channel:
    extrMult[0] = avgG/avgR
    extrMult[2] = avgG/avgB

  2. This gives the multiplier values for the R and B channels. The value for the G channel is 1.0, as we have scaled the other to this channel, so that the four values needed are
    extrMult = [avgG/avgR, 1.0, avgG/avgB, 1.0]

  3. Then, I extract the raw image again:
    with rawpy.imread(oldFn) as raw: inImageArray = raw.postprocess(output_color=rawpy.ColorSpace.raw, gamma=(1, 1), use_camera_wb=False, output_bps=16, user_wb=extrMult, no_auto_bright=True, bright=extrBright, demosaic_algorithm=rawpy.DemosaicAlgorithm.AHD)

This seems to work very well. After the second extraction, the selected grey area of the image appears and measures to be neutral grey.

I hope this is clear - get back to me if it isn't!

Steve Morton

@letmaik
Copy link
Owner

letmaik commented Apr 6, 2016

Great work, I think it's actually better if more of that custom functionality happens outside rawpy itself, since it will always have a limited set of base functionality only.
Maybe we can put your example into an ipython notebook, seems like a nice demo.

@junaway
Copy link

junaway commented Apr 6, 2016

I used another strategy:

1st step:
Open a white_balance_file
Unpack it
Set the half_size option to True (for speed)
Process it
Get the RGB image

2nd step:
Select a greybox region (using a custom utility)
Extract the four parameters you would use with the -A keyword (Since half_size is set to True in the first step, you need to multiply by two all the dimensions of the greybox. Why? Because the -A keyword works on the original size.)

3rd step:
Open the same white_balance_file
Unpack it
Set the half_size option to True (for speed again)
Set the user_mul values with the greybox values
Set use_auto_wb to True (very important, otherwise LibRaw doesn't use user_mul, unlike dcraw)
Process it
Extract pre_mul values (using the daylight_whitebalance property from rawpy for example)

Voilà. Those pre_mul values can be used with the -r keyword 👍
I hope I didn't miss any step. This method is working for me and I get the exact same result as dcraw.exe, dcraw64.exe, and dcraw_emu.exe.

Hope that helps.

@Steve8650
Copy link
Author

Steve8650 commented Apr 6, 2016

Thanks for this – particularly the half size option, which I had forgotten about!

It probably isn’t clear from my reply, but this whole colour balance process happens more or less automatically. The only user input required is, first, select the raw file to use for the white balance, and second, to select the neutral area in that file.

The program of which this is a part is intended for processing raw files containing images of colour negative film – i.e I take a photo of the negative on a light box. I use the rawpy user white balance to compensate for the orange base colour of the film, so the colour balance image usually contains a section of clear film base. Once the multipliers have been determined, they can then be applied to the images from all the negatives from that particular film, so I write them into a small file in the same folder as the .dng’s for future use. As an aside, it is interesting how much difference there is between colour negative films, even those by the same manufacturer, and of the same type – no wonder dark room colour printing was so difficult!

Once the multipliers for a particular film have been determined, the raw files from the whole film will be processed with the same values.

I use a similar technique for determined the Brightness value – I use the ratio of the average of the green channel of the reference patch (which in my case is the film base) and calculate the Brightness parameter as 216-1/avgG ( for 16 bit images) i.e. the clear film base represents the brightest part of the (negative) image. Later in the program, after inverting the image, I set both the black and white points using actual image data. Finally, I adjust the final brightness of the image, and tweak the final colour balance, by applying user selectable gamma functions to each channel (i.e. px_out = (px_ingamma)*scaling_factor). Gamma values vary between 0.5 and 3.0, and numpy makes it almost trivial to use look up tables to apply the function to the image data.

The program actually works extremely well. I import the final image (saved as tiff file) into Adobe Lightroom, where any final twiddles can be performed, but often none are needed.

In parallel, I have created a similar program for handling monochrome negatives (of which I have several thousand, dating back to the 1960’s!), which also works well.

I might get round to writing this all up properly on my currently moribund website at www.stevemortonphotography.co.uk, but I probably ought to redo the site first!

Cheers

Steve Morton

@letmaik
Copy link
Owner

letmaik commented May 9, 2016

I was wondering if one of you has a good test image I could use for a public ipython notebook where I would demonstrate the gray area selection and white balance calculations etc. I'm trying to get some examples together. If so, let me know (by email if you prefer) or just upload it somewhere. Thanks in advance!

@Steve8650
Copy link
Author

Steve8650 commented May 10, 2016 via email

@letmaik
Copy link
Owner

letmaik commented May 10, 2016

That's perfect, thanks. The more specialized, the better. It's all about
interesting use cases :)

On 10/05/2016 14:17, Steve8650 wrote:

Hi Mark

I would be happy to let you have a couple of images to show how the
work-around that I described earlier works, but do note that my
application is pretty specialised, and only likely to be meaningful to
someone trying to do the same thing!

It may take a short while to sort out some examples, and explain what
my code is doing, and then I’ll put it on my Google Drive site and
send you a link, if this is OK?

Best wishes

Steve Morton

From: Maik Riechert
Sent: Monday, May 9, 2016 11:46 PM
To: neothemachine/rawpy
Cc: Steve8650 ; State change
Subject: Re: [neothemachine/rawpy] rawpy questions (white balance;
dcraw -A option) (#12)

I was wondering if one of you has a good test image I could use for a
public ipython notebook where I would demonstrate the gray area
selection and white balance calculations etc. I'm trying to get some
examples together. If so, let me know (by email if you prefer) or just
upload it somewhere. Thanks in advance!

@Steve8650
Copy link
Author

OK, here is a link:

https://drive.google.com/folderview?id=0B_1stN2zxz2tSmtsOEN2RWJlXzg&usp=sharing

I’ve tried to explain, succinctly, what it is all about in the file demo.docx, and I think I have included everything you need to actually run the program.

Good luck!

If you do produce a public notebook, could you send me a link? Also, any suggestions for improving the code would be welcome.

Best wishes

Steve

From: Maik Riechert
Sent: Tuesday, May 10, 2016 2:40 PM
To: neothemachine/rawpy
Cc: Steve8650 ; State change
Subject: Re: [neothemachine/rawpy] rawpy questions (white balance; dcraw -A option) (#12)

That's perfect, thanks. The more specialized, the better. It's all about
interesting use cases :)

On 10/05/2016 14:17, Steve8650 wrote:

Hi Mark

I would be happy to let you have a couple of images to show how the
work-around that I described earlier works, but do note that my
application is pretty specialised, and only likely to be meaningful to
someone trying to do the same thing!

It may take a short while to sort out some examples, and explain what
my code is doing, and then I’ll put it on my Google Drive site and
send you a link, if this is OK?

Best wishes

Steve Morton

From: Maik Riechert
Sent: Monday, May 9, 2016 11:46 PM
To: neothemachine/rawpy
Cc: Steve8650 ; State change
Subject: Re: [neothemachine/rawpy] rawpy questions (white balance;
dcraw -A option) (#12)

I was wondering if one of you has a good test image I could use for a
public ipython notebook where I would demonstrate the gray area
selection and white balance calculations etc. I'm trying to get some
examples together. If so, let me know (by email if you prefer) or just
upload it somewhere. Thanks in advance!


You are receiving this because you modified the open/close state.
Reply to this email directly or view it on GitHub

@letmaik
Copy link
Owner

letmaik commented Jun 12, 2016

@Steve8650 I just finished the first version of the notebook. It doesn't go into as much detail as your document and code, but it illustrates the basics that are relevant to the use of rawpy. Let me know if you spot an obvious error or think it can be improved in any way (I'm sure it can!). I simplified the process in some ways (e.g. not using 16 bit images, and using the absolute black level instead of a percentile) but the main principles should be the same.

http://nbviewer.jupyter.org/github/neothemachine/rawpy-notebooks/blob/master/colour-negative/colour-negative.ipynb

@letmaik
Copy link
Owner

letmaik commented Jun 12, 2016

Hmm, I was just wondering. Why is the separate blank film base actually necessary? I mean, there is also blank film at each colour negative at the bottom where the numbers and holes are. It's smaller, but couldn't you just use that?

@Steve8650
Copy link
Author

Maik

That is really good! I hadn’t seen a Juypter notebook ‘in action’ before – impressive!

I hadn’t considered using matplotlib to display the image – it might have been a bit easier than all that messing around with tkinter, although I would still have needed a user interface, I suppose.

A couple of points:-

Right at the start, you should mention that the images used are photographs (not scans) of the negatives, saved as raw files. I don’t see why a similar process wouldn’t work with a film scanner, but most of them come with commercial software to do the conversions. Using a normal DSLR to capture the original negative is quick and easy.

At point 7, the reason that the green channel is used as the reference is that the DSLR sensor has twice as many green pixels as it has red and blue ones (the Bayer matrix), so that, in theory at least, it is the least noisy of the three channels.

Cheers

Steve

From: Maik Riechert
Sent: Monday, June 13, 2016 12:51 AM
To: neothemachine/rawpy
Cc: Steve8650 ; Mention
Subject: Re: [neothemachine/rawpy] rawpy questions (white balance; dcraw -A option) (#12)

@Steve8650 I just finished the first version of the notebook. It doesn't go into as much detail as your document and code, but it illustrates the basics that are relevant to the use of rawpy. Let me know if you spot an obvious error or think it can be improved in any way (I'm sure it can!). I simplified the process in some ways (e.g. not using 16 bit images, and using the absolute black level instead of a percentile) but the main principles should be the same.

http://nbviewer.jupyter.org/github/neothemachine/rawpy-notebooks/blob/master/colour-negative/colour-negative.ipynb


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

@Steve8650
Copy link
Author

Steve8650 commented Jun 13, 2016 via email

@Steve8650
Copy link
Author

Steve8650 commented Jun 13, 2016 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants