Raw image processing with rawpy

1.3k views Asked by At

I have raw image data (NEF-files) that I'm trying to process with rawpy.

My current workflow is as follows:

  1. Bad Pixel fix
  2. Calculation of white balance and brightness with a ColorChecker
  3. Definition of rawpy Parameters
  4. Postprocessing image with rawpy.postprocess(options)
  5. Saving rgb-array as tiff-file

See the code below for more details:

# bad pixel fix
raw_original = rawpy.imread('raw_image.NEF')
bad_pixels = enhance.find_bad_pixels(['raw_image.NEF'], find_hot=False)
enhance.repair_bad_pixels(raw_original, bad_pixels)
raw_repaired = raw_original


# calculation of white-balance and brightness with ColorChecker
def quick_raw(path):
    with rawpy.imread(path) as raw:
        opts = rawpy.Params(output_color=rawpy.ColorSpace.raw, four_color_rgb=True, no_auto_bright=True, 
                            user_wb=[1.0, 1.0, 1.0, 1.0], gamma=(1, 1), output_bps=8, bright=1)
        rgb_base = raw.postprocess(opts)
        raw.close()
    # mapping intensity   
    map_i = np.mean(rgb_base, axis=2).astype(float) / (2 ** 8 - 1)
    # detection of white patch of ColorChecker with thresholding
    map_i[np.logical_or(map_i <= 0.25, map_i >= 0.8)] = float('nan')
    mp_coo = np.where(~np.isnan(map_i))
    quick_rgb = rgb_base[mp_coo[0], mp_coo[1]].copy()
            
    # white balance - ratio
    avgR = np.mean(quick_rgb[..., 0])
    avgG = np.mean(quick_rgb[..., 1])
    avgB = np.mean(quick_rgb[..., 2])
    
    a = avgG / avgR
    b = avgG / avgB
    wb_mult = [a, 1, b, 1]
    
    B = 200 / avgG
    
    return wb_mult, B

wb, b = quick_raw('ColorChecker.NEF')


# defining rawpy options
opts = rawpy.Params(output_color=rawpy.ColorSpace.raw, four_color_rgb=True, no_auto_bright=True, 
                    user_wb=list(wb), gamma=(1, 1), output_bps=16, bright=b)
# postprocessing image with options
rgb = raw_repaired.postprocess(opts)
# save image as .tiff-file
cv2.imwrite('raw_image.tiff', rgb[..., ::-1])

raw_repaired.close()

To validate the process I use the same ColorChecker.NEF-file for white balance correction and as processed image. If I am correct, I should receive an image which is similar to the thumbnail I receive from Windows when opening a NEF-file. Additionaly I should receive rgb-values of (243, 243, 242) for the white patch of the ColorChecker (see https://en.wikipedia.org/wiki/ColorChecker).

Below you can see the results of my validation:

Processed tiff-image

Thumbnail of NEF-image

There's an unwanted difference between those two images and I receive (255, 255, 255) as rgb-values for the white patch which indicates that my validation basically fails.

Is there anything I'm missing in my workflow or do I perform raw image-processing in a wrong way?

Do I validate my workflow correctly? Any help is highly appreciated!

1

There are 1 answers

0
user22482365 On

The .tiff you are creating is a linear tiff. It does not have a gamma curve applied to the image data. However, the thumbnail of the raw has one - it is jpg-encoded. That causes the difference you noticed.