Logo elodees  elodees

A caring AI for a better world













Only alphabetic characters accented or not as well as the space are accepted

Logo IA




Raw image processing





No account yet ?

Sign up to access all content




Tested in Anaconda and Python 3.7

from matplotlib import pyplot as plt
import numpy as np
import imageio
import exifread
import rawpy
 
file_path = "nikond7000_iso100/nikond7000_iso100.NEF"
 
"""
https://www.techtalk7.com/raw-image-processing-with-rawpy/
"""
# calculation of white-balance and brightness with ColorChecker
def wb_raw(file_path):
    with rawpy.imread(file_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 = wb_raw(file_path)
 
print("wb", wb)
print("b", b)
print()
 
"""
Exemples : wb = (0,0,0,0) b = 100
"""
 
def postProcessing(file_path, save, wb, b):
    with rawpy.imread(file_path) as raw:
        rgb = raw.postprocess(  
                                # demosaic_algorithm = rawpy.DemosaicAlgorithm.AHD,
                                # half_size = False,
                                # four_color_rgb = False,
                                # use_camera_wb = False,
                                # use_auto_wb = False,
                                  user_wb = list(wb),
                                # output_color = rawpy.ColorSpace.raw,
                                # output_bps = 16,user_flip=None,
                                # user_black = None,
                                # user_sat = None,
                                # no_auto_bright = False,
                                # auto_bright_thr = 0.01,
                                # adjust_maximum_thr = 0,
                                  bright = b,
                                # highlight_mode = rawpy.HighlightMode.Ignore,
                                # exp_shift = None,
                                # exp_preserve_highlights = 0.0,
                                # no_auto_scale = True,
                                # gamma = (2.222, 4.5),
                                # chromatic_aberration = None,
                                # bad_pixels_path = None
                           )
 
        print(f'raw type:                     {raw.raw_type}')                      # raw type (flat or stack, e.g., Foveon sensor)
        print(f'number of colors:             {raw.num_colors}')                    # number of different color components, e.g., 3 for common RGB Bayer sensors with two green identical green sensors 
        print(f'color description:            {raw.color_desc}')                    # describes the various color components
        print(f'raw pattern:                  {raw.raw_pattern}')                   # decribes the pattern of the Bayer sensor
        print(f'black levels:                 {raw.black_level_per_channel}')       # black level correction
        print(f'white level:                  {raw.white_level}')                   # camera white level
        print(f'color matrix:                 {raw.color_matrix.tolist()}')         # camera specific color matrix, usually obtained from a list in rawpy (not from the raw file)
        print(f'XYZ to RGB conversion matrix: {raw.rgb_xyz_matrix.tolist()}')       # camera specific XYZ to camara RGB conversion matrix
        print(f'camera white balance:         {raw.camera_whitebalance}')           # the picture's white balance as determined by the camera
        print(f'daylight white balance:       {raw.daylight_whitebalance}')         # the camera's daylight white balance
        print()
 
        with open(file_path, 'rb') as f:
            tags = exifread.process_file(f)
            for key, value in tags.items():
                if key != 'JPEGThumbnail':  # do not print (uninteresting) binary thumbnail data
                    print(f'{key}: {value}')
            print()
 
        rgb_uint8 = rgb
        rgb_uint8 = rgb_uint8.astype(np.uint8)
 
        plt.imshow(rgb_uint8)
        plt.axis('off')
        plt.title('rgb (raw)')
        plt.show()
 
        bw = (0.21 * rgb[:,:,0]) + (0.72 * rgb[:,:,0]) + (0.07 * rgb[:,:,0])
 
        plt.imshow(bw, 'gray')
        plt.axis('off')
        plt.title('bw (raw)')
        plt.show()
 
        if save == 1:
            imageio.imsave('output.tiff', rgb)
 
        return rgb
 
postProcessing(file_path, 0, wb, b)
 


Nikon image




Different stages of processing a raw image



a0016-jmac_MG_0795.dng



Sensor picture

Nikon image

Subtract black levels

Nikon image

White balance

Nikon image

Mosaicing (bayer RGBG)

Nikon image

Demosaicing

Nikon image

Standard RGB

Nikon image

Gamma

Nikon image








Adjust exposure of RAW image



The Bayer Grid

Generate pixels from the photosites of a sensor

Light Vs Colors












Welcome, my name is Eric Soupet and I am the administrator of the site elodees.com. elodees.com is a state of the art of Artificial Intelligence and aims to be collaborative, you can now offer content such as articles, events, tutorials, ... so don't hesitate !

Platform images credit : Pixabay - Pixabay License | Pexels - Pexels License