Skip to content

Instantly share code, notes, and snippets.

@glyg
Last active June 30, 2021 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save glyg/1ca89c3b2fe948aa8b1680aa61ec3a51 to your computer and use it in GitHub Desktop.
Save glyg/1ca89c3b2fe948aa8b1680aa61ec3a51 to your computer and use it in GitHub Desktop.
import os
import sys
from pathlib import Path
sys.path.append(r"C:\Users\endo\Documents\endo-py")
import numpy as np
import matplotlib.pyplot as plt
from skimage.filters.rank import geometric_mean
from skimage.morphology import disk
from skimage.util import img_as_ubyte, img_as_uint
from scipy.signal import convolve2d
from endoscope.hw.imagecalculator import ImageCalculator
from endoscope.hw.waveform import Waveform
import tifffile
def get_calculator(calibration_dir, imgsize=385, **kwargs):
"""Instanciates an ImageCalculator from a calibration directory"""
npys = list(Path(calibration_dir).glob("*.npy"))
# take all the calibration npys and put them in a (10, num_samples) array
xpos = np.concatenate(
[np.load(npy, allow_pickle=True)[()]["xpos"] for npy in npys]
).reshape((len(npys), -1))
ypos = np.concatenate(
[np.load(npy, allow_pickle=True)[()]["ypos"] for npy in npys]
).reshape((len(npys), -1))
calculator = ImageCalculator(imgsize=imgsize, **kwargs)
# average positions over all the calibration data
calculator.xvolts = xpos.mean(axis=0)
calculator.yvolts = ypos.mean(axis=0)
return calculator
def npy_to_tiff(npy_file, calculator, fill_radius=5, fov=120, to_csv=True, data_srce='PMT1'):
"""Uses an ImageCalculator instance to compute an image
from an npy file, and saves the result as tiff.
The `fov` value determines the registered pixel size
"""
intensity = np.load(npy_file, allow_pickle=True)[()][data_srce]
image = calculator.calc_image(intensity)
if to_csv:
csv_fname = Path(npy_file).absolute().with_suffix(".csv")
with open(csv_fname, 'w', encoding='utf-8') as csvf:
data = np.array([calculator.xv, calculator.yv, calculator._intensities]).T
header = 'xv,yv,intensity'
np.savetxt(csvf, data, delimiter=',',header=header)
# find the non-empty pixels
mask = (calculator.image >= calculator._intensities.min()).astype(bool)
# put the signal of the empty pixels to the min of the image
im_min = calculator.image[mask.nonzero()].min()
calculator._image[(~mask).nonzero()] += im_min
# convert to uint8
im = img_as_uint((calculator._image - im_min) / (calculator._image.max() - im_min))
# take the local mean for empty pixels
filled = geometric_mean(im, disk(fill_radius), mask=mask)
# replace empty pixels with their local mean
corrected = np.where(mask, im, filled)
# corrected = image
pix_size = fov / corrected.shape[0]
tiff_fname = Path(npy_file).absolute().with_suffix(".ome.tif")
tifffile.imsave(
tiff_fname,
corrected,
ome=True,
metadata={"axes": "YX", "PhysicalSizeX": pix_size, "PhysicalSizeY": pix_size},
)
print(f"saved {tiff_fname}")
return corrected
def convert_all_to_tiff(
npy_dir,
calibration_dir,
imgsize=200,
fill_radius=2,
fov=120,
to_csv=True,
data_srce="PMT1"
):
"""converts all the npy files in the npy_dir directory to tiff, using
calibration data from calibration_dir
"""
calculator = get_calculator(calibration_dir, imgsize=imgsize)
for npy_file in npy_dir.glob("*.npy"):
npy_to_tiff(
npy_file,
calculator,
fill_radius=fill_radius,
fov=fov,
to_csv=to_csv,
data_srce=data_srce
)
def plot_single(data_path, calib_path, index):
start = 0
stop = 100_000 + start
#slc = slice(start, stop)
slc = slice(None, None)
calculator = get_calculator(calib_path, imgsize=200) # , timeslice=slc)
npy_file = list(data_path.glob("*.npy"))[index]
intensity = np.load(npy_file, allow_pickle=True)[()]["PMT1"]
image = calculator.calc_image(intensity[slc])
# This plots the positions colored by intensity,
# should already look like an image
fig, ax = plt.subplots()
ax.scatter(
calculator.xv,
calculator.yv,
c=intensity[slc],
s=10)
ax.set_aspect("equal")
# get the filled image and save as tiff
corrected = npy_to_tiff(npy_file, calculator, fill_radius=2, fov=120)
fig, ax = plt.subplots()
ax.imshow(corrected)
plt.show()
calib_path= r'C:/Users/endo/EndoscopeData/Calibration/200um/10fps'
data_paths = [
Path(r"C:\Users\endo\Desktop\Imaging\200um\10fps\souris_80mW_100µm"),
Path(r"C:\Users\endo\Desktop\Imaging\200um\10fps\souris1_50mW_8fps"),
Path(r"C:\Users\endo\Desktop\Imaging\200um\10fps\Souris1_80mW_8fps_100µm"),
Path(r"C:\Users\endo\Desktop\Imaging\200um\10fps\souris1_100µm_last_100mW"),
Path(r"C:\Users\endo\Desktop\Imaging\200um\10fps\souris1_100mW_100µm"),
Path(r"C:\Users\endo\Desktop\Imaging\200um\10fps\souris2_80mW"),
]
#plot_single(data_paths[0], calib_path, 10)
for data_path in data_paths:
print(f"treating {data_path}")
convert_all_to_tiff(
data_path,
calib_path,
imgsize=200,
fill_radius=2,
fov=120
)
print(f"{data_path} done")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment