Skip to content

Instantly share code, notes, and snippets.

@Entropy512
Created April 30, 2024 15:00
Show Gist options
  • Save Entropy512/5c82cb57408ac70ba263a3a0cb410b43 to your computer and use it in GitHub Desktop.
Save Entropy512/5c82cb57408ac70ba263a3a0cb410b43 to your computer and use it in GitHub Desktop.
Plot film density digitized with WebPlotDigitizer
#!/usr/bin/env python3
'''
Converts a CSV file exported by WebPlotDigitizer ( https://apps.automeris.io/wpd/ ) to a dcamprof camera SSF JSON
For the time being, the column headers need fixing - Replace the empty entry to the right of Blue in the first row with Blue, etc.
'''
import argparse
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import json
import os
ap = argparse.ArgumentParser()
ap.add_argument('-i', '--input', type=argparse.FileType('rb'), required=True,
help='path to input files')
args = vars(ap.parse_args())
pd.options.mode.copy_on_write = True
density_data = pd.read_csv(args['input'], header=[0,1])
'''
WebPlotDigitizer exports in the order you added points, and has individual X values for each dataset instead of a single X column that is suitable for indexing,
so let's do some re-sorting.
'''
datasets = {}
for color in ['Red', 'Green', 'Blue']:
cdata = density_data[color]
cdata.rename(columns={'Y' : color}, inplace=True)
cdata.set_index('X', inplace=True, drop=True)
cdata = cdata[cdata.index.notnull()]
datasets[color] = cdata
density_data = pd.concat(datasets.values()).sort_index()
# https://stackoverflow.com/questions/35855772/pandas-merge-duplicate-index-into-single-index
density_data = density_data.groupby(density_data.index).sum(min_count=1)
# https://stackoverflow.com/questions/41493282/in-python-pandas-how-can-i-re-sample-and-interpolate-a-dataframe
dstep = 0.1
exposure_vals = np.arange(-4.0,1.0 + dstep, dstep)
density_data = density_data.reindex(density_data.index.union(exposure_vals))
# https://stackoverflow.com/questions/68548971/linearly-extrapolate-pandas-dataframe-using-built-in-interpolate-method
density_data.interpolate(method='slinear', fill_value="extrapolate", limit_direction="both", inplace=True)
density_data = density_data.loc[exposure_vals]
density_data['Red'] -= density_data['Red'].min()
density_data['Green'] -= density_data['Green'].min()
density_data['Blue'] -= density_data['Blue'].min()
plt.plot(density_data['Red'], color='r')
plt.plot(density_data['Green'], color='g')
plt.plot(density_data['Blue'], color='b')
plt.figure()
plt.plot(np.power(10.0,-density_data['Red']), color='r')
plt.plot(np.power(10.0,-density_data['Green']), color='g')
plt.plot(np.power(10.0,-density_data['Blue']), color='b')
plt.figure()
plt.plot(np.power(10,density_data.index),np.power(10.0,-density_data['Red']), color='r')
plt.plot(np.power(10,density_data.index),np.power(10.0,-density_data['Green']), color='g')
plt.plot(np.power(10,density_data.index),np.power(10.0,-density_data['Blue']), color='b')
plt.figure()
plt.semilogx(np.power(10.0,-density_data['Red']), np.log2(np.power(10,density_data.index)), color='r', label='Film Red')
plt.semilogx(np.power(10.0,-density_data['Green']), np.log2(np.power(10,density_data.index)), color='g', label='Film Green')
plt.semilogx(np.power(10.0,-density_data['Blue']), np.log2(np.power(10,density_data.index)), color='b', label='Film Blue')
density_vals = np.linspace(0,2.5,2000)
tcoeff_vals = np.power(10,-density_vals)
plt.semilogx(tcoeff_vals, np.log2(np.power(tcoeff_vals, -1.5)/np.power(10,2.8)), label='Simple Exponent (exp = -1.5)')
plt.xlabel('Normalized Transmission Coefficient (Orange Mask = 1.0)')
plt.ylabel('Scene Light (EV)')
plt.title('Scene Light vs. Film Transmission Coefficient for Fuji Superia Xtra 400')
plt.legend()
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment