DCamProf - a digital camera profiling toolNews2015-05-01New patch release 0.5.1. I hadn't tested on Lightroom properly. It was shown that Lightroom cannot handle too high precision on matrix rationals and it doesn't like if the standard observer WP is different from 1931_2. I have now changed default observer to 1931_2 as it's an easier to use default, and made an automatic remapping in the make-dcp tool to handle the case when a different observer was used during profile creation.
2015-04-30
What is DCamProf?
To generate a camera profile you need either the camera spectral sensitivity functions (SSFs) or a measured target. DCamProf has no measurement functionality, but you can use the free and open-source Argyll CMS to get a .ti3 file with measurement data which DCamProf can read. Here's a feature list:
Note that many features are related to camera SSFs, and indeed you get most out of DCamProf if you have SSFs available. You don't need them to make great profiles though, having them is more about flexibility and convenience than accuracy. You can then also learn many things of how cameras work by testing various scenarios, testing the efficiency of a specific target design, testing how a profile performs under a different illuminant etc. The reason I started this software was that 1) Argyll can't do DCPs, and 2) I was not pleased with the commercially available alternatives for making own camera profiles. Too much hidden under the hood, too little control, and many indications that the quality of the finalized profiles was not that good, mainly regarding with smoothness. Then I added the SSF ability and the software grew to something more than just a profile maker, now you can say it's a camera color rendering simulator as well. The software is quite technical, but if you can use Argyll you can use DCamProf. At some point I will probably make a more in-depth article about camera profiling and using DCamProf which I will link here, but for now there's only the minimal reference documentation found on this page. Downloading and building DCamProfDownload the source code for DCamProf v0.5.1. It's developed on Linux and compiling it there is easy as all third parties should be available as standard packages in your Linux distribution. It should also be relatively easy to build on Mac OS X. I haven't tried on Windows, but it's probably easy to build using Cygwin tools.DCamProf uses OpenMP to make use of all your CPU cores in parallel. You can build it without OpenMP (remove the -fopenmp words from the Makefile) but some aspects of the program will then run much slower as it will use only one core. At the time of writing Mac OS X standard compiler clang doesn't support OpenMP (it's in the works though), unless you build your own clang from source. An alternative to building it on your OS X or Windows platform is simply to install a Linux virtual box and run it there, make sure you give the virtual machine access to all cores. An added bonus is then easy access to Argyll, gnuplot, exiftool and other related tools. How DCamProf models camerasDCamProf looks on the perfect camera as a colorimetric camera, that is the SSFs matches the color matching functions for the CIE XYZ color space. No real camera is colorimetric so the goal of profiling is to make it perform as close as possible to one.DCamProf assumes that the camera is linear, that is if you for example double the intensity of a certain spectrum the raw values will also double and there will be no change in their relation. This is indeed true for any normal digital camera today, with the possible exception of extreme underexposure and very close to clipping where there can be non-linear effects. The linearity assumption leads to that the correction lookup table only needs to be indexed on chromaticity (that is saturation and hue, but not lightness), but the output still needs correction factors for all three dimensions as some colors can be rendered too dark or too light with a fixed factor throughout the full lightness range. That is DCamProf works with a LUT with 2D input and 3D output, commonly referred to as a 2.5D LUT. 2.5D vs 3D LUTWith a 2.5D LUT we assume that the same color in a darker shade will have the same shape of its spectrum, only scaled down. This is true if you render colors darker by reducing the camera exposure in a fixed condition. However, if we compare a dark and light color of the same hue and saturation in a printed media the spectrum shapes will differ because a typical print technology will alter the colorant mix (eg inks) depending on lightness.This means that our linearity assumption breaks as the relative mix of camera raw values may differ slightly between dark and light colors and in this case a full 3D LUT could make a more exact correction. However, this only makes sense in highly controlled conditions when copying known media (such as printed photographs), that is when you're using the camera just like a flatbed scanner. The light source must be fixed, the camera exposure must be fixed, and the camera profile must be designed using a target made with the same materials as the objects you shoot. As a 3D LUT only makes sense in this very narrow use case DCamProf supports only 2.5D (so far). If you really need a 3D LUT you can use Argyll, but you're then limited to ICC profiles. For strict reproduction work that may be a better approach. Note that commercial raw converters often use 3D LUTs, not to achieve better accuracy though but to make film-like subjective lightness-dependent adjustments. For example making dark shades more saturated and cooler (bluer) while highlights of the same color is made warmer (redder). DCamProf is not designed to make profiles that provide subjective "looks". The idea is instead that you start off with as accurate color as possible and then tune the color to your own liking using post-processing color adjustment tools available in raw converters and photo editors. Personally I prefer this way to work as I'm then myself in full control of the look, being fully aware of when and how I deviate from realism rather than letting my look be influenced in unclear ways by the taste of the raw converter manufacturer. Basic workflow for making a profile using a test target
Basic workflow for making a profile from camera SSFsIf you have the camera's spectral sensitivity functions you can skip the target shooting process.
dcamprof make-profile -c ssf.json -i StdA target.ti3 profile.json Choosing test targetDue to natural limitations of camera profiling precision it's quite hard to improve on the classic 24 patch Macbeth color checker when it comes to making profiles for all-around use. It's more important to have a good reference measurement of the test target than to have many patches. If you don't believe me please feel free to make your own experiments with DCamProf; by using camera SSFs you can simulate profiling with both few and many patches and compare target matching between them.DCamProf allows you to use any target you like though, you can even print your own and use a spectrometer and Argyll to get reference values. A modern inkjet printer with the higher end pigment ink sets seems to have quite nice smooth spectra so the quality of these targets should be fine. Use a high quality semi-gloss paper (without optical brighteners!) to produce high saturation patches. Although darker repeats of colors does not hurt there's not much gain from it as the LUT is 2.5D, so an IT-8 style target (most patches are just repeats in darker shades) does not make that much sense. The profiling process requires at least one white (or neutral gray) patch. A slightly off-white patch is no problem (for example if you print your own target on OBA-free paper it's likely slightly yellow), DCamProf will compensate. If you have the camera's SSFs you can use the built-in spectral databases (or import your own) rather than shooting real test targets. In that case you will probably want to select spectral data that matches what you are going to shoot, for example reflectance spectra from nature if you are a landscape photographer.
Test target reference filesThe foundation of profiling using test targets is that the profiling software knows what CIE XYZ coordinate each color patch corresponds to, or even better which reflectance spectrum each color patch has so the software can calculate the XYZ values internally.Higher end test targets may be individually measured so you get a CGATS text file with reference values, and Argyll's scanin tool can use them directly. If you get a standard 24 patch Macbeth color checker you probably don't have an individual reference file and then a generic file like the one provided with DCamProf (cc24_ref.cie) will have to do. Having the reflectance spectra is strongly preferred over pre-calculated XYZ values, so do get that if you can. The problem with pre-calculated values and no spectra is that when changing illuminants the software cannot re-calculate XYZ from scratch using spectral data, but must rely on a chromatic adaptation transform which is less exact. It's also a higher risk for the user to mess up by forgetting to inform DCamProf of which illuminant the XYZ values are related to. If there's spectral data the reference values are always re-generated from scratch to fit the currently used illuminant, which is both exact and convenient. If you have a spectrometer (usually designed for printer profiling) you can measure your target and generate your own reference file with spectra. Using Argyll you do like this:
In some cases you could get the reference spectra in some format that Argyll can't read directly. Argyll is delivered with a few conversion tools to handle other common text formats, cb2ti3, kodak2ti3 and txt2ti3. You may be helped by making a dummy conversion using DCamProf, like this: dcamprof make-target -p input.txt -a "name" output.ti3, and sometimes you may have to do some manual edits in a text editor too to get it into a format Argyll accepts. Shooting test targetsTo consider:
Uneven lighting is a common problem in camera profiling, so do make sure you have even light. If you notice strange bending in the lightness dimension when making the profile, the issue could be an unevenly lit test target. Minimize vignetting by shooting the target relatively small in the center of the image, and use a relatively small aperture (say f/8 if on 135 full frame). Avoid reflections from nearby colored surfaces that may distort the color of the light source. If shooting outdoor, shooting in an open space with someone holding up the test target in front away from the body is a good alternative. If you know what you are doing you can push the exposure a little extra to get optimal "expose to the right" (ETTR) and thus as low noise as possible. But be careful, clipped colors will be a disaster in terms of results. I use to exposure bracket a few shots and check the levels in the linear raw conversion to see that there is no clipping. Argyll's scanin is sensitive to perspective distortion, so try to shoot as straight on as possible, and correct any residual rotation/perspective in the raw conversion. File formatsJSONDCamProf uses JSON as a base for its own file formats. Open the files that comes in the data-examples directory in the DCamProf archive for documentation. The JSON parser in DCamProf has been modified to parse floating point numbers with maximum possible precision.If you get a JSON format error of your hand-edited files it can be hard to figure out where it is, then you can use one of the online JSON validators like JSON lint. Argyll .ti3DCamProf reads Argyll .ti3 files produced by the scanin tool. Note that the Argyll .ti3 format is rich in features and DCamProf only cares about a subset of it. It expects to get RGB measurement triplets matched with XYZ reference values, and possibly (hopefully) spectral data.DCamProf can also generate .ti3 files and will then add some columns specific to DCamProf. Files remain compatible with Argyll though as unknown columns are ignored. The .ti3 format (or rather an even more reduced subset of it) is also used when you want to import spectral data when you make a target to be processed by camera SSFs. An example of this exists in the data-examples directory. DCPDCamProf can read and write DNG camera profiles (DCPs).Command referenceDCamProf is a collection of tools built into a single binary. The first parameter specifies the command (tool) you want to run, then followed by command-specific arguments:dcamprof <command> [command-specific flags] <command args>If you run the binary without parameters you get a list of all commands and their flags. The basic workflow is:
Here follows a description of each command available. make-targetdcamprof make-profile <flags, with inputs> <output.ti3>Make a target file which contains raw camera RGB values paired with reference XYZ values, and (optionally) spectral reflectance. The file format is Argyll's .ti3, with some DCamProf extensions. If you're using Argyll for measuring a target you don't need to use this command, but you can still use it to regenerate XYZ values with a different observer for example (this requires that the .ti3 file contains spectral data). If you have your camera's SSFs you don't need to shoot any physical target, then you render the .ti3 file from scratch using this command. Overview of flags:
Built-in spectral dataDCamProf has a few spectral databases built-in. These come from freely available sources, see the acknowledgments for information.
Generated spectral dataDCamProf has a spectral rendering algorithm that can make reflectance spectra to match any given XYZ coordinate for the chosen observer and illuminant. It's sort of an impossible task as there are an infinite amount of spectra to choose from. In this infinite set DCamProf finds a smooth spectra which has similar properties to real reflectance spectra.Although not a full substitute to real measured data it can be used for experiments, test profile performance, establishing a baseline or filling out for areas where you don't have real spectral data. And indeed, a profile rendered completely from generated spectra will work, try if you like. You can generate spectra along the chromaticity border of a gamut and optionally fill the inside with grid of patches. The samples are always made as light as possible (as high reflectance as possible) for the given chromaticity. Extremely saturated colors are by necessity narrow-band and will thus be darker than less saturated colors. The gamuts available are locus, pointer, srgb, adobergb and prophoto. Add "-grid" suffix, eg "pointer-grid" to create a grid. The grid spacing can be adjusted with the -g parameter. Gamuts with extreme or even out of human gamut colors like locus and prophoto will cause the spectral renderer to fail producing spectra on some chromaticity coordinates, this is normal. Be warned that spectral data generation is very processing intensive. DCamProf uses OpenMP to process several patches in parallel on all available cores, but it can still take minutes to produce a grid, or even hours if it's really dense.
ObserversThe observer is a mathematical model of the eye, defining its spectral sensitivity functions, or color matching functions (CMFs). It's not intended to exactly match the eye's cone response, but to provide "equal" results. The observer SSFs have been mathematically transformed to work better in real applications.When you integrate these CMFs with a spectrum you get the CIE XYZ tristimulus coordinates. That is the observer is key element in modeling what colors we see. As there's no method to actually measure the signals the eye sends to the brain the CMFs have been derived based on results from color matching experiments. The precision is thus dependent on the color matching skills of the people involved in the experiment. The original observer was published as early as 1931, and it's still the number one standard observer. This is not because it's the most exact one, but because the CIE standard organization will not accept new standards unless significant improvement is made. Some minor improvements have been made over the years, but the original 1931 standard observer holds up well enough. There are 2 and 10 degree variants of observers. This simply refers to how large area of the eye the tested color patch covers. With the more narrow 2 degree angle the eye is slightly better at color separation, but the 10 degree generally matches real situations better. The 1931 is a 2 degree observer, and the first standardized 10 degree observer was published in 1964. DCamProf contains a number of observers, you can see a list when running the command without parameters. I'd like to use the 2006 observer as the default one as it's more accurate than the original 1931, and I'd also rather use the 10 degree observer as I think it matches real situations better than the 2 degree. However, as most DCP software expects a 1931_2 observer I've chosen that as the default.
ExamplesRe-generate XYZ reference values with a new illuminant (D65) and observer (using the default 1931_2) for an Argyll-generate .ti3 file:dcamprof make-target -i D65 -p argyll.ti3 output.ti3Generate targets files from scratch using camera SSF and built-in database: dcamprof make-target -c 5dmk2-ssf.json -i StdA -p cc24 output.ti3 dcamprof make-target -c 5dmk2-ssf.json -i StdA -p cc24 -p munsell output.ti3Use the spectral generator to make targets from scratch: dcamprof make-target -c 5dmk2-ssf.json -i 7500K -g 0.01 -p pointer-grid output.ti3 dcamprof make-target -c 5dmk2-ssf.json -i D65 -p pointer -p srgb-grid output.ti3Re-generate both RGB and XYZ values from a previously created file which contains spectral information: dcamprof make-target -c 5dmk2-ssf.json -i D65 -p input.ti3 output.ti3Assemble a target from imported spectra and built-in database: dcamprof make-target -p input1.txt -a "class1" -p input2.txt -a "class2" -p cc24 output.ti3Note that in this last case there is no SSF provided and while the input text files might have RGB values, no RGB values can be generated for the built-in cc24, and the output will thus contain dummy values (zeroes) for the RGB triplets. That is to be used when making a profile you need to run it through again to re-generate RGB values with provided camera SSFs. For convenience the make-profile and test-profile commands support re-generation directly so you usually don't need to re-generate reference values separately with the make-target command. If you are using Argyll source files it's preferred that you include spectra throughout the workflow so XYZ reference will be re-generated with the observer chosen in DCamProf. If not, I recommend using the 1964_10 observer in Argyll and choose that as well in DCamProf. If the XYZ reference values comes without spectra from a source you cannot control it's important to know which observer and illuminant that was used so you can later inform make-profile of that. make-profiledcamprof make-profile [flags] <input-target.ti3> <output-profile.json>Make a camera profile (in DCamProf's own native format, which can be converted later on) based on an Argyll .ti3 target file, either generated by Argyll from a raw test target photo, or by dcamprof make-target. The target file contains test patches with raw RGB values from the camera coupled with reference CIE XYZ coordinates of the patches, and possibly also the spectral reflectance of each patch. Overview of flags:
IlluminantsIt's important that you get illuminants right in order to generate a correct profile. The .ti3 file format does not contain information on which illuminant that was used for the camera raw RGB or XYZ values. This means that you must keep track of that yourself and provide the information to DCamProf via the -i and -I parameters.There are a few possible scenarios:
In the most flexible case you have the camera's SSFs too. In this case also the RGB values are regenerated for the calibration illuminant you choose. If you lack camera SSFs the RGB values in the target file must match the calibration illuminant. That is if you have shot a test target in daylight similar to D65 and made a target file with Argyll you should set the calibration illuminant to D65. If you lack reflectance spectra in the target file the specified XYZ illuminant must match the ones used in the target. The values could for example originate from a target manufacturer reference file, and is then often relative to D50 or D65. Make sure to look it up so you can provide the correct one. If you have measured the XYZ reference values yourself using a spectrometer you should have spectra in the target file. If not they have probably disappeared along the way, look over the workflow and see if you can provide DCamProf with spectral information. DCamProf will need XYZ values for both the calibration illuminant and the "profile connection space" which always is D50. A target file only contains XYZ values for one illuminant, and thus the other or both must be calculated. If there is no spectral information CIECAM02's chromatic transform CAT02 will be used, which does not provide as precise results as when calculating from spectra. If you can't get the spectra, it's best to have reference values relative to D50 as the LUT works in that space. WeightingWeighting is controlled with the -w parameter and is used to specify the importance of colors. There are two purposes, one is to inform the matrix optimizer so it will try to make better fit of one set of colors at the cost of another. The other is to specify a maximally accepted error (in Delta E) for each class of colors, this is then used in matrix optimization but more importantly to relax the LUT bending. A LUT can always stretch, compress and bend to match the target patches exactly, but that can result in sharp and even inverted bends causing ugly gradient transitions (typically most visible in photos with strong out-of-focus blur backgrounds when one color transitions into another). In this case it's better to relax the fitting, and the LUT optimizer will automatically relax in the best way based on the provided acceptable delta E levels.If you create a matrix-only profile matrix fitting is obviously important, but if you make a LUT it's generally not worthwhile fine-tuning matrix weights, as the LUT will correct the residual error anyway. Feel free to experiment though. The matrix optimization result is mostly affected by the actual patches provided. Re-weighting them will have some effect, but changing patch set has typically a much larger effect. When using a LUT it can be better to let the matrix optimizer ignore the delta E relaxing weights, as it may provide a better starting point for the LUT. Use the -M parameter to control this. To assign different weights to different groups of patches the target file must be split into "classes" (=groups of patches), specified through a "SAMPLE_CLASS" column in the file. The idea is that you can have a naming such as "skin", "forest_green", "textiles" etc and then for example assign greater importance to skin-tones. Class names in the target file is a DCamProf concept and is not available in Argyll-generated files. By running an Argyll file through dcamprof make-target -p argyll.ti3 -a name out.ti3 you can add a class column, and then edit the text file manually and change names to split into more classes if you like. That way you can split even a 24 patch color checker into several classes. However, the main purpose of class-splitting is to be used when you have a number of distinct patch sets of different spectral types as you typically have when making a target directly with a camera's SSFs. DCamProf makes a pre-weighting per default (the user weighting is added on top), this is to handle the situation when you combine several patch sets with different density. Some patch sets may have lots of patches concentrated around some specific color, and another may have few patches widely separated. To not cause the dense sets to totally dominate, there's a pre-weighting based on Delta E distances that normalizes all patches. This is generally a good thing, but if you really want "1 patch = 1 unit" you can disable this normalization by adding -W. This normalization only affects the matrix optimizer, the LUT optimizer only looks at the max acceptable delta E deviations. If you don't have any class names (or all patches are in the same class) there's no value in providing a matrix weight. However the delta E relaxation can still be useful. Finding the right weights is a trial-and-error process. Dump reports and plots (-r report_dir) and visualize the results, see the section on report directory files for more examples. For each class you can assign up to five weights using the -w parameter, these are in order:
Here follows a few examples: "-w skin 0,4 -w nature 6,1": the class "skin" should have full LUT correction (0 Delta E) and have 4 times the weight than ordinary patches during matrix optimization, while the class "nature" can be relaxed with up to 6 DE for a smoother LUT, matrix optimizer weight set to 1 (no change). "-w all 3.5": "all" is a reserved name to point out all patches in the target file. Here the LUT optimizer is instructed to relax all patches up to 3.5 DE to make a smoother LUT. "-w all 0,1,4,1,1": 0 delta E, unchanged weighting (1), and then three weighting parameters for delta E, which is the lightness, chroma and hue k weights for the CIEDE2000 algorithm. A higher value means less priority, so here we say we're less bothered with lightness than chroma (saturation) and hue. Lowering the importance of lightness is often a good idea, it's probably the least disturbing to have errors in. Note that all this weighting stuff is only about matching the specific provided patches, the profiler can't magically make the camera work better. For example, if a camera is bad at separating green colors, it will still be bad even if the particular green patches in the target have been mapped correctly. Color matrix and forward matrixYou may have noted that I have adopted the DNG Profile names of matrices also for the native DCamProf format. This is simply because the names are familiar and the concept is good. It doesn't lock the native format to DCP profiles.The forward matrix operates in D50 XYZ space, and using D50 as a reference illuminant is not unique to DNG profiles, it's used for ICC profiles too. As the conversion from the calibration illuminant to D50 is a generic issue DCamProf has adopted the concept with using a forward matrix. Profile-making tipsDo experiment! Learn how to use a plotting tool and plot results. To get a general feel of how profiling works in practice you can play around with one of the example camera SSFs, and then use the acquired knowledge and feel when you tune settings for your targeted camera (where you may not have SSFs).What you will see is that there is no such thing as perfect result, and the farther from the white-point you get tougher it will be to compensate errors. While it can be fun to try to get a profile that works all the way out to the locus it will hurt performance of common colors. It's generally better to maximize performance for colors you're actually going to shoot. Pointer's gamut approximates the limit of how saturated real reflective colors can be, colors outside that need to be represented by emissive (or transmissive) light like lasers and diodes. It's generally not worth-wile trying to get a good match outside Pointer's gamut. If you have the camera's SSF you can plot and see how well the camera can actually separate colors, you will probably see that there are some issues when it comes to extremely saturated colors, and no camera profile can compensate for that. Consider that a perfect match to a specific color checker does not mean that the color precision is perfect, not even for those colors. It's only perfect for the particular spectra the color checker has, somewhat compromised by various measurement errors throughout the profile making process. Therefore I suggest to always apply some LUT relaxing to smoothen profiles at least some. As true perfection cannot be had, it's better to make sure color transitions are smoothly rendered. Using the -m and -f parameters you can experiment with using separate parameters for optimizing the matrix and the LUT. If the LUT seems to need a lot of strange stretching it may be because the matrices are no good, and in some cases it might be worthwhile to render them separately, perhaps with a different patch set even (which is feasible when you're using SSFs). ExamplesIn all examples below I assume the target file has reflectance spectra. If not you need to specify the XYZ reference values illuminant using the -I parameter.Example 1: basic profile making with default parameters, using calibration illuminant StdA (calibration illuminant = the light source the target was shot under): dcamprof make-profile -i StdA target.ti3 profile.jsonExample 2: assuming we have a target with cc24 and pointer border, we make a smoother LUT by relaxing patch matching, 0.5 delta E on cc24 and 4 delta E on the pointer border. We still let the matrix make best match it can without relaxation (-M). We also reduce the importance of lightness matching through setting of the CIE DE2000 weights (4,1,1). By providing camera's SSF (-c) the RGB values will be re-generated for the given illuminant (D65). Plotting data is saved to the "dump" directory (-r). dcamprof make-profile -r dump -c ssf.json -i D65 -M -w cc24 0.5,1,4,1,1 -w pointer 4,1,4,1,1 target.ti3 profile.jsonExample 3: make matrices using one target, and the LUT using another by running make-profile twice: dcamprof make-profile -i D65 target1.ti3 m.json dcamprof make-profile -i D65 -m m.json -f m.json target2.ti3 profile.json test-profiledcamprof test-profile [flags] <target.ti3> <profile.json | profile.dcp>The test profile command is used to test how well a profile can match a specific target. It will print a text summary on the console, for deeper information you should use the -r parameter to dump text files and plots. Overview of flags:
White balancePer default DCamProf will calculate the optimal white balance to match the target as well as possible. This is analogous to setting white balance in your raw converter with the white balance picker on the white patch on a color checker.If you instead want to test how the profile will match colors when the camera is set to a different white balance (such as a camera preset) you can provide a custom white balance via the -w setting. It's given as a balance between red, green and blue, or as channel multipliers. To find out what multipliers a camera is using you can use exiftool on a raw file. White balance can be stored in different ways depending on raw format, it's out of the scope of this documentation to cover it in full. Anyway, in most cases it's some sort of multipliers, and often green is repeated twice, like this: WB RGGB Levels Daylight : 15673 8192 8192 10727And then you simply provide "-w m15673,8192,10727" to DCamProf, note the "m" which say that we provide white balance as multipliers rather than actual resulting balance between the channels which is 1/m. When DCamProf prints a white balance it will show the balance normalized to 1.0, meaning that the above example is translated to 0.52,1,0.76. Analyzing camera color separation performanceThere is a special feature embedded in the test-profile command, which is that if you provide the camera's SSF you can get an analysis of the camera's color separation performance. This is a pure "hardware" test and has thus no relation to the profile so if you are only interested in this result you can provide any dummy profile.To get a sane result you need a highly populated grid of patches to test with. I recommend to generate a locus grid, like this: dcamprof make-target -c cam-ssf.json -p locus-grid -g 0.01 locus-grid.ti3This will take quite some time, but once generated you can reuse this grid with any camera since when you provide the SSF and illuminants the RGB and XYZ values will be regenerated from spectra: dcamprof test-profile -r dump1 -c cam-ssf.json -i D50 locus-grid.ti3 any-profile.jsonTo get the plot you need to provide the -r parameter, and then the file is named ssf-csep.dat. You can plot it for example with this gnuplot script: unset key set palette rgbformula 30,31,32 set cbrange [0:300] plot 'gmt-locus.dat' using 1:2:4 w l lw 4 lc rgb var, \ 'ssf-csep.dat' pt 5 ps 2 lt palette, \ 'gmt-adobergb.dat' w l lc "red", \ 'gmt-pointer.dat' using 1:2:4 w l lw 2 lc rgb varWhat you see is a heat-map in a u'v' chromaticity diagram, here limited to 300 max. Each dot shows how much the camera signal will change in 16 bits (65536 steps) for 1 delta E change in chromaticity (= change in hue and saturation with constant lightness). No current camera is really 16 bit, this is just used as a fixed reference to get a number in a comfortable-to-read range. For this type of test you should not worry about a camera's dynamic range and read noise, shot noise will be the limiting factor. A black dot means that the signal change is zero and thus the camera cannot separate color at that chromaticity location and no profile can ever change that. The test is run against the target provided and it expects a dense grid-like layout of patches, if your target is coarse there can be misleading results. The locus grid generated in this example makes reflectance spectra, so the colors tested are all related to the illuminant, the colors are as light as the illuminant allows for that chromaticity. This means more saturated colors are naturally bit darker and thus harder to separate. However it becomes harder for the eye too. Often cameras will show good separation capability in the purple range, and that is partly because the eye is relatively poor at it. As the values are related to Delta E they will be related to the eye's capability (as modeled by the observer's color matching functions). The diagram always shows values relative to a D50 white point. You can test with a different illuminant using the -i parameter. You will see the result changing, but note that the coordinates are always remapped to D50 in the diagram. Note that the generated locus grid will not go all the way to the edge of the line of purples. This is because the line of purples is actually black (as it's at the border of the eye's sensititivy) so moving in a bit we get saner colors. The spectral generator can still have some issues to reach all the way to the locus and line of purples so you may get some gaps.
DCP vs native DCamProf profilesYou can test both DCPs and native profiles. DCPs will be rendered according to the DNG specification, but tone curve and baseline exposure is ignored. If a DCP contains both HueSatMap and LookTable only the HueSatMap is applied (as the DNG profile intention is such that HueSatMap should be about accuracy, LookTable about a subjective "look"). DCamProf will print information about this when run.By design DCPs cannot represent colors outside the Prophoto gamut triangle, so if you're doing testing with extreme colors close to the locus you will see clipping to the Prophoto gamut edge. Otherwise a DCP should perform about the same as a native profile. If you test a profile from Adobe or other commercial raw converter you will likely see rather large color errors. This is because those profiles are not designed to reproduce accurate colors, but rather to provide a subjective "look", like film. ExamplesExample 1: test how well profile.dcp matches target.ti3 under illuminant StdA, and write text files and plot data to the directory "dump" (it's assumed target.ti3 has spectra, if not you need to provide the -I parameter too):dcamprof test-profile -r dump -i StdA target.ti3 profile.dcpExample 2: test how well the profile will match colors with a camera white balance preset (found out via exiftool for example): dcamprof test-profile -r dump -w m15673,8192,10727 -i D65 target.ti3 profile.jsonExample 3: disable the profile's LUT and see how well the matrix matches the target (note that some DCPs designed with other tools are made such that the matrix is very far from correct color and the LUT is required to get close): dcamprof test-profile -r dump -L -i D65 target.ti3 profile.dcp make-dcpdcamprof make-dcp [flags] <profile.json> <output.dcp>Converts a profile in DCamProf native format to Adobe's DNG Camera Profile (DCP) which can be used directly in various raw converters. There's really not much to this command, generally you only run it with the -c flag to specify unique camera name. Overview of flags:
HueSatMap LUT generationThe DNG HueSatMap is generated from the native 2.5D LUT in the DCamProf profile. This is done by sampling it at the hue and saturation divisions provided. The default is 90,30 (controlled with the -h parameter) which is a quite dense table and there's little reason to change that. If you'd want to change it it's probably to reduce the table size to get a smaller profile.The DCamProf native LUT is spline-interpolated while a HueSatMap is linearly interpolated. This means that you may get smoother gradient transitions if you have a bit denser HueSatMap than needed for actual target matching. Therefore I think the 90,30 density is quite good to have even if the profile is based on very few patches. If you dump plotting data with the -r parameter you will get data for the HueSatMap so you can visualize it. This is useful if you experiment with the table density. Example plot for comparing native LUT with HSM LUT (useful to see if you should adjust HSM table size):
Manual editsWhen running the make-dcp command you can only specify the camera name. If you want to adjust other aspects such as copyright string and more you need to dot this manually by using the dcp2json and json2dcp commands:
Dual-illuminant DNG profilesCurrently DCamProf has no built-in support to directly generate a dual-illuminant profile. However you can do it manually by first creating two separate single-illuminant profiles and then manually merge them by using the dcp2json and json2dcp commands. A good choice of illuminant pair is StdA and D65.To see how the format is, convert an existing dual-illuminant DCP (as provided by Adobe's DNG Converter for example) to JSON and use that as a guide when merging your own file. ExampleBasic conversion, this is what you will do most of the time (replace name with your specific camera name):dcamprof make-dcp -c "Canon EOS 5D mark II" profile.json profile.dcp Report directory filesWhen DCamProf is run with the -r <report_dir> flag enabled it will write data files for plotting and report text files. The files are suitable to plot with gnuplot, but you can use any other plotting software if you like as it's just text files with the numbers in columns.Text filesThe report text files contain patch matching reports:
0 RGB 0.076 0.095 0.040 => XYZ 0.127 0.111 0.055 (0.126 0.109 0.052) DE 1.25 DE LCh 0.16 0.33 1.19 (dark brown)First there's the patch index (0 in this example) then camera raw RGB values (0.0 - 1.0 range), then CIE XYZ reference values (0.0 - 1.0 range), and then within parentheses what XYZ values the conversion made, and then CIEDE2000 values for color difference between reference and converted value, related to the test illuminant. The first delta E value is the total with 1,1,1 k weights, the following three is considering lightness (L) chroma (=saturation, C) and hue (h) separately. In the above example we see that most part of the color difference sits in hue (1.19 delta E). Finally there's a text name of the color. This text name is highly approximate and may not really be that correct, but it roughly points out the type of color in lightness (light, dark), chroma (grayish, strong, vivid etc) and hue. Plot filesIt varies a bit between commands and parameters used which files that are produced, but many will be same, for example if the command processes a target it will produce files related to the target.Most files have u'v' chromaticity coordinates, and if there's lightness there's CIE Luv / CIE Lab lightness divided by 100. The division by 100 is there to make it about the same scale as u'v'. This is the same 3D space as the DCamProf LUT operates in and is roughly "perceptually uniform", that is moving a certain distance in the diagram makes up a certain color difference. However as the space is linear and lightness is normalized it's not as uniform it could be, especially towards the line of purples which in reality goes towards black and thus hard to differ for the eye. Here's a list of data files you can find in the report directory after a run:
Example gnuplot scriptsAs patch colors are often involved I recommend using gnuplot with a gray background rather than the default white. If you use the X11 terminal you do this by starting gnuplot with the following command gnuplot -background gray. All examples here are adapted for a gray background.In gnuplot you do 2D plots with the plot command, and 3D plots with splot. It's often useful to view a 3D plot in 2D though, and thanks to gnuplot's isometric perspective viewing a 3D plot straight from above makes it perfectly 2D. You can rotate a 3D plot using the mouse, and you can zoom in by right-clicking and drawing a zoom-in-box. Type reset and replot to return to the original view. It's not a quick thing to master gnuplot, but with the help of the example scripts here you should be able to get around and do the tasks necessary for visualizing DCamProf data. You can label the axes etc, but I usually make it simple and just remove all labels with unset key.
Be careful to watch gnuplot's auto-scaling of axes. The lightness axis in a LUT often gets greatly exaggerated due to it's not plot at the same scale as chromaticity. You can control the scales with brackets, use the same scale range on all axes: splot [0:0.6] [0:0.6] [-0.3:0.3] \ 'nve-lut.dat' w l lc "beige", \ 'gmt-prophoto.dat' w l lc "red", \ 'gmt-locus.dat' w l lw 4 lc rgb varWith equal scale on the L axis a LUT typically looks very flat as L adjustments are generally minor. More example scripts are found throughout the documentation. Call for spectral databases and camera SSFsDCamProf contains some built-in spectral data that has been retrieved from public sources. I'd like to have more. A database with spectral reflectance of human skin is currently the most desired, useful for rendering portrait profiles.There are reference standard sets such as the ISO TR 16066, but those are not free and cannot be freely redistributed so I can't include that in DCamProf. If you know of any database you think is useful for inclusion please let me know. The other aspect is camera SSFs. It's quite complicated and/or costly to measure camera SSFs so most users will not be able to do that and thus have to rely on public sources. If you can provide camera SSFs or have links to sources I have missed please let me know. Links to camera SSFs
Links to spectral databases
AcknowledgmentsI'd like to thank those that have made camera SSFs and spectral databases available, without those DCamProf would not have been possible in its current form. Currently DCamProf has spectral databases from University of Eastern Finland and BabelColor, see the section with links to spectral databases for references.Thanks to Mike Hutt for the Nelder-Mead simplex implementation which is used in DCamProf for solving various multi-variable complex optimization problems. I also want to thank Jarno Elonen for publishing a thin plate spline implementation which served as base for the DCamProf TPS used for getting a smooth LUT. The copyright for the TPS source is required to be repeated in the documentation, so here it is:
|