I think, I need to describe processing stages in LibRaw (simplified case, bayer image)
1) open_file() - reads metadata (EXIF and makernotes)
2) unpack() - decodes file contents into imgdata.rawdata.raw_image.
COLOR() call is useful after that: to know what color has pixel at (row,col).
3) dcraw_process():
- do raw2image() internally, allocate imgdata.image[] and populate
imgdata.image[row*width+col[COLOR(row,col)] = rawdata.raw_image[(row+top)*raw_width+col+left]
- do white balance
- than bayer interpolation
- and other possible postprocessing such as denoise or highlight recovery
- than output color conversion and data scale
After that, image[row*width+col] has [0..2] components filled with RGB values and something in [3]
4) dcraw_make_mem_image() may be used to create 3-component bitmap (with gamma correction), in 8- or 16-bit per component to be written into TIFF/JPEG or displayed on screen..
That's all that simple :)
You may repeat steps 3 and 4 with different imgdata.params settings to get different renderings
Can you confirm the following code, for the usage of COLOR():
In image after dcraw_processed, to get the color of pixel at, e.g., (10, 3):
int row = 3;
int col = 10;
int iwidth = rawProcess.imgdata.sizes.iwidth;
int color value = rawProcess.imgdata.image[iwidth*row + col][COLOR(row, col)];
The row and col variables in image[iwidth*row + col] are the same expected in COLOR(row, col), is that correct?
To extract one channel only, there is several ways
1) extract it from raw_image: find 1-st green component (using COLOR) coordinate in (0,0)-(1,1) square and than go from pixel to pixel with +2 increment in both directions
2) do raw2image with params.half_size
It will create half-sized image[] array with all 4 components are non-zero (because each bayer 2x2 square will go into one image[] pixel)
Than use [1] plane from image
Ok, I see dcraw_make_mem_image() in documentation, that's good, I will use it.
I might need to do coaligmnent of series of images with just, say, their green component.
So I need to just extract a bitmap of just one of the three RGB components of the demosaiced image, what function do you recommend to use?
color value = image[pixel number][COLOR(row,col)], indeed, but it is not intended to use this way.
If one uses dcraw_process(), he will get image[] with interpolated colors after this call.
If one uses own processing, he hardly need 4-component image[] array.
raw2image is *compatibility layer* for some programs created to use with Libraw pre-0.15 (separate raw_image and image was introduced in version 0.15).
Thank you for these caveats. I noticed the need of using the user_black, user_cblack.
I notice the use of COLOR() is somehow same as using FC(), right? The latter is used in raw2image() apparently.
I haven't go through those functions yet. COLOR() is not documented so can you say a bit more about how to use this? I had a look in libraw.h
You wrote:
int COLOR(int row, int col) { return libraw_internal_data.internal_output_params.fuji_width? FCF(row,col):FC(row,col);}
If COLOR(row, col) gives a color value at pixel(2,2), that value must be in some color table, right? Where/how do I know which color table this COLOR() output value corresponds to?
Or did you mean, more simply, that COLOR(row,col) is meant to be used like this:
colorValue at pixel (2,2) = imgdata.image(COLOR(row,col)) ?
which would just consist in converting 2D coordinates in the 1D buffer index.
If you will use dcraw_process() for image postprocessing, you need to fix values in raw_image[] array, because dcraw_process() will call raw2image_ex(), so override any changes made in image[] array.
Also, you need to set imdata.params.user_black and user_cblack[4] to zero to prevent additional black level subtraction in dcraw_process()
Regarding a correction pipeline, would it make sense to make my own corrections on the non-demosaiced raw_image, such as subtracting my own dark image (an average "master" of dark images in fact) taken with the same camera (same parameters), and calling raw2image() on the dark-subtracted raw_image? Or should I better perform this on the imgdata.image after the raw2image() call ?
I'm soon publishing my software for which i'm trying to implement Libraw, so, again, thank you for your time.
Pixels (in raw_image) are recorded 'as in raw file'.
Colors are depending on camera CFA pattern.
The LibRaw::COLOR(row,col) call will return color for given pixel (row,col) are in image[] coordinate space i.e. visible area (so counted from top_margin,left_margin point of raw_image)
Let me take one step back on raw_image(). I see the initialization and dimensioning of raw_image, set as a one dimension array (row, or column, that's just an abstraction here):
does that go to the next row where I'd see the BGBG associated to the same pixel ? you said 4 values per pixel, as expected for Bayer image, so just checking I understand how they are set in the raw files.
raw2images arranges pixel values (from raw_image array, 1 value per pixel) to image[][4] array (4 values per pixel).
So, only one of image[N][0..3] is non-zero after raw2image, all other 3 components are still zero.
This is 'prepare for interpolation' step.
Actual interpolation (and white balance, output color profile conversion, brightness adjustment) is made by dcraw_process()
Could not understand the question
pixels 16799706 .... 16799710
are all in the same row
So, only two colors.
Again
ROWn: RGRGRGRGRGRGR
ROWn+1: GBGBGBGBGBGB
So, do you mean that, above, pixInd 16799706 is telling me that R = 2175, and that
pixInd 16799707 is giving my G2 = 2207 ?
pixInd 16799708 is B = 2134
pixInd 16799709 is G = 2161
and then these 4 values are my RGBG for one non-demosaiced single colored pixel?
Looks normal for me (after raw2image, not dcraw_process):
Each row (or column )in bayer pattern contains only two colors:
RGRGRGRG
GBGBGBGB
(really G2 in second row)
That's good.
Does dcraw_make_mem_image() also perform:
- do white balance
- than bayer interpolation
- and other possible postprocessing such as denoise or highlight recovery
as dcraw_process()?
Just to be clear:
Do i invoke dcraw_make_mem_image() INSTEAD OF dcraw_process() or AFTER dcraw_process()?
I think, I need to describe processing stages in LibRaw (simplified case, bayer image)
1) open_file() - reads metadata (EXIF and makernotes)
2) unpack() - decodes file contents into imgdata.rawdata.raw_image.
COLOR() call is useful after that: to know what color has pixel at (row,col).
3) dcraw_process():
- do raw2image() internally, allocate imgdata.image[] and populate
imgdata.image[row*width+col[COLOR(row,col)] = rawdata.raw_image[(row+top)*raw_width+col+left]
- do white balance
- than bayer interpolation
- and other possible postprocessing such as denoise or highlight recovery
- than output color conversion and data scale
After that, image[row*width+col] has [0..2] components filled with RGB values and something in [3]
4) dcraw_make_mem_image() may be used to create 3-component bitmap (with gamma correction), in 8- or 16-bit per component to be written into TIFF/JPEG or displayed on screen..
That's all that simple :)
You may repeat steps 3 and 4 with different imgdata.params settings to get different renderings
If image has dcraw_processed() (so, bayer data interpolated), you possibly do not need COLOR():
image[row*iwidth+col][0..3] will contain Red, Green, Blue in 0..2 and some garbage (not-interpolated G2 or zero) in [3]
See below instead, reply fields got too narrow...
Can you confirm the following code, for the usage of COLOR():
In image after dcraw_processed, to get the color of pixel at, e.g., (10, 3):
The
row
andcol
variables inimage[iwidth*row + col]
are the same expected inCOLOR(row, col)
, is that correct?Excellent, useful information! Thanks! Will post soon on the other forum topic the github link for the software (opensource of course)
Raphael
To extract one channel only, there is several ways
1) extract it from raw_image: find 1-st green component (using COLOR) coordinate in (0,0)-(1,1) square and than go from pixel to pixel with +2 increment in both directions
2) do raw2image with params.half_size
It will create half-sized image[] array with all 4 components are non-zero (because each bayer 2x2 square will go into one image[] pixel)
Than use [1] plane from image
Ok, I see dcraw_make_mem_image() in documentation, that's good, I will use it.
I might need to do coaligmnent of series of images with just, say, their green component.
So I need to just extract a bitmap of just one of the three RGB components of the demosaiced image, what function do you recommend to use?
This is demosaiced, white balanced, brightness adjusted, not rotated (!) image with linear gamma.
If you wish to get RGB bitmap (8 or 16 bit) with gamma applied and without extra (4th) component. use dcraw_make_mem_image() call.
After dcraw_process, image[][] contains demosaiced data? only 3-values RGB and not 4-values-RGBG, is that correct?
After dcraw_process(), if I do:
color value = image[pixel number][COLOR(row,col)] and I get... interpolated color?
Thanks
color value = image[pixel number][COLOR(row,col)], indeed, but it is not intended to use this way.
If one uses dcraw_process(), he will get image[] with interpolated colors after this call.
If one uses own processing, he hardly need 4-component image[] array.
raw2image is *compatibility layer* for some programs created to use with Libraw pre-0.15 (separate raw_image and image was introduced in version 0.15).
For bayer images, COLOR is just FC()
For fuji (SuperCCD, X-Trans) it is not
Thank you for these caveats. I noticed the need of using the user_black, user_cblack.
I notice the use of COLOR() is somehow same as using FC(), right? The latter is used in raw2image() apparently.
I haven't go through those functions yet. COLOR() is not documented so can you say a bit more about how to use this? I had a look in libraw.h
You wrote:
If COLOR(row, col) gives a color value at pixel(2,2), that value must be in some color table, right? Where/how do I know which color table this COLOR() output value corresponds to?
Or did you mean, more simply, that COLOR(row,col) is meant to be used like this:
colorValue at pixel (2,2) = imgdata.image(COLOR(row,col)) ?
which would just consist in converting 2D coordinates in the 1D buffer index.
If you will use dcraw_process() for image postprocessing, you need to fix values in raw_image[] array, because dcraw_process() will call raw2image_ex(), so override any changes made in image[] array.
Also, you need to set imdata.params.user_black and user_cblack[4] to zero to prevent additional black level subtraction in dcraw_process()
Regarding a correction pipeline, would it make sense to make my own corrections on the non-demosaiced raw_image, such as subtracting my own dark image (an average "master" of dark images in fact) taken with the same camera (same parameters), and calling raw2image() on the dark-subtracted raw_image? Or should I better perform this on the imgdata.image after the raw2image() call ?
I'm soon publishing my software for which i'm trying to implement Libraw, so, again, thank you for your time.
Pixels (in raw_image) are recorded 'as in raw file'.
Colors are depending on camera CFA pattern.
The LibRaw::COLOR(row,col) call will return color for given pixel (row,col) are in image[] coordinate space i.e. visible area (so counted from top_margin,left_margin point of raw_image)
Ok. I'm still processing your explanations:
Let me take one step back on raw_image(). I see the initialization and dimensioning of raw_image, set as a one dimension array (row, or column, that's just an abstraction here):
When i display the raw values, if I printout the raw_image[] at 4 consecutive indices,
say:
unpack(): raw_image[ i ] = 2135
unpack(): raw_image[ i+1 ] = 2091
unpack(): raw_image[ i+2 ] = 2126
unpack(): raw_image[ i+3 ] = 2174
assuming i'm in row_N, say, at the beginning of the row, are these values corresponding to RGRG?
Then if I print at
unpack(): raw_image[ i + width]
unpack(): raw_image[ i+1 + width]
unpack(): raw_image[ i+2 + width]
unpack(): raw_image[ i+3 +width]
does that go to the next row where I'd see the BGBG associated to the same pixel ? you said 4 values per pixel, as expected for Bayer image, so just checking I understand how they are set in the raw files.
Thanks
raw2images arranges pixel values (from raw_image array, 1 value per pixel) to image[][4] array (4 values per pixel).
So, only one of image[N][0..3] is non-zero after raw2image, all other 3 components are still zero.
This is 'prepare for interpolation' step.
Actual interpolation (and white balance, output color profile conversion, brightness adjustment) is made by dcraw_process()
Yes, I'm aware of how a detector is structured. I'm confused on the software side.
The RGBG is just confusing me with how they get represented in the ushort (*)[4] array.
I saw your other reply. i'm gonna do some more tests and try to understand it better, displaying Row_N and Row_N+1
Thanks.
Have you noted, that in bayer-pattern cameras (all modern, except foveon sensors) each pixel is monochrome (R _or_ G _or_ B) ?
Could not understand the question
pixels 16799706 .... 16799710
are all in the same row
So, only two colors.
Again
ROWn: RGRGRGRGRGRGR
ROWn+1: GBGBGBGBGBGB
yes, that's what I did 2 replies above with
pixInd = iwidth*row + col + i
(I iterated over i 5 times).
Please see my "in-between" reply above. It's really important that I get that cleared out.
Hmm... getting there...
raw2image(): imgdata.image[ 16799706 ][0 to 3] = | 2175 | 0 | 0 | 0
raw2image(): imgdata.image[ 16799707 ][0 to 3] = | 0 | 2207 | 0 | 0
raw2image(): imgdata.image[ 16799708 ][0 to 3] = | 2134 | 0 | 0 | 0
raw2image(): imgdata.image[ 16799709 ][0 to 3] = | 0 | 2161 | 0 | 0
raw2image(): imgdata.image[ 16799710 ][0 to 3] = | 2139 | 0 | 0 | 0
So, do you mean that, above, pixInd 16799706 is telling me that R = 2175, and that
pixInd 16799707 is giving my G2 = 2207 ?
pixInd 16799708 is B = 2134
pixInd 16799709 is G = 2161
and then these 4 values are my RGBG for one non-demosaiced single colored pixel?
Also, please note, that image[] do not contain invisible pixels.
So, raw_image[(row+top_margin)*raw_width + left_margin+col] becomes just image[row*iwidth+col]
Looks normal for me (after raw2image, not dcraw_process):
Each row (or column )in bayer pattern contains only two colors:
RGRGRGRG
GBGBGBGB
(really G2 in second row)
Pages