write_path / write_image.pyon commit add dlw module; clean up for handover (d7cac70)
   1"""
   2write_image.py
   3Andrew Lorimer, January 2025
   4Monash University
   5
   6Converts a path in a monochrome image to a series of points 
   7in a defined format for laser writing with the confocal 
   8setup. Configuration is done in write_image.ini. This version
   9for use with write_path.py (Python).
  10"""
  11
  12import configparser as cp
  13import cv2
  14import numpy as np
  15import sys
  16import matplotlib.pyplot as plt
  17import write_path
  18from pipython import datarectools, pitools
  19import nidaqmx
  20import pipython
  21import time
  22
  23DEFAULTS = {'dimensions': '100, 100',
  24            'z': '0',
  25            'n_levels': '10',
  26            'pitch': 1,
  27            'black_exposure': '1'}
  28DEFAULT_CONFIG_PATH = "write_image.ini"
  29
  30if __name__ == "__main__":
  31    
  32    # Get config file path from arguments or use default path
  33    if len(sys.argv) > 1 and sys.argv[1]:
  34        config_path = sys.argv[1]
  35    else:
  36        config_path = DEFAULT_CONFIG_PATH
  37
  38    # Set up config parser
  39    config = cp.ConfigParser()
  40    config['DEFAULT'] = DEFAULTS
  41    config.read_file(open(config_path))
  42
  43    # Set config values
  44    real_dim = np.fromstring(config.get('Main', 'dimensions'), dtype=float, sep=",")
  45    z = config.getfloat('Main', 'z')
  46    n_levels = int(config.getfloat('Main', 'n_levels'))
  47    pitch = config.getfloat('Main', 'pitch')
  48    black_exposure = config.getfloat('Main', 'black_exposure')
  49    input_path = config.get('Main', 'input')
  50
  51    # Read image
  52    im = cv2.imread(input_path, cv2.IMREAD_GRAYSCALE)
  53    im_dim = im.shape
  54
  55    # Check if aspect ratios match
  56    if (im_dim[0] / im_dim[1] != real_dim[0]/real_dim[1]):
  57        print("Warning: input and output aspect ratios do not match - result will be distorted")
  58
  59    # Convert image to defined number of levels
  60    im = im // (255/n_levels)
  61
  62    # Upsample/downsample image for the writing resolution
  63    n_points = real_dim / pitch
  64    n_points = n_points.astype(int)
  65    im = cv2.resize(im, (int(n_points[0]), int(n_points[1])), interpolation=cv2.INTER_CUBIC)
  66
  67    # Expand dynamic range
  68    im = (im - im.min()) * 255/(im.max()-im.min())
  69    # Display image
  70    fig, ax = plt.subplots()
  71    ax.imshow(im, cmap='gray')
  72    plt.show()
  73
  74    print("Min: {}, Max: {}".format(im.min(), im.max()))
  75
  76    min_exposure = 0.1
  77    #exposure_times = (100**((n_levels - im)/n_levels) - (1 - min_exposure)) * black_exposure / (100 - (1 - min_exposure))
  78    p = 1
  79    #exposure_times = (black_exposure / min_exposure)**(((n_levels - im)/n_levels)**p) * min_exposure
  80    exposure_times = -(black_exposure - min_exposure)/n_levels * im + black_exposure
  81    fig, ax = plt.subplots()
  82    ax.imshow(exposure_times, cmap='gray')
  83    plt.show()
  84
  85    print("Min: {}, Max: {}".format(exposure_times.min(), exposure_times.max()))
  86
  87    cont = input("Write image? (y/n): ")
  88
  89    if cont.lower() != 'y':
  90        sys.exit()
  91
  92    print("Writing image")
  93
  94    task, pidevice = write_path.setup()
  95
  96    start_x = 0
  97    start_y = 3
  98    pidevice.MOV({1: start_x, 2: start_y, 3: z})
  99    
 100
 101    try:
 102        for i in range(34, n_points[0]):
 103            for j in range(n_points[1]):
 104                pidevice.MOV({1: i*pitch+start_x, 2: j*pitch+start_y})
 105                pitools.waitontarget(pidevice, [1, 2])
 106                time.sleep(0.1)
 107                exposure_time = exposure_times[i, j]
 108                print(exposure_time)
 109                if exposure_time >= min_exposure:
 110                    task.write(True)
 111                    time.sleep(exposure_time)
 112                    task.write(False)
 113                    time.sleep(0.1)
 114    finally:
 115        print("Exiting")
 116        pidevice.MOV({1: start_x, 2: start_y, 3: z})
 117        pitools.waitontarget(pidevice, [1, 2])
 118        pitools.stopall(pidevice)
 119        task.write(False)
 120        task.close()
 121
 122