Skip to content

Commit

Permalink
Normalisation and core finding improved
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeHughesKent committed May 25, 2023
1 parent 80d98ab commit f8ec229
Show file tree
Hide file tree
Showing 6 changed files with 336 additions and 183 deletions.
4 changes: 2 additions & 2 deletions docs/source/pybundle_class.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ for a detailed description of each option's meaning.
* coreMethod = None (``set_core_method``)
* outputType = 'float64' (``set_output_type``)

**CROP/MASK Settings (for FILTER/EDGE_FILTER only):**
**CROP/MASK Settings:**

* applyMask = False (``set_apply_mask``)
* autoMask = True (``set_auto_mask``)
* autoLoc = False (``set_auto_loc``)
* crop = False(``set_crop``)
* loc = None (``set_loc``)
* mask = None (``set_mask``)

* radius = None (``set_radius``)

**CALIB/BACKGROUND/NORMALISATION Settings:**

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "PyFibreBundle"
version = "1.3.1"
version = "1.3.2"
description = "Image processing of images acquired through fibre imaging bundle, including core removal, mosaicing and super-resolution.."
readme = "README.md"
authors = [{ name = "Michael Hughes", email = "m.r.hughes@kent.ac.uk" }]
Expand Down
61 changes: 44 additions & 17 deletions src/pybundle/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,9 @@ def find_bundle(img, **kwargs):


def crop_rect(img, loc):
"""Extracts a square around the bundle using specified co-ordinates.
"""Extracts a square around the bundle using specified co-ordinates. If the
rectange is larger than the image then the returned image will be a rectangle,
limited by the extent of the image.
Returns tuple of (cropped image as 2D numpy array, new location tuple)
Expand All @@ -269,16 +271,27 @@ def crop_rect(img, loc):
loc : location to crop, specified as bundle location tuple of
(centreX, centreY, radius)
"""

cx,cy, rad = loc
imgCrop = img[cy-rad:cy+ rad, cx-rad:cx+rad]

# Correct the co-ordinates of the bundle so that they
# are correct for new cropped image
newLoc = [rad,rad,loc[2]]

return imgCrop, newLoc

if loc is not None:

h,w = np.shape(img)[:2]
cx,cy, rad = loc

minX = np.clip(cx-rad, 0, None)
maxX = np.clip(cx+rad, None, w)


minY = np.clip(cy-rad, 0, None)
maxY = np.clip(cy+rad, None, h)

imgCrop = img[minY:maxY, minX: maxX]

# Correct the co-ordinates of the bundle so that they
# are correct for new cropped image
newLoc = [rad,rad,loc[2]]

return imgCrop, newLoc
else:
return img, None



Expand Down Expand Up @@ -314,14 +327,17 @@ def apply_mask(img, mask):
with areas to be kept as 1 and areas to be masked as 0.
"""

if img.ndim == 3:
m = np.expand_dims(mask, 2)
if mask is not None:
if img.ndim == 3:
m = np.expand_dims(mask, 2)
else:
m = mask
imgMasked = np.multiply(img, m)

return imgMasked
else:
m = mask
imgMasked = np.multiply(img, m)
return img

return imgMasked


def auto_mask(img, loc = None, **kwargs):
""" Locates bundle and sets pixels outside to 0 .
Expand All @@ -332,13 +348,24 @@ def auto_mask(img, loc = None, **kwargs):
Keyword Arguments:
loc : optional location of bundle as tuple of (centreX, centreY, radius),
defaults to determining this using find_bundle
radius : optional, int, radius of mask to use rather than the automatically
determined radius
Others : if loc is not specified, other optional keyword arguments will
be passed to find_bundle.
"""
radius = kwargs.get('radius', None)

# If location not specified, find it
if loc is None:
loc = pybundle.find_bundle(img, **kwargs)

# If radius was specified, replace auto determined radius
if radius is not None:
loc = (loc[0], loc[1], radius)

# Mask image
mask = pybundle.get_mask(img, loc)
imgMasked = pybundle.apply_mask(img, mask)

Expand Down
38 changes: 24 additions & 14 deletions src/pybundle/core_interpolation.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
import math
import time


import matplotlib.pyplot as plt

import cv2 as cv

from scipy.spatial import Delaunay
Expand Down Expand Up @@ -53,15 +56,18 @@ def find_cores(img, coreSpacing):
# If a colour image, convert to greyscale by taking the maximum value across the channels
imgF = pybundle.max_channels(imgF)

imgF = (imgF / np.max(imgF) * 255).astype('uint8')
imgF = (imgF / np.max(imgF) * 255).astype('uint8')

# Find regional maximum by taking difference between dilated and original
# image. Because of the way dilation works, the local maxima are not changed
# and so these will have a value of 0
kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (coreSpacing,coreSpacing))
kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (int(round(coreSpacing)),int(round(coreSpacing)) ))
kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (3,3 ))

imgD = cv.dilate(imgF, kernel)

imgMax = 255 - (imgF - imgD) # we need to invert the image

# Just keep the maxima
thres, imgBinary = cv.threshold(imgMax, 0,1,cv.THRESH_BINARY+cv.THRESH_OTSU)

Expand Down Expand Up @@ -117,9 +123,10 @@ def core_values(img, coreX, coreY, filterSize, **kwargs):

if filterSize is not None:
img = pybundle.g_filter(img, filterSize)

if numba and numbaAvailable:
cInt = core_value_extract_numba(img, coreX, coreY)

cInt = np.zeros(np.shape(coreX))
if numba and numbaAvailable:
cInt = cInt + core_value_extract_numba(img, coreX, coreY)
else:
cInt = img[coreY, coreX]

Expand Down Expand Up @@ -156,29 +163,31 @@ def calib_tri_interp(img, coreSize, gridSize, **kwargs):
spurious core detections outside of bundle, defualts to True
mask : optional, boolean, when reconstructing output image will be masked outside of
bundle, defaults to True
"""

centreX = kwargs.get('centreX', -1)
centreY = kwargs.get('centreY', -1)
radius = kwargs.get('radius', -1)
centreX = kwargs.get('centreX', None)
centreY = kwargs.get('centreY', None)
radius = kwargs.get('radius', None)
filterSize = kwargs.get('filterSize', 0)
normalise = kwargs.get('normalise', None)
autoMask = kwargs.get('autoMask', True)
mask = kwargs.get('mask', True)
background = kwargs.get('background', None)

if autoMask:
img = pybundle.auto_mask(img)
img = pybundle.auto_mask(img, radius = radius)
# Find the cores in the calibration image
coreX, coreY = pybundle.find_cores(img, coreSize)
coreX = np.round(coreX).astype('uint16')
coreY = np.round(coreY).astype('uint16')

# Default values
if centreX < 0:
if centreX is None:
centreX = np.mean(coreX)
if centreY < 0:
if centreY is None:
centreY = np.mean(coreY)
if radius < 0:
if radius is None:
dist = np.sqrt((coreX - centreX)**2 + (coreY - centreY)**2)
radius = max(dist)

Expand Down Expand Up @@ -385,9 +394,10 @@ def recon_tri_interp(img, calib, **kwargs):
numba = kwargs.get('numba', True)

# Extract intensity from each core
t1 = time.perf_counter()
cVals = pybundle.core_values(
img, calib.coreX, calib.coreY, calib.filterSize, **kwargs).astype('float64')

if calib.background is not None:
cVals = cVals - calib.backgroundVals

Expand Down
Loading

0 comments on commit f8ec229

Please sign in to comment.