Alex,
I am not clear if my earlier follow up was actually posted. So apologies for a repeated post.
The link you had sent me was really helpful. I think I now understand how the cam_xyz, rgb_cam, cam_mul and pre_mul matrices work.
However, the code referenced in the link appears to be older and hence does not contain any reference to ccm. Also, the link does not contain any information/comments about cmatrix.
I just noticed from the latest code that appears to populate cmatrix primarily through calls to cam_xyz_coeff.
Would appreciate any help about these two matrices (ccm and cmatrix)?
no_auto_scale=1 is very special use parameter. If set, it will instruct dcraw_process() to skip scale_colors() step (this step performs WB and data scaling). This is not intended to use with standard LibRaw's interpolation methods, this parameter is targeted if one implements own interpolation (demosaic) that wants to deal with unchanged (not scaled) source data.
It looks like we need to document no_auto_scale better in LibRaw docs :)
To manual control output brightness, use no_auto_bright=1 and change imgdata.params.bright from 1 to something.
I tried auto white balancing and it went a long way toward fixing the issues. I did have to manually reduce the brightness though. Is there a way to control the brightness adjustment in ppm_tiff_writer?
I'm also noticing that the red and blue channels appear very compressed in the output image relative to the green channel. I'm not sure what would cause that.
[edit] I set no_auto_bright = 1 and no_auto_scale = 1 and that seems to have helped. Not sure why one of those would have compressed one channel and not the others. I think I'll probably need to do some custom analysis of the negative to set the white balance and scale of the resulting image. Something about inverting the values seems to throw off the automatic processes.
Ah, ok, that makes sense, thanks for the explanation. I guess I'll have to do something more sophisticated than just inverting the wb coefficients, because the output channels are getting cut off on the high end. Thanks for explaining that!
I want to try to invert the RAW data, rather than the processed data, for a few reasons. The first is that I eventually want to make a tool that outputs a RAW file (using the DNG SDK). While it is possible to invert a negative in most RAW editors by inverting the tone curve, it makes the resulting image difficult to work with, and being able to work with the inverted image in RAW would make things a lot easier.
The second reason is a bit more abstract, and is somewhat of an experiment. The way that the different color emulsion layers work in a negative—specifically the orange mask that negative the color leakage in the magenta and cyan channels—means that for any operation on those channel to work correct, you need to operate in the negative's native color space. The matrix multiplication that converts the RAW data into a color space alters the curves in the individual color channels in a way that makes inverting and cancelling the effect of the orange mask difficult. I'm guessing that the demosaic process might screw with the color channels from the negative as well.
Finally, the ultimate goal of all of this is building a tool that will take 3 RAW exposures—one of each color channel—created by taking a photo of the negative with red, green and blue light, and compositing them together. The tool will then invert the image, white balance and output to RAW.
A lot of this process is derived from the way film scanners work. Most high end film scanners user RGB light sources and black and white sensors to read the three color channels and account for the orange mask by adjusting the analog gain per channel.
1/0.418985 == 2.38672/1.0 (G/R coeffs ratio). Or, in other words, dcraw_process scales WB coeffs to get full data range after WB applied (and scaled at some time).
BTW, I still not sure that RAW value inversion leads in the right direction. Why not invert (w/ mask subtraction) image after raw processing applied?
So I've done a bit of work trying to figure out how to invert the white balance of my image, but I'm seeing some counterintuitive behavior from the white balance process, and I'm hoping you can provide me some insight into what's going on. I compiled libRaw with DCRAW_VERBOSE enabled to get some transparency into what white balance coefficients were actually getting used, and this is what I'm observing.
If I make no change to any white balance settings, I get: multipliers 2.858569 1.000000 1.338857 1.000000
If I run this loop, which inverts the white balance value for each channel:
for(int i = 0;i < 3; i++) {
if (ImageProcessor.imgdata.color.cam_mul[i] != 0) {
ImageProcessor.imgdata.params.user_mul[i] = 1 / ImageProcessor.imgdata.color.cam_mul[i];
}
}
I can see that my user_mul values are set correctly, but the draw_process uses different values for some reason.
I even tried manually setting the user_mul values, but got the same result. I'm sort of at a loss for where the multipliers that get used are coming from.
Alex,
Thanks for your reply. I will use the COLOR function to serve as an index into the cdesc.
I actually figured out what I was doing wrong. I got the bit order of the filters field wrong. It says that filters represents an 8x2 area with 2 bits per pixel. I assumed that bits 31-30 and 29-28 corresponds to the top two pixels in this 8x2 area. But it turns out that bits 0-1 and 2-3 correspond to the top two pixels in this 8x2 area. I tested this hypothesis for a bunch of files and it seems to hold. Hope my understanding this correct.
Also, what does the colors field in the libraw_iparams_t represent?
C-API getters/setters are indeed limited (to the ones that really used in real applications), your contributions are welcome (please use GitHub pull request for that).
Besides that, tiff/ppm writer is very limited, esp. in tiff part (no compression, no striping/tiling, etc, etc). It is not intended for use in any real application, this is just a placeholder, to allow LibRaw samples to write some files.
Use make_mem_image() and your preferred TIFF writer (e.g. libtiff) in real apps.
i am exactly stuck at the same spot as NicolasB although I am using VB.Net. but in the end there is no option to access the params.ouput_tiff from the DLLimport statements/ C API. so I can only create a ppm file and not a tiff
Alex i see that you point to some setters in your comment but i dont see any in the doc nor the source "libraw.h" file that could change the "output_tiff" value.
Note that the method posted above by NicolasB essentially lets libraw.dll do the whole work and no real object is passed back to the calling .NET program
The alternative would be to recreate the whole C++ class structure in VB (or C#) which is quite daunting just for this simple function.
To check color accuracy it is better to check something with known colors and even spectral response (e.g. color checker) and known light source, not wall with unknown dye used under unknown light
I hope you support Canon Eos RP raw format (cr3).
cmatrix is camera color data similar to rgb_cam, but calculated from in-RAW color data.
ccm is also 'camera color matrix' retireved from RAW in 'as is' (excl. normalizing) form.
Alex,
I am not clear if my earlier follow up was actually posted. So apologies for a repeated post.
The link you had sent me was really helpful. I think I now understand how the cam_xyz, rgb_cam, cam_mul and pre_mul matrices work.
However, the code referenced in the link appears to be older and hence does not contain any reference to ccm. Also, the link does not contain any information/comments about cmatrix.
I just noticed from the latest code that appears to populate cmatrix primarily through calls to cam_xyz_coeff.
Would appreciate any help about these two matrices (ccm and cmatrix)?
Dinesh
no_auto_scale=1 is very special use parameter. If set, it will instruct dcraw_process() to skip scale_colors() step (this step performs WB and data scaling). This is not intended to use with standard LibRaw's interpolation methods, this parameter is targeted if one implements own interpolation (demosaic) that wants to deal with unchanged (not scaled) source data.
It looks like we need to document no_auto_scale better in LibRaw docs :)
To manual control output brightness, use no_auto_bright=1 and change imgdata.params.bright from 1 to something.
I tried auto white balancing and it went a long way toward fixing the issues. I did have to manually reduce the brightness though. Is there a way to control the brightness adjustment in ppm_tiff_writer?
I'm also noticing that the red and blue channels appear very compressed in the output image relative to the green channel. I'm not sure what would cause that.
[edit] I set no_auto_bright = 1 and no_auto_scale = 1 and that seems to have helped. Not sure why one of those would have compressed one channel and not the others. I think I'll probably need to do some custom analysis of the negative to set the white balance and scale of the resulting image. Something about inverting the values seems to throw off the automatic processes.
I will take a look at that link. I will get back to you if I have any questions.
Dinesh
LibRaw's postprocessing is mostly similar with dcraw.c's one (that's why postprocessing procedure is called dcraw_process())
So, most of your questions are answered in 'dcraw annotated' site: https://ninedegreesbelow.com/files/dcraw-c-code-annotated-code.html
For DNG-specific processing (color data extraction etc) look into DNG specs
1) imgdata.params.output_color=0 will output resulting demosaiced image in 'camera' color space.
3) highlight clipping may occur because
a) red or blue channel is clipped due to WB
b) or auto-brightness applied in ppm_tiff_writer or make_mem_image
Ah, ok, that makes sense, thanks for the explanation. I guess I'll have to do something more sophisticated than just inverting the wb coefficients, because the output channels are getting cut off on the high end. Thanks for explaining that!
I want to try to invert the RAW data, rather than the processed data, for a few reasons. The first is that I eventually want to make a tool that outputs a RAW file (using the DNG SDK). While it is possible to invert a negative in most RAW editors by inverting the tone curve, it makes the resulting image difficult to work with, and being able to work with the inverted image in RAW would make things a lot easier.
The second reason is a bit more abstract, and is somewhat of an experiment. The way that the different color emulsion layers work in a negative—specifically the orange mask that negative the color leakage in the magenta and cyan channels—means that for any operation on those channel to work correct, you need to operate in the negative's native color space. The matrix multiplication that converts the RAW data into a color space alters the curves in the individual color channels in a way that makes inverting and cancelling the effect of the orange mask difficult. I'm guessing that the demosaic process might screw with the color channels from the negative as well.
Finally, the ultimate goal of all of this is building a tool that will take 3 RAW exposures—one of each color channel—created by taking a photo of the negative with red, green and blue light, and compositing them together. The tool will then invert the image, white balance and output to RAW.
A lot of this process is derived from the way film scanners work. Most high end film scanners user RGB light sources and black and white sensors to read the three color channels and account for the orange mask by adjusting the analog gain per channel.
1/0.418985 == 2.38672/1.0 (G/R coeffs ratio). Or, in other words, dcraw_process scales WB coeffs to get full data range after WB applied (and scaled at some time).
BTW, I still not sure that RAW value inversion leads in the right direction. Why not invert (w/ mask subtraction) image after raw processing applied?
So I've done a bit of work trying to figure out how to invert the white balance of my image, but I'm seeing some counterintuitive behavior from the white balance process, and I'm hoping you can provide me some insight into what's going on. I compiled libRaw with DCRAW_VERBOSE enabled to get some transparency into what white balance coefficients were actually getting used, and this is what I'm observing.
If I make no change to any white balance settings, I get: multipliers 2.858569 1.000000 1.338857 1.000000
If I run this loop, which inverts the white balance value for each channel:
I can see that my user_mul values are set correctly, but the draw_process uses different values for some reason.
user_mul: 0.418985 1.000000 0.599532 0.000000
multipliers 1.000000 2.386720 1.430915 2.386720
I even tried manually setting the user_mul values, but got the same result. I'm sort of at a loss for where the multipliers that get used are coming from.
Yes.
And many (not all) color matrices in adobe_coeff() are 9-items (3x3), not 12 (4x3).
Also, for 3-color images 4th component is moved to image[][2] before interpolation step.
Alex,
Thanks for the clarification. Does it mean that if colors == 3, then the cam_xyz is effectively 3x3 matrix?
Dinesh
colors is color (component) count really :). It may be 3 or 4 even for RGB(G) files if two greens are different.
For 2x2 bayer images, color (index) is:
(imgdata.idata.filters >> (((row << 1 & 14) | (col & 1)) << 1) & 3);
Alex,
Thanks for your reply. I will use the COLOR function to serve as an index into the cdesc.
I actually figured out what I was doing wrong. I got the bit order of the filters field wrong. It says that filters represents an 8x2 area with 2 bits per pixel. I assumed that bits 31-30 and 29-28 corresponds to the top two pixels in this 8x2 area. But it turns out that bits 0-1 and 2-3 correspond to the top two pixels in this 8x2 area. I tested this hypothesis for a bunch of files and it seems to hold. Hope my understanding this correct.
Also, what does the colors field in the libraw_iparams_t represent?
Followup:
if you need to know *color* for given pixel, not 'color index', use value returned by COLOR() as index in cdesc.
DCRAW_VERBOSE has removed from current 'snapshot' when cleaning up (outdated) source code generation from (patched) dcraw.c
It is still available in 0.19-release
cdesc is not a pattern, it is just indication (RGB or CMYK or CMYG, etc), so for all four R-G-B-G2 orders possible cdesc will be set to RGBG
C-API getters/setters are indeed limited (to the ones that really used in real applications), your contributions are welcome (please use GitHub pull request for that).
Besides that, tiff/ppm writer is very limited, esp. in tiff part (no compression, no striping/tiling, etc, etc). It is not intended for use in any real application, this is just a placeholder, to allow LibRaw samples to write some files.
Use make_mem_image() and your preferred TIFF writer (e.g. libtiff) in real apps.
Hi,
i am exactly stuck at the same spot as NicolasB although I am using VB.Net. but in the end there is no option to access the params.ouput_tiff from the DLLimport statements/ C API. so I can only create a ppm file and not a tiff
Alex i see that you point to some setters in your comment but i dont see any in the doc nor the source "libraw.h" file that could change the "output_tiff" value.
Note that the method posted above by NicolasB essentially lets libraw.dll do the whole work and no real object is passed back to the calling .NET program
The alternative would be to recreate the whole C++ class structure in VB (or C#) which is quite daunting just for this simple function.
I do not see very big problem here.
To check color accuracy it is better to check something with known colors and even spectral response (e.g. color checker) and known light source, not wall with unknown dye used under unknown light
Yes, they are also wrong. Here's a link to the shots by both 1100D and 80D: https://drive.google.com/open?id=1WXae5dDIwxz77b2JD9cSPv-LXasytjN3
I used the following commands for dcraw_emu to get comparable-brightness results:
dcraw_emu -W -b 5 80D.CR2
dcraw_emu -W -b 3.5 1100D.CR2
I've not checked how accurate the 1100D colors are, but at least they seem more believable.
Just found libraw_dcraw_make_mem_thumb, which seems to be working...
I've made progress - I now have it building using the C api...
I'm puzzled by this, however.
This code works:
libraw_data_t * image = libraw_init(0);
libraw_open_file(image, "IMG_0174.cr2");
libraw_unpack_thumb(image);
libraw_dcraw_thumb_writer(image, "h:\\outcr2.jpg");
The return codes from all function calls is zero, and the output file is created ok.
Yet, when I examine the image->thumbnail properties, everything is zero and the thumbnail type is LIBRAW_THUMBNAIL_UNKNOWN
I'd like to be able to process the thumbnail data without wasting time writing to disk, but it doesn't seem to be there. Yet it writes to disk ok.
Is there some other step I need to take to get to the thumbnail/preview data?
Many thanks
Are colors generated by dcraw_emu are wrong? If so, could you please provide raw file sample?
Pages