Examples
Simple
Easy to use function to run all the process at once
"""
Using the utility class Emva1288, process a descriptor file
print results and plot graphics
"""
import os
from emva1288.process import Emva1288
from emva1288.camera.dataset_generator import DatasetGenerator
# dir_ = '/home/work/1288/datasets/'
# fname = 'EMVA1288_ReferenceSet_001_CCD_12Bit/EMVA1288_Data.txt'
# fname = os.path.join(dir_, fname)
dataset_generator = DatasetGenerator(width=100,
height=50,
bit_depth=8,
dark_current_ref=30)
fname = dataset_generator.descriptor_path
e = Emva1288(fname)
e.results()
e.plot()
Camera simulator
Use the camera simulator to capture images
import numpy as np
from emva1288.camera import Camera
c = Camera()
radiances = np.linspace(0, c.get_radiance_for(mean=200), num=20)
for radiance in radiances:
img = c.grab(radiance)
print(img.mean(), img.std())
Report
Generate a report
import emva1288
from emva1288 import process
from emva1288 import report
import os
def main(dataset_descripton_file,
gain,
black_level,
bit_depth,
steps
):
# Load the dataset
parser = process.ParseEmvaDescriptorFile(dataset_descripton_file)
imgs = process.LoadImageData(parser.images)
dat = process.Data1288(imgs.data)
# Description of the setup
setup = report.info_setup()
setup['Standard version'] = emva1288.__standard_version__
# Basic information
basic = report.info_basic()
basic['vendor'] = 'Simulation'
basic['data_type'] = 'Single'
basic['sensor_type'] = 'simulated sensor'
basic['resolution'] = f'{dat.cols}x{dat.rows}'
basic['model'] = 'Simulated camera'
# Marketing information
marketing = report.info_marketing()
marketing['watermark'] = 'Example'
# Initialize the report with the marketing data
# Provide a non existent name for the output directory
myreport = report.Report1288('myreport',
marketing=marketing,
setup=setup,
basic=basic)
# Operation point
# bit_depth, gain, black_level, exposure_time, wavelength,
# temperature, housing_temperature, fpn_correction,
# summary_only
op1 = report.info_op()
op1['summary_only'] = False
op1['camera_settings']['Gain'] = gain
op1['camera_settings']['Black level'] = black_level
op1['camera_settings']['Bit depth'] = f'{bit_depth} bits'
op1['test_parameters']['Illumination'] = 'Variable with constant exposure time'
op1['test_parameters']['Irradiation steps'] = steps
# Add the operation point to the report
# we can add as many operation points as we want
# we pass the emva1288.Data1288 object to extract automatically all the results
# and graphics
myreport.add(op1, dat.data)
# Generate the latex files
myreport.latex()
if __name__ == '__main__':
# Arguments used for dataset generation and report configuration
gain = 0.1
black_level = 29.4
bit_depth = 12
steps = 50
# # Alternative 1: Load one test to add it as operation point
# dir_ = '/path/to/emva1288/datasets/'
# fname = 'EMVA1288_ReferenceSet_003_Simulation_12Bit/EMVA1288_Data.txt'
# fname = os.path.join(dir_, fname)
# Alternative 2: Generate a new test dataset
from emva1288.camera.dataset_generator import DatasetGenerator
dataset_generator = DatasetGenerator(width=640,
height=480,
K=gain,
blackoffset=black_level,
bit_depth=bit_depth,
steps=steps,
exposure_fixed=1000000,
dark_current_ref=30)
fname = dataset_generator.descriptor_path
main(dataset_descripton_file=fname,
gain=gain,
black_level=black_level,
bit_depth=bit_depth,
steps=steps)
Module by module
EMVA1288 process calling all the modules
"""
Calling one by one the classes that compose the reference implementation
process a descriptor file, print the results and plot the graphics
"""
from emva1288 import process
from emva1288.camera.dataset_generator import DatasetGenerator
# dir_ = '/home/work/1288/datasets/'
# fname = 'EMVA1288_ReferenceSet_003_Simulation_12Bit/EMVA1288_Data.txt'
dataset_generator = DatasetGenerator(width=100, height=50, bit_depth=8,
dark_current_ref=30)
# Parse the descriptor file
# parser = process.ParseEmvaDescriptorFile(os.path.join(dir_, fname))
parser = process.ParseEmvaDescriptorFile(dataset_generator.descriptor_path)
# Load images
imgs = process.LoadImageData(parser.images)
# Extract data from images
dat = process.Data1288(imgs.data)
# Compute the results
res = process.Results1288(dat.data)
res.print_results()
# Plot the graphics
plot = process.Plotting1288(res)
plot.plot()
Full capture simulation
Simulate the capture as it would be done in the lab.
import numpy as np
from emva1288.camera import Camera
from emva1288.process.routines import get_int_imgs
from emva1288 import process
def get_emva_blackoffset(cam):
"""Find the blackoffset to satifsfy EMVA1288 requirements"""
bini = cam.blackoffset
# Find black offset with a maximum of 0.5% of values at Zero
bo = cam.blackoffsets[0]
pixels = cam.width * cam.height
for i in cam.blackoffsets:
cam.blackoffset = i
img = cam.grab(0)
bo = i
if np.count_nonzero(img) > pixels * .995:
break
cam.blackoffset = bini
return bo
def get_emva_gain(cam):
"""Find the gain to satisfy EMVA1288 requirements"""
gini = cam.K
# Find gain with a minum temporal noise of 0.5DN
g = cam.Ks[0]
for gain in cam.Ks:
cam.K = gain
g = gain
img1 = cam.grab(0).astype(np.int64)
img2 = cam.grab(0).astype(np.int64)
if (img1 - img2).std() > 0.5:
break
cam.K = gini
return g
def get_temporal(cam, radiance):
img1 = cam.grab(radiance)
img2 = cam.grab(radiance)
imgs = get_int_imgs((img1, img2))
return {'sum': np.sum(imgs['sum']), 'pvar': np.sum(imgs['pvar'])}
def get_spatial(cam, radiance, L=50):
imgs = []
for i in range(L):
imgs.append(cam.grab(radiance))
return get_int_imgs(imgs)
data = {'temporal': {},
'spatial': {},
'width': None, 'height': None}
# Intialize the camera, here we can specify different image size
# or any other parameter that Camera allows
c = Camera(bit_depth=10,
width=100,
height=50)
# Fill the information
data['width'] = c.width
data['height'] = c.height
# Maximum exposure for test
exposure_max = 9000000
# Find the camera parameters for the test
c.exposure = exposure_max
c.blackoffset = get_emva_blackoffset(c)
c.K = get_emva_gain(c)
# Find the radiance that will saturate the camera at our maximum exposure time
saturation_radiance = c.get_radiance_for()
# Initialize the exposure for the spatial measure
exposure_spatial = None
# Loop through the exposures
for exposure in np.linspace(c.exposure_min, exposure_max, 100):
c.exposure = exposure
data['temporal'][exposure] = {}
# For each exposure, take to measurements (bright, dark)
for radiance in (saturation_radiance, 0.0):
photons = c.get_photons(radiance)
# Get the temporal data
data['temporal'][exposure].setdefault(photons, {})
data['temporal'][exposure][photons] = get_temporal(c, radiance)
# Check if we are at the middle of the range, to set the spatial exp
img = c.grab(radiance)
if not exposure_spatial and (img.mean() > c.img_max / 2.):
exposure_spatial = exposure
# Get the spatial data
if exposure_spatial == exposure:
data['spatial'].setdefault(exposure, {})
data['spatial'][exposure].setdefault(photons, {})
data['spatial'][exposure][photons] = get_spatial(c, radiance)
# Process the collected data
dat = process.Data1288(data)
res = process.Results1288(dat.data, pixel_area=c.pixel_area)
res.print_results()
plot = process.Plotting1288(res)
plot.plot()
Custom plot
Add custom image to the generated plots
# This example shows how to extend/modify the plots generated
from emva1288.process import Emva1288
from emva1288.camera.dataset_generator import DatasetGenerator
from emva1288.process.plotting import Emva1288Plot, EVMA1288plots
# Create a plot
class PRNUImage(Emva1288Plot):
name = 'PRNU Image'
def plot(self, test):
self.ax.imshow(test.spatial['avg'],
aspect='auto',
gid='%d:data' % test.id)
# Get a results object
dataset_generator = DatasetGenerator(width=100,
height=50,
bit_depth=8,
dark_current_ref=30)
fname = dataset_generator.descriptor_path
e = Emva1288(fname)
######
# To plot only the PRNUImage
e.plot(PRNUImage)
#####
# To plot all plus PRNUImage
plots = EVMA1288plots + [PRNUImage]
e.plot(*plots)
Results exchange file generation
Create a results xml file for comparison
import os
from emva1288 import process
# specify the path to the image stack
dir_ = '/home/work/1288/datasets/EMVA1288_ReferenceSet_001_CCD_12Bit/'
fname = 'EMVA1288_Data.txt'
fname = os.path.join(dir_, fname)
fresult = 'EMVA1288_Result.xml'
fresult = os.path.join(dir_, fresult)
parser = process.ParseEmvaDescriptorFile(os.path.join(dir_, fname))
imgs = process.LoadImageData(parser.images)
dat = process.Data1288(imgs.data)
res = process.Results1288(dat.data)
res.print_results()
f = open(os.path.join(dir_, fresult), "wb")
f.write(res.xml())
f.close()
Results comparison
Compare two result files
import os
from emva1288 import process
# specify the path to the files to compare
dir_ = '/home/work/1288/datasets/EMVA1288_ReferenceSet_001_CCD_12Bit/'
fresult1 = 'EMVA1288_Result1.xml'
fresult2 = 'EMVA1288_Result2.xml'
fcompare = 'EMVA1288_Compare.txt'
u = process.routines.compare_xml(os.path.join(dir_, fresult1),
os.path.join(dir_, fresult2),
os.path.join(dir_, fcompare))
print(u)
Structure of the image data
ipython