I wrote a short C++ program to collect a raw histogram:
#include <stdio.h>
#include <math.h>
#include "libraw/libraw.h"
struct hist_bucket {
int id;
long r;
long g1;
long g2;
long b;
};
int main(int argc, char **argv)
{
if (argc < 2) {
printf("Usage: rawhistogram <rawfile> [number_buckets, default=256]");
exit(0);
}
LibRaw iProcessor;
iProcessor.open_file(argv[1]);
iProcessor.unpack();
iProcessor.raw2image(); //use this to normalize the bayer pattern to RGBG (??)
// set the number of possible values in the raw data range using the libraw data_maximum, default = 16384 (2^14):
int data_range = 16384; //2^14
if (iProcessor.imgdata.color.data_maximum < pow(2,13)) data_range = pow(2,13);
else if (iProcessor.imgdata.color.data_maximum < pow(2,12)) data_range = pow(2,12);
else if (iProcessor.imgdata.color.data_maximum < pow(2,11)) data_range = pow(2,11);
//printf("data range: %d\n", data_range);
//set the number of buckets, default = 256:
int num_buckets = 256;
if (argc >= 3)
num_buckets = atoi(argv[2]);
//printf("number of buckets: %d\n", num_buckets);
hist_bucket histogram[num_buckets];
//initialize channel histograms:
for (int i=0; i< num_buckets; i++) {
histogram[i].id = i;
histogram[i].r = 0;
histogram[i].g1 = 0;
histogram[i].g2 = 0;
histogram[i].b = 0;
}
//collect the channel histograms:
printf(",r,g1,b,g2\n");
for(int i = 0;i < iProcessor.imgdata.sizes.iwidth * iProcessor.imgdata.sizes.iheight; i++) {
if (iProcessor.imgdata.image[i][0] > 0 )
histogram[ int (((float) iProcessor.imgdata.image[i][0] / (float) data_range) * (float) num_buckets) ].r++;
if (iProcessor.imgdata.image[i][1] > 0 )
histogram[ int (((float) iProcessor.imgdata.image[i][1] / (float) data_range) * (float) num_buckets) ].g1++;
if (iProcessor.imgdata.image[i][2] > 0 )
histogram[ int (((float) iProcessor.imgdata.image[i][2] / (float) data_range) * (float) num_buckets) ].b++;
if (iProcessor.imgdata.image[i][3] > 0 )
histogram[ int (((float) iProcessor.imgdata.image[i][3] / (float) data_range) * (float) num_buckets) ].g2++;
}
//print the channel histograms in parallel columns:
for (int i=0; i< num_buckets; i++)
printf("%d,%ld,%ld,%ld,%ld\n", i, histogram[i].r, histogram[i].g1, histogram[i].g2, histogram[i].b);
iProcessor.recycle();
}
You just need libraw-dev (Ubuntu), or libraw (msys2) to compile it. It runs from the command line:
$ rawhistogram DSG_0001.NEF
and you get a 256-bucket histogram set of the four channels R, G1, B, G2 in csv format, ready for loading in your favorite spreadsheet. You can change the number of histogram buckets by adding the number to the command line:
$ rawhistogram DSG_0001.NEF 1024
256 seems to be a good compromise between data precision and manageability.
If anyone REALLY wants to assess the differences weāve been discussing, this is the sort of tool you needā¦