Skip to content

GUI helper modules

Description

This module contains functions to calculate muscle architectural parameters based on binary segmentations by convolutional neural networks. The parameters include muscle thickness, pennation angle and fascicle length. First, input images are segmented by the CNNs. Then the predicted aponeuroses and fascicle fragments are thresholded and filtered. Fascicle fragments and aponeuroses are extrapolated and the intersections determined. This module is specifically designed for single image analysis. The architectural parameters are calculated and the results are plotted.

Functions scope

sortContours Function to sort detected contours from proximal to distal. contourEdge Function to find only the coordinates representing one edge of a contour. doCalculations Function to compute muscle architectural parameters based on convolutional neural network segmentation.

Notes

Additional information and usage examples can be found at the respective functions documentations.

contourEdge(edge, contour)

Function to find only the coordinates representing one edge of a contour.

Either the upper or lower edge of the detected contours is calculated. From the contour detected lower in the image, the upper edge is searched. From the contour detected higher in the image, the lower edge is searched.

PARAMETER DESCRIPTION
edge

String variable defining the type of edge that is searched. The variable can be either "T" (top) or "B" (bottom).

TYPE: (T, B) DEFAULT: "T"

contour

List variable containing sorted contours.

TYPE: list

RETURNS DESCRIPTION
x

Array variable containing all x-coordinates from the detected contour.

TYPE: ndarray

y

Array variable containing all y-coordinated from the detected contour.

TYPE: ndarray

Examples:

>>> contourEdge(edge="T", contour=[[[195 104]] ... [[196 104]]])
[196 197 198 199 200 ... 952 953 954 955 956 957],
[120 120 120 120 120 ... 125 125 125 125 125 125]

doCalculations(original_image, img_copy, h, w, calib_dist, spacing, model_apo, model_fasc, dictionary, filter_fasc, image_callback=None)

Function to compute muscle architectural parameters based on convolutional neural network segmentation in images.

Firstly, images are segmented by the network. Then, predictions are thresholded and filtered. The aponeuroses edges are computed and the fascicle length and pennation angle calculated. This is done by extrapolating fascicle segments above a threshold length. Then the intersection between aponeurosis edge and fascicle structures are computed. Returns none when not more than one aponeurosis contour is detected in the image.

PARAMETER DESCRIPTION
original_image
Normalized, reshaped and rescaled rayscale image to be
analysed as a numpy array. The image must
be loaded prior to model inputting, specifying a path
is not valid.

TYPE: ndarray

img_copy

A copy of the input image.

TYPE: ndarray

h

Integer variable containing the height of the input image (img).

TYPE: int

w

Integer variable containing the width of the input image (img).

TYPE: int

calib_dist

Integer variable containing the distance between the two specified point in pixel units. This value was either computed automatically or manually. Must be non-negative. If "None", the values are outputted in pixel units.

TYPE: int

spacing

Integer variable containing the known distance in milimeter between the two placed points by the user or the scaling bars present in the image. This can be 5, 10, 15 or 20 milimeter. Must be non-negative and non-zero.

TYPE: (10, 5, 15, 20) DEFAULT: 10

model_apo

Contains keras model for prediction of aponeuroses

model_fasc

Contains keras model for prediction of fascicles

dictionary

Dictionary variable containing analysis parameters. These include must include apo_threshold, apo_length_tresh, fasc_threshold, fasc_cont_threshold, min_width, max_pennation, min_pennation.

TYPE: dict

filter_fasc

If True, fascicles will be filtered so that no crossings are included. This may reduce number of totally detected fascicles.

TYPE: bool

image_callback

Callback function to update the image display. If None, no callback is used.

DEFAULT: None

RETURNS DESCRIPTION
fasc_l

List variable contianing the estimated fascicle lengths based on the segmented fascicle fragments in pixel units as float. If calib_dist is specified, then the length is computed in centimeter.

TYPE: list

pennation

List variable containing the estimated pennation angles based on the segmented fascicle fragments and aponeuroses as float.

TYPE: list

x_low1

List variable containing the estimated x-coordinates of the lower edge from the upper aponeurosis as integers.

TYPE: list

x_high1

List variable containing the estimated x-coordinates of the upper edge from the lower aponeurosis as integers.

TYPE: list

midthick

Float variable containing the estimated distance between the lower and upper aponeurosis in pixel units. If calib_dist is specified, then the distance is computed in centimeter.

TYPE: float

fig

Figure including the input image, the segmented aponeurosis and the extrapolated fascicles.

TYPE: figure

Notes

For more detailed documentation, see the respective functions documentation.

Examples:

>>> doCalculations(img=[[[[0.10113753 0.09391343 0.09030136]
                       [0.10878626 0.10101581 0.09713058]
                       [0.10878634 0.10101589 0.09713066]
                       ...
                       [0.         0.         0.        ]
                       [0.         0.         0.        ]
                       [0.         0.         0.        ]]]],
                   img_copy=[[[[0.10113753 0.09391343 0.09030136]
                       [0.10878626 0.10101581 0.09713058]
                       [0.10878634 0.10101589 0.09713066]
                       ...
                       [0.         0.         0.        ]
                       [0.         0.         0.        ]
                       [0.         0.         0.        ]]]],
                    h=512, w=512,calib_dist=None, spacing=10,
                    filename=test1,
                    apo_modelpath="C:/Users/admin/Documents/DL_Track/Models_DL_Track/Final_models/model-VGG16-fasc-BCE-512.h5",
                    fasc_modelpath="C:/Users/admin/Documents/DL_Track/Models_DL_Track/Final_models/model-apo-VGG-BCE-512.h5",
                    scale_statement=None,
                    dictionary={'apo_treshold': '0.2', 'apo_length_tresh': '600', fasc_threshold': '0.05', 'fasc_cont_thresh': '40', 'min_width': '60', 'min_pennation': '10', 'max_pennation': '40'},
                    filter_fasc = False)
[1030.1118966321328, 1091.096002143386, ..., 1163.07073327008, 1080.0001937069776, 976.6099281240987]
[19.400700671533016, 18.30126098122986, ..., 18.505345607096586, 18.727693601171197, 22.03704574228162]
[441, 287, 656, 378, 125, 15, ..., -392, -45, -400, -149, -400]
[1410, 1320, 1551, 1351, 1149, ..., 885, 937, 705, 869, 507]
348.1328577

filter_fascicles(df)

Filters out fascicles that intersect with their neighboring fascicles based on their x_low and x_high values.

PARAMETER DESCRIPTION
df

A DataFrame containing the fascicle data. Expected columns include 'x_low', 'y_low', 'x_high', and 'y_high'.

TYPE: DataFrame

RETURNS DESCRIPTION
DataFrame

A DataFrame with the fascicles that do not intersect with their neighbors.

Examples:

>>> data = {'x_low': [1, 3, 5], 'y_low': [1, 2, 3], 'x_high': [4, 6, 7], 'y_high': [4, 5, 6]}
>>> df = pd.DataFrame(data)
>>> print(filter_fascicles(df))
   x_low  y_low  x_high  y_high
0      1      1       4       4
2      5      3       7       6

sortContours(cnts)

Function to sort detected contours from proximal to distal.

The input contours belond to the aponeuroses and are sorted based on their coordinates, from smallest to largest. Moreover, for each detected contour a bounding box is built. The bounding boxes are sorted as well. They are however not needed for further analyses.

PARAMETER DESCRIPTION
cnts

List of arrays containing the detected aponeurosis contours.

TYPE: list

RETURNS DESCRIPTION
cnts

Tuple containing arrays of sorted contours.

TYPE: tuple

bounding_boxes

Tuple containing tuples with sorted bounding boxes.

TYPE: tuple

Examples:

>>> sortContours(cnts=[array([[[928, 247]], ... [[929, 247]]],
dtype=int32),
((array([[[228,  97]], ... [[229,  97]]], dtype=int32),
(array([[[228,  97]], ... [[229,  97]]], dtype=int32),
(array([[[928, 247]], ... [[929, 247]]], dtype=int32)),
((201, 97, 747, 29), (201, 247, 750, 96))
Description

This module contains functions for three different approaches to calculate muscle architectural parameters accounted for fascicle curvature. The parameters include muscle thickness, pennation angle and fascicle length. All calculations are based on a fascicle mask and aponeurses mask. Fascicle fragments are connected and extrapolated and the intersection points with the extrapolated aponeuroses are determined. The architectural parameters are calculated and the results are plotted. Additionally, it is possible to calculate an orientation map of the fascicles based on the fascicle mask. This module is specifically designed for single image analysis.

Functions scope

curve_polyfitting Function to calculate the fascicle length and pennation angle accounted for curvature following a second order polynomial fitting approach. curve_connect Function to calculate the fascicle length and pennation angle accounted for curvature following a approach of connecting fascicles. orientation_map Function to calculate an orientation map based on the fascicle mask. doCalculations_curved Function to compute muscle architectural parameters accounted for fascicle curvature.

Notes

Additional information can be found at the respective functions documentations.

adapted_contourEdge(edge, contour)

Function to find only the coordinates representing one edge of a contour.

Either the upper or lower edge of the detected contours is calculated. From the contour detected lower in the image, the upper edge is searched. From the contour detected higher in the image, the lower edge is searched. Allows for more points around the end of the contour than contourEdge.

PARAMETER DESCRIPTION
edge

String variable defining the type of edge that is searched. The variable can be either "T" (top) or "B" (bottom).

TYPE: (T, B) DEFAULT: "T"

contour

List variable containing sorted contours.

TYPE: list

RETURNS DESCRIPTION
x

Array variable containing all x-coordinates from the detected contour.

TYPE: ndarray

y

Array variable containing all y-coordinated from the detected contour.

TYPE: ndarray

Examples:

>>> contourEdge(edge="T", contour=[[[195 104]] ... [[196 104]]])
[196 197 198 199 200 ... 952 953 954 955 956 957],
[120 120 120 120 120 ... 125 125 125 125 125 125]

adapted_filter_fascicles(df, tolerance)

Filters out fascicles that intersect with other fascicles

This function counts for each fascicle the number of intersections with other fascicles and ranks them based on the number of intersections. The fascicle with the highest intersection count is excluded. This ranking and exclusion process is repeated until there are no more intersections.

PARAMETER DESCRIPTION
df

A DataFrame containing the fascicle data. Expected columns include 'coordsXY'.

TYPE: DataFrame

tolerance

Tolerance to allow intersection points near the aponeuroses

TYPE: int

RETURNS DESCRIPTION
DataFrame

A DataFrame with the fascicles that do not intersect with other fascicles.

Example

data = {'coordsXY': [[(78, 268), (78, 266), ...], [(43, 265), (42, 264), ...], ...]} tolerance = 100 adapted_filter_fascicles(data, tolerance)

contourEdge(edge, contour)

Function to find only the coordinates representing one edge of a contour.

Either the upper or lower edge of the detected contours is calculated. From the contour detected lower in the image, the upper edge is searched. From the contour detected higher in the image, the lower edge is searched.

PARAMETER DESCRIPTION
edge

String variable defining the type of edge that is searched. The variable can be either "T" (top) or "B" (bottom).

TYPE: (T, B) DEFAULT: "T"

contour

List variable containing sorted contours.

TYPE: list

RETURNS DESCRIPTION
x

Array variable containing all x-coordinates from the detected contour.

TYPE: ndarray

y

Array variable containing all y-coordinated from the detected contour.

TYPE: ndarray

Examples:

>>> contourEdge(edge="T", contour=[[[195 104]] ... [[196 104]]])
[196 197 198 199 200 ... 952 953 954 955 956 957],
[120 120 120 120 120 ... 125 125 125 125 125 125]

crop(original_image, image_fas, image_apo)

Function to crop the frame around ultrasound images

Additionally crops the fascicle and aponeuroses images in order that all three images have the same size

PARAMETER DESCRIPTION
original_image

Image of the original ultrasound image

TYPE: list

image_fas

Binary image of the fascicles within the original image

TYPE: list

image_apo

Binary image of the aponeuroses within the original image

TYPE: list

RETURNS DESCRIPTION
cropped_US

Image of the original ultrasound image without frame around it

TYPE: list

cropped_fas

Cropped binary image of fascicles within the original image

TYPE: list

cropped_apo

Cropped binary image of the aponeuroses within the original image

TYPE: list

Examples:

>>> crop(original_image=array([[[160, 160, 160],[159, 159, 159],[158, 158, 158],...[158, 158, 158],[147, 147, 147],[  1,   1,   1]],...,[[  0,   0,   0],[  0,   0,   0],[  0,   0,   0],...,[  4,   4,   4],[  3,   3,   3],[  3,   3,   3]]], dtype=uint8), image_fas = array([[0, 0, 0, ..., 0, 0, 0],[0, 0, 0, ..., 0, 0, 0],[0, 0, 0, ..., 0, 0, 0],...,[0, 0, 0, ..., 0, 0, 0],[0, 0, 0, ..., 0, 0, 0],[0, 0, 0, ..., 0, 0, 0]], dtype=uint8), image_apo = array([[[0, 0, 0],[0, 0, 0],[0, 0, 0],...,[0, 0, 0],[0, 0, 0],[0, 0, 0]]], dtype=uint8))

curve_connect(contours_sorted, ex_x_LA, ex_y_LA, ex_x_UA, ex_y_UA, original_image, parameters, filter_fasc, approach)

Function to calculate the fascicle length and pennation angle accounted for curvature following linear connection between fascicles

This function identifies individual fascicle contours and connects them if they are likely part of the same fascicle. A second-order polynomial curve is fitted through these contours; if the curvature exceeds a specified range, a linear fit is used instead. This fit is solely for detecting the contours. curve_connect_linear: The first contour of the fascicle is extrapolated to determine its intersection point with the lower aponeurosis. curve_connect_poly: The lower aponeurosis and the first contour are connected using a second-order polynomial fit based on all detected contours. Following common path for both approaches: After the initial extrapolation, the first contour is added. A linear connection is made from the last point of the current contour to the first point of the next contour, and this next contour is added. This process continues until the final contour is reached. The final contour is then used for a linear extrapolation to determine the intersection point with the upper aponeurosis. Adding all these parts together, the function calculates the fascicle length and pennation angle.

PARAMETER DESCRIPTION
contours_sorted

List containing all (x,y)-coordinates of each detected contour

TYPE: list

ex_x_LA

List containing all x-values of the extrapolated lower aponeurosis

TYPE: list

ex_y_LA

List containing all y-values of the extrapolated lower aponeurosis

TYPE: list

ex_x_UA

List containing all x-values of the extrapolated upper aponeurosis

TYPE: list

ex_y_UA

List containing all y-values of the extrapolated upper aponeurosis

TYPE: list

original_image

Ultrasound image to be analysed

TYPE: ndarray

parameters

Dictionary variable containing analysis parameters. These include apo_length_threshold, apo_length_thresh, fasc_cont_thresh, min_width, max_pennation,min_pennation, tolerance, tolerance_to_apo, coeff_limit

TYPE: dict

filter_fasc

If True, fascicles will be filtered so that no crossings are included. This may reduce number of totally detected fascicles.

TYPE: bool

approach

Can either be curve_connect_linear or curve_connect_poly. If curve_connect_linear is used, a linear extrapolation between the lower aponeurosis and the first fascicle contour is used. If curve_connect_poly is used, a seconde order polynomial extrapolation between the lower and aponeurosis and the first fascicle contour is used; if the curvature exceeds a specified range, a linear fit is used instead.

TYPE: str

RETURNS DESCRIPTION
data

Dictionary containing the fascicle length and pennation angle for each fascicle.

TYPE: dict

Examples:

>>> curve_connect(contours_sorted=[array([ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36], dtype=int32), array([166, 166, 166, 165, 165, 165, 164, 164, 164, 163, 163, 163, 162, 162, 162, 161, 161, 161, 160, 160, 160, 159, 159, 159, 158, 158, 158, 157, 157, 157, 156, 156], dtype=int32), ...], ex_x_LA=[-256.0, -255.79515903180635, -255.59031806361273, -255.38547709541908, -255.18063612722545, -254.9757951590318, ...], ex_y_LA=[203.6459743268554, 203.64809836232556, 203.65022013210233, 203.6523396361857, ...], ex_x_UA=[-256.0, -255.79515903180635, -255.59031806361273, -255.38547709541908, -255.18063612722545, ...], ex_y_UA=[45.83649948451378, 45.829729965913046, 45.82296488688939, 45.81620424744281, 45.80944804757331, ...], original_image=array([[[160, 160, 160],[159, 159, 159],[158, 158, 158],...[158, 158, 158],[147, 147, 147],[  1,   1,   1]],...,[[  0,   0,   0],[  0,   0,   0],[  0,   0,   0],...,[  4,   4,   4],[  3,   3,   3],[  3,   3,   3]]], dtype=uint8), parameters={apo_length_thresh=600, fasc_cont_thresh=5, min_width=60, max_pennation=40,min_pennation=5, tolerance=10, tolerance_to_apo=100}, filter_fascicles=True, approach="curve_connect_linear")

curve_polyfitting(contours_sorted, ex_x_LA, ex_y_LA, ex_x_UA, ex_y_UA, original_image, parameters, filter_fasc)

Function to calculate the fascicle length and pennation angle accounted for curvature following a second order polynomial fitting approach

This function identifies individual fascicle contours and connects them if they are likely part of the same fascicle. A second-order polynomial curve is fitted through these contours; if the curvature exceeds a specified range, a linear fit is used instead. By knowing the positions of the aponeuroses, the intersection points between the fascicles and the lower and upper aponeuroses can be determined. Using these intersection points, the fascicle length and pennation angle are calculated.

Parameters

contours_sorted : list List containing all (x,y)-coordinates of each detected contour ex_x_LA : list List containing all x-values of the extrapolated lower aponeurosis ex_y_LA: list List containing all y-values of the extrapolated lower aponeurosis ex_x_UA : list List containing all x-values of the extrapolated upper aponeurosis ex_y_UA : list List containing all y-values of the extrapolated upper aponeurosis original_image : np.ndarray Ultrasound image to be analysed parameters : dict Dictionary variable containing analysis parameters. These include apo_length_threshold, apo_length_thresh, fasc_cont_thresh, min_width, max_pennation,min_pennation, tolerance, tolerance_to_apo, coeff_limit filter_fasc : bool If True, fascicles will be filtered so that no crossings are included. This may reduce number of totally detected fascicles.

Returns

fascicle_length : list List variable containing the estimated fascicle lengths based on the segmented fascicle fragments in pixel units as float. pennation_angle : list List variable containing the estimated pennation angles based on the segmented fascicle fragments and aponeuroses as float. x_low : list List variable containing the intersection points between the fascicles and the lower aponeurosis x_high : list List variable containing the intersection points between the fascicles and the upper aponeurosis fig : matplot.figure Figure including the input ultrasound image, the segmented aponeuroses and the found fascicles extrapolated between the two aponeuroses.

Examples:

>>> curve_polyfitting(contours_sorted=[array([ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36], dtype=int32), array([166, 166, 166, 165, 165, 165, 164, 164, 164, 163, 163, 163, 162, 162, 162, 161, 161, 161, 160, 160, 160, 159, 159, 159, 158, 158, 158, 157, 157, 157, 156, 156], dtype=int32), ...], ex_x_LA=[-256.0, -255.79515903180635, -255.59031806361273, -255.38547709541908, -255.18063612722545, -254.9757951590318, ...], ex_y_LA=[203.6459743268554, 203.64809836232556, 203.65022013210233, 203.6523396361857, ...], ex_x_UA=[-256.0, -255.79515903180635, -255.59031806361273, -255.38547709541908, -255.18063612722545, ...], ex_y_UA=[45.83649948451378, 45.829729965913046, 45.82296488688939, 45.81620424744281, 45.80944804757331, ...], original_image=array([[[160, 160, 160],[159, 159, 159],[158, 158, 158],...[158, 158, 158],[147, 147, 147],[  1,   1,   1]],...,[[  0,   0,   0],[  0,   0,   0],[  0,   0,   0],...,[  4,   4,   4],[  3,   3,   3],[  3,   3,   3]]], dtype=uint8), parameters={apo_length_thresh=600, fasc_cont_thresh=5, min_width=60, max_pennation=40,min_pennation=5, tolerance=10, tolerance_to_apo=100}, filter_fascicles=True)

doCalculations_curved(original_image, img_copy, h, w, model_apo, model_fasc, dic, filter_fasc, calib_dist, spacing, approach, image_callback=None)

Function to compute muscle architectural parameters accounted for fascicle curvature

The aponeuroses edges are computed and the fascicle contours are connected to form complete fascicles. Based on three different approaches the fascicle length and pennation angle get calculated. Furthermore, it is possible to calculate an orientation map showing the slope at different points in the region of interest.

Returns none when not more than one aponeurosis contour or no fascicle contours are detected in the image.

PARAMETER DESCRIPTION
original_image

Ultrasound image to be analysed

TYPE: ndarray

img_copy

A copy of the input image.

TYPE: ndarray

h

Integer variable containing the height of the input image (original image).

TYPE: int

w

Integer variable containing the width of the input image (original image).

TYPE: int

model_apo

Contains keras model for prediction of aponeuroses

model_fasc

Contains keras model for prediction of fascicles

dic

Dictionary variable containing analysis parameters. These include apo_length_threshold, apo_length_thresh, fasc_cont_thresh, min_width, max_pennation,min_pennation, tolerance, tolerance_to_apo

TYPE: dict

filter_fasc

If True, fascicles will be filtered so that no crossings are included. This may reduce number of totally detected fascicles.

TYPE: bool

calib_dist

Integer variable containing the distance between the two specified point in pixel units. This value was either computed automatically or manually. Must be non-negative. If "None", the values are outputted in pixel units.

TYPE: int

spacing

Integer variable containing the known distance in milimeter between the two placed points by the user or the scaling bars present in the image. This can be 5, 10, 15 or 20 millimeter. Must be non-negative and non-zero.

TYPE: (10, 5, 15, 20) DEFAULT: 10

approach

Can either be curve_polyfitting, curve_connect_linear, curve_connect_poly or orientation_map. curve_polyfitting calculates the fascicle length and pennation angle according to a second order polynomial fitting (see documentation of function curve_polyfitting). curve_connect_linear and curve_connect_poly calculate the fascicle length and pennation angle according to a linear connection between the fascicles fascicles (see documentation of function curve_connect). orientation_map calculates an orientation map and gives an estimate for the median angle of the image (see documentation of function orientation_map)

TYPE: str

image_callback

Callback function for displaying the image. If None, no image is displayed.

DEFAULT: None

RETURNS DESCRIPTION
fascicle_length

List variable containing the estimated fascicle lengths based on the segmented fascicle fragments in pixel units as float. If calib_dist is specified, then the length is computed in centimeter.

TYPE: list

pennation_angle

List variable containing the estimated pennation angles based on the segmented fascicle fragments and aponeuroses as float.

TYPE: list

midthick

Float variable containing the estimated distance between the lower and upper aponeurosis in pixel units. If calib_dist is specified, then the distance is computed in centimeter.

TYPE: float

x_low

List variable containing the intersection points between the fascicles and the lower aponeurosis

TYPE: list

x_high

List variable containing the intersection points between the fascicles and the upper aponeurosis

TYPE: list

fig

Figure including the input ultrasound image, the segmented aponeuroses and the found fascicles extrapolated between the two aponeuroses.

TYPE: figure

Notes

For more detailed documentation, see the respective functions documentation.

Examples:

>>> doCalculations_curved(original_image=array([[[160, 160, 160],[159, 159, 159],[158, 158, 158],...[158, 158, 158],[147, 147, 147],[  1,   1,   1]],...,[[  0,   0,   0],[  0,   0,   0],[  0,   0,   0],...,[  4,   4,   4],[  3,   3,   3],[  3,   3,   3]]], dtype=uint8), fas_image = array([[0, 0, 0, ..., 0, 0, 0],[0, 0, 0, ..., 0, 0, 0],[0, 0, 0, ..., 0, 0, 0],...,[0, 0, 0, ..., 0, 0, 0],[0, 0, 0, ..., 0, 0, 0],[0, 0, 0, ..., 0, 0, 0]], dtype=uint8), apo_image = array([[[0, 0, 0],[0, 0, 0],[0, 0, 0],...,[0, 0, 0],[0, 0, 0],[0, 0, 0]]], dtype=uint8), dic={apo_length_thresh=600, fasc_cont_thresh=5, min_width=60, max_pennation=40,min_pennation=5, tolerance=10, tolerance_to_apo=100}, filter_fascicles=True, calib_dist = None, spacing = 10, approach = "curve_polyfitting")

do_curves_intersect(curve1, curve2)

Function to detect wheter two curves are intersecting or not.

PARAMETER DESCRIPTION
curve1

List containing (x,y) coordinate pairs representing one curve

TYPE: list

curve2

List containing (x,y) coordinate pairs representing a second curve

TYPE: list

RETURNS DESCRIPTION
Bool

'True' if the curves have an intersection point 'False' if the curves don't have an intersection point

Examples:

>>> do_curves_intersect(curve1=[(98.06, 263.24), (98.26, 263.19), ...],
curve2=[(63.45, 258.82), (63.65, 258.76), ...])

find_complete_fascicle(i, contours_sorted_x, contours_sorted_y, contours_sorted, label, mid, width, tolerance, coeff_limit)

Function to find complete fascicles based on connection of single contours.

The function extrapolates a second order polynomial fit through the first contour. If the coefficients fall outside a specified range, the curve is considered too curved. As a result, a linear fit is calculated and used for subsequent calculations. The next contour is identified if its first point lies within a specified tolerance range in the positive and negative y-direction around the extrapolated fit. If this condition is met, both contours serve as the basis for the next polynomial fit. This process is repeated until no more possible connecting contours are found.

PARAMETER DESCRIPTION
i

Integer value defining the starting contour

TYPE: int

contours_sorted_x

List containing all x-coordinates of each detected contour

TYPE: list

contours_sorted_y

List containing all y-coordinates of each detected contour

TYPE: list

contours_sorted

List containing all (x,y)-coordinates of each detected contour

TYPE: list

label

Dictionnary containing a label true or false for every fascicle contour, true if already used for an extrapolation, false if not

TYPE: dictionnary

mid

Integer value defining the middle of the image

TYPE: int

width

Integer value defining the width of the image

TYPE: int

tolerance

Integer value specifing the permissible range in the positive and negative y-direction within which the next contour can be located to still be considered a part of the extrapolated fascicle

TYPE: int

coeff_limit

Value defining the maximum value of the first coefficient in the second polynomial fit

TYPE: float

RETURNS DESCRIPTION
ex_current_fascicle_x

List containing the x-coordinates of each found and extrapolated fascicle

TYPE: list

ex_current_fascicle_y

List containing the y-coordinates of each found and extrapolated fascicle

TYPE: list

linear_fit

'True' if extrapolated fit is linear 'False' if extrapolated fit follows a second order polynomial

TYPE: bool

inner_number_contours

List containing the indices of each contour that constitute each fascicle

TYPE: list

Examples:

>>> find_complete_fascicle(i=0, contours_sorted_x=[array([ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36],dtype=int32),...,array([481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497],dtype=int32)]), contours_sorted_y=[array([166, 166, 166, 165, 165, 165, 164, 164, 164, 163, 163, 163, 162, 162, 162, 161, 161, 161, 160, 160, 160, 159, 159, 159, 158, 158, 158, 157, 157, 157, 156, 156],dtype=int32),...,array([76, 76, 76, 76, 75, 75, 75, 74, 74, 74, 74, 73, 73, 73, 72, 72, 72],dtype=int32)], contours_sorted=[[array([ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36],dtype=int32),array([166, 166, 166, 165, 165, 165, 164, 164, 164, 163, 163, 163, 162, 162, 162, 161, 161, 161, 160, 160, 160, 159, 159, 159, 158, 158, 158, 157, 157, 157, 156, 156], dtype=int32),...]], label={0: False, 1: False, 2: False, 3: False, 4: False, 5: False, 6: False, 7: False, 8: False, 9: False, 10: False, 11: False, 12: False, 13: False}, mid=256.0, width=512, tolerance=10, coeff_limit=0.000583)

find_complete_fascicle_linear(i, contours_sorted_x, contours_sorted_y, contours_sorted, label, mid, width, tolerance, coeff_limit)

Traces a complete fascicle by iteratively fitting and extrapolating a linear model through connected contour segments in an ultrasound image.

Starting from a seed contour i, the function fits a line, extrapolates it over a defined width, and collects all contour segments that lie within a vertical tolerance range around the extrapolated line. The procedure continues recursively to find connected fascicle segments along the extrapolated path.

PARAMETER DESCRIPTION
i

Index of the initial contour used to start the fascicle tracing.

TYPE: int

contours_sorted_x

List of arrays containing the x-coordinates of each contour segment.

TYPE: list of ndarray

contours_sorted_y

List of arrays containing the y-coordinates of each contour segment.

TYPE: list of ndarray

contours_sorted

List of full contour arrays (used for proximity checking).

TYPE: list of ndarray

label

Dictionary mapping contour indices to a boolean indicating whether they have already been used. Will be updated in-place.

TYPE: dict

mid

Midpoint x-coordinate used as center of extrapolation range.

TYPE: int

width

Half-width of the extrapolation span in pixels (from mid - width to mid + width).

TYPE: int

tolerance

Vertical distance in pixels allowed between the extrapolated line and candidate contour segments.

TYPE: int

coeff_limit

Currently unused; placeholder for limiting slope or intercept values during fitting.

TYPE: float

RETURNS DESCRIPTION
ex_current_fascicle_x

Extrapolated x-coordinates of the complete fascicle.

TYPE: ndarray

ex_current_fascicle_y

Corresponding y-coordinates from the final linear model fit.

TYPE: ndarray

linear_fit

Flag indicating whether a linear fit was successfully computed (always True in current logic).

TYPE: bool

inner_number_contours

List of contour indices that belong to the detected fascicle.

TYPE: list of int

Notes
  • This function modifies the label dictionary in-place to prevent reprocessing contours.
  • The input coeff_limit is accepted but currently not used for filtering.

Examples:

>>> ex_x, ex_y, is_linear, used_contours = find_complete_fascicle_linear(
...     i=0,
...     contours_sorted_x=contour_x_list,
...     contours_sorted_y=contour_y_list,
...     contours_sorted=contour_list,
...     label={j: False for j in range(len(contour_x_list))},
...     mid=256,
...     width=100,
...     tolerance=5,
...     coeff_limit=0.5
... )
>>> plt.plot(ex_x, ex_y)
>>> print(f"Used {len(used_contours)} contour segments.")

find_next_fascicle(all_contours, contours_sorted_x, contours_sorted_y, x_current_fascicle, y_current_fascicle, x_range, upper_bound, lower_bound, label)

Function to find the next fascicle contour

PARAMETER DESCRIPTION
all_contours

List containing all (x,y)-coordinates of each detected contour

TYPE: list

contours_sorted_x

List containing all x-coordinates of each detected contour

TYPE: list

contours_sorted_y

List containing all y-coordinates of each detected contour

TYPE: list

x_current_fascicle

List containing the x-coordinates of the currently examined fascicle

TYPE: list

y_current_fascicle

List containing the y-coordinates of the currently examined fascicle

TYPE: list

x_range

List containing all x-coordinates within the range of the extrapolation

TYPE: list

upper_bound

List containing all y-coordinates of the lower boundary

TYPE: list

lower_bound

List containing all y-coordinates of the upper boundary

TYPE: list

label

Dictionnary containing a label true or false for every fascicle contour, true if already used for an extrapolation, false if not

TYPE: dictionnary

RETURNS DESCRIPTION
new_x

List containing the x-coordinates of the currently examined fascicle merged with the x-coordinates of the next fascicle contour within the boundary if one was found

TYPE: list

new_y

List containing the y-coordinates of the currently examined fascicle merged with the y-coordinates of the next fascicle contour within the boundary if one was found

TYPE: list

found_fascicle

Integer value of the found fascicle contour, -1 if no contour was found

TYPE: int

Examples:

>>> find_next_fascicle(all_contours = , contours_sorted_x=[array([ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36],dtype=int32),...,array([481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493,494, 495, 496, 497],dtype=int32)]), contours_sorted_y=[array([166, 166, 166, 165, 165, 165, 164, 164, 164, 163, 163, 163, 162, 162, 162, 161, 161, 161, 160, 160, 160, 159, 159, 159, 158, 158, 158, 157, 157, 157, 156, 156], dtype=int32),...,array([76, 76, 76, 76, 75, 75, 75, 74, 74, 74, 74, 73, 73, 73, 72, 72, 72],dtype=int32)], x_current_fascicle=array([ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36],dtype=int32), y_current_fascicle=array([166, 166, 166, 165, 165, 165, 164, 164, 164, 163, 163, 163, 162, 162, 162, 161, 161, 161, 160, 160, 160, 159, 159, 159, 158, 158, 158, 157, 157, 157, 156, 156], dtype=int32), x_range=array([-256.   , -255.795, -255.59 , ...,  767.59 ,  767.795,  768.   ]), upper_bound=array([243.137, 243.069, 243.001, ..., -97.372, -97.44 , -97.508]), lower_bound=array([263.137, 263.069, 263.001, ..., -77.372, -77.44 , -77.508]), label={0: True, 1: False, 2: False, 3: False, 4: False, 5: False, 6: False, 7: False, 8: False, 9: False, 10: False, 11: False, 12: False, 13: False})

is_point_in_range(x_point, y_point, x_poly, lb, ub)

Function to detect wheter a point is between an upper and a lower boundary or not.

PARAMETER DESCRIPTION
x_point

Single integer variable representing the x-coordinate of the point to be analyzed

TYPE: int

y_point

Single integer variable representing the y-coordinate of the point to be analyzed

TYPE: integer

x_poly

List containing all x-coordinates of the range where the point could be located

TYPE: list

lb

List containing all y-coordinates of the lower boundary

TYPE: list

ub

List containing all y-coordinates of the upper boundary

TYPE: list

RETURNS DESCRIPTION
Bool

'True' if point is within both boundaries 'False' if point is outside the boundaries

Examples:

>>> is_point_in_range(x_point=250, y_point=227,
x_poly=([-200, ..., 800]), lb=([303.165, ..., 130.044]),
ub=([323.165, ..., 150.044]))

orientation_map(fas_image, apo_image, g, h)

Function to calculate an orientation map based on the fascicle mask

The function calculates the orientations of fascicles based on the fascicle mask using the OrientationPy package. It then uses linear inter- and extrapolation to determine the orientation of all points in the region between the two aponeuroses using the Rbf package. Finally, the resulting vectors are smoothed with a Gaussian filter. To approximate the median angle, the image is divided into six sections: two horizontally and three vertically. The median angle is then calculated for each of these sections. In the plot only the median for the part in the lower half and middle of the image is displayed.

PARAMETER DESCRIPTION
fas_image

Mask of fascicles

TYPE: ndarray

apo_image

Mask of aponeuroses

TYPE: ndarray

g

Containing coefficients to calculate second order polynomial fit for upper aponeurosis

TYPE: poly1d

h

Containing coefficients to calculate second order polynomial fit for lower aponeurosis

TYPE: poly1d

RETURNS DESCRIPTION
split_angles_deg_median

List variable containing the estimated pennation angles for the six parts of the image

TYPE: list

fig

Figure showing the estimated slope at different points in the region between the two aponeuroses as a heat map

TYPE: figure

Examples:

>>> orientation_map(original_image=array([[[160, 160, 160],[159, 159, 159],[158, 158, 158],...[158, 158, 158],[147, 147, 147],[  1,   1,   1]],...,[[  0,   0,   0],[  0,   0,   0],[  0,   0,   0],...,[  4,   4,   4],[  3,   3,   3],[  3,   3,   3]]], dtype=uint8), fas_image = array([[0, 0, 0, ..., 0, 0, 0],[0, 0, 0, ..., 0, 0, 0],[0, 0, 0, ..., 0, 0, 0],...,[0, 0, 0, ..., 0, 0, 0],[0, 0, 0, ..., 0, 0, 0],[0, 0, 0, ..., 0, 0, 0]], dtype=uint8), apo_image = array([[[0, 0, 0],[0, 0, 0],[0, 0, 0],...,[0, 0, 0],[0, 0, 0],[0, 0, 0]]], dtype=uint8), g=poly1d([ 0.   , -0.006, 40.841]), h=poly1d([ -0.   ,  -0.003, 204.533]))

sortContours(cnts)

Function to sort detected contours from proximal to distal.

The input contours belond to the aponeuroses and are sorted based on their coordinates, from smallest to largest. Moreover, for each detected contour a bounding box is built. The bounding boxes are sorted as well. They are however not needed for further analyses.

PARAMETER DESCRIPTION
cnts

List of arrays containing the detected aponeurosis contours.

TYPE: list

RETURNS DESCRIPTION
cnts

Tuple containing arrays of sorted contours.

TYPE: tuple

bounding_boxes

Tuple containing tuples with sorted bounding boxes.

TYPE: tuple

Examples:

>>> sortContours(cnts=[array([[[928, 247]], ... [[929, 247]]],
dtype=int32),
((array([[[228,  97]], ... [[229,  97]]], dtype=int32),
(array([[[228,  97]], ... [[229,  97]]], dtype=int32),
(array([[[928, 247]], ... [[929, 247]]], dtype=int32)),
((201, 97, 747, 29), (201, 247, 750, 96))
Description

This module contains functions to caculate muscle architectural parameters based on binary segmentations by convolutional neural networks. The parameters include muscle thickness, pennation angle and fascicle length. First, input images are segmented by the CNNs. Then the predicted aponeuroses and fascicle fragments are thresholded and filtered. Fascicle fragments and aponeuroses are extrapolated and the intersections determined. This module is specifically designed for video analysis and is predisposed for execution from a tk.TK GUI instance. The architectural parameters are calculated. The results are plotted and converted to an output video displaying the segmentations. Each frame is evaluated separately, independently from the previous frames.

Functions scope

doCalculations Function to compute muscle architectural parameters based on convolutional neural netwrok segmentation.

Notes

Additional information and usage examples can be found at the respective functions documentations. See specifically do_calculations.py.

See Also

do_calculations.py

doCalculationsVideo(vid_len, cap, vid_out, flip, apo_model, fasc_model, calib_dist, dic, step, filter_fasc, gui, segmentation_mode, frame_callback=None)

Function to compute muscle architectural parameters based on convolutional neural network segmentation in videos.

Firstly, images are segmented by the network. Then, predictions are thresholded and filtered. The aponeuroses edges are computed and the fascicle length and pennation angle calculated. This is done by extrapolating fascicle segments above a threshold length. Then the intersection between aponeurosis edge and fascicle structures are computed. Returns none when not more than one aponeurosis contour is detected in the image.

PARAMETER DESCRIPTION
vid_len

Integer variable containing the number of frames present in cap.

TYPE: int

cap

Object that contains the video in a np.ndarrray format. In this way, seperate frames can be accessed.

TYPE: VideoCapture

vid_out

Object that is stored in the vpath folder. Contains the analyzed video frames and is titled "..._proc.avi" The name can be changed but must be different than the input video.

TYPE: VideoWriter

flip

String variable defining wheter an image should be flipped. This can be "no_flip" (video is not flipped) or "flip" (video is flipped).

TYPE: (no_flip, flip) DEFAULT: "no_flip"

apo_model

Aponeurosis neural network.

fasc_model

Fascicle neural network.

calib_dist

Integer variable containing the distance between the two specified point in pixel units. The points must be 10mm apart. Must be non-negative. If "None", the values are outputted in pixel units.

TYPE: int

dic

Dictionary variable containing analysis parameters. These include must include apo_threshold, fasc_threshold, fasc_cont_threshold, min_width, max_pennation, min_pennation.

TYPE: dict

step

Integer variable containing the step for the range of video frames. If step != 1, frames are skipped according to the size of step. This might decrease processing time but also accuracy.

TYPE: int

filter_fasc

If True, fascicles will be filtered so that no crossings are included. This may reduce number of totally detected fascicles.

TYPE: bool

gui

A tkinter.TK class instance that represents a GUI. By passing this argument, interaction with the GUI is possible i.e., stopping the calculation process after each image.

TYPE: TK

segmentation_mode

String variable containing the segmentation mode. This is used to determine the segmentation model used. Choose between "stacked" and and "None". When "stacked" is chosen, the frames are loaded in stacks of three.

TYPE: str

frame_callback

Boolean variable determining whether the current frame is displayed in main UI.

TYPE: bool DEFAULT: None

RETURNS DESCRIPTION
fasc_l_all

List of arrays contianing the estimated fascicle lengths based on the segmented fascicle fragments in pixel units as float. If calib_dist is specified, then the length is computed in centimeter. This is computed for each frame in the video.

TYPE: list

pennation_all

List of lists containing the estimated pennation angles based on the segmented fascicle fragments and aponeuroses as float. This is computed for each frame in the video.

TYPE: list

x_lows_all

List of lists containing the estimated x-coordinates of the lower edge from the upper aponeurosis as integers. This is computed for each frame in the video.

TYPE: list

x_highs_all

List of lists containing the estimated x-coordinates of the upper edge from the lower aponeurosis as integers. This is computed for each frame in the video.

TYPE: list

midthick_all

List variable containing the estimated distance between the lower and upper aponeurosis in pixel units. If calib_dist is specified, then the distance is computed in centimeter. This is computed for each frame in the video.

TYPE: list

Examples:

>>> doCalculations(vid_len=933, cap=< cv2.VideoCapture 000002BFAD0560B0>,
                    vid_out=< cv2.VideoWriter 000002BFACEC0130>,
                    flip="no_flip",
                    apo_modelpath="C:/Users/admin/Documents/DL_Track/Models_DL_Track/Final_models/model-VGG16-fasc-BCE-512.h5",
                    fasc_modelpath="C:/Users/admin/Documents/DL_Track/Models_DL_Track/Final_models/model-apo-VGG-BCE-512.h5",
                    calib_dist=98,
                    dic={'apo_treshold': '0.2', 'fasc_threshold': '0.05',
                    'fasc_cont_thresh': '40', 'min_width': '60',
                    'min_pennation': '10', 'max_pennation': '40'},
                    filter_fasc = False,
                    gui=<__main__.DL_Track_US object at 0x000002BFA7528190>,
                    segmentation_mode=None,
                    display_frame=True)
[array([60.5451731 , 58.86892027, 64.16011534, 55.46192704, 63.40711356]), ..., array([64.90849385, 60.31621836])]
[[19.124207107383114, 19.409753216521565, 18.05706763600641, 20.54453899050867, 17.808652286488794], ..., [17.26241882195032, 16.284803480359543]]
[[148, 5, 111, 28, -164], [356, 15, 105, -296], [357, 44, -254], [182, 41, -233], [40, 167, 42, -170], [369, 145, 57, -139], [376, 431, 32], [350, 0]]
[[725, 568, 725, 556, 444], [926, 572, 516, 508], [971, 565, 502], [739, 578, 474], [554, 766, 603, 475], [1049, 755, 567, 430], [954, 934, 568], [968, 574]]
[23.484416057267826, 22.465452189555794, 21.646971767045816, 21.602856412413924, 21.501286239714894, 21.331137350026623, 21.02446763240188, 21.250352548097883]

optimize_fascicle_loop(contoursF3, new_Y_UA, new_Y_LA, new_X_UA, new_X_LA, y_UA, y_LA, width, min_pennation, max_pennation, filter_fascicles_func, fasc_cont_thresh, calib_dist)

Extracts, extrapolates, and filters fascicle contours based on angle and length criteria.

This function processes a list of fascicle contour candidates, fits a linear function to each fascicle, extrapolates it, and computes intersections with extrapolated aponeuroses. Fascicles that meet a specified range of pennation angles and are long enough are retained. Optionally, filtering of overlapping fascicles can be applied. The result is returned as a structured pandas.DataFrame.

PARAMETER DESCRIPTION
contoursF3

List of fascicle contours (as arrays of shape (N, 1, 2)) returned by OpenCV findContours.

TYPE: list of np.ndarray

new_Y_UA

Y-values of the extrapolated upper aponeurosis curve (from polynomial fit).

TYPE: ndarray

new_Y_LA

Y-values of the extrapolated lower aponeurosis curve (from polynomial fit).

TYPE: ndarray

new_X_UA

X-values corresponding to new_Y_UA, used to estimate the aponeurosis slope.

TYPE: ndarray

new_X_LA

X-values corresponding to new_Y_LA, used to estimate the aponeurosis slope.

TYPE: ndarray

width

Image width, used to define extrapolation range.

TYPE: int

min_pennation

Minimum allowable pennation angle for valid fascicle inclusion (in degrees).

TYPE: float

max_pennation

Maximum allowable pennation angle for valid fascicle inclusion (in degrees).

TYPE: float

filter_fascicles_func

Optional function to apply filtering to remove overlapping or invalid fascicles. Should accept and return a pandas.DataFrame.

TYPE: callable or None

fasc_cont_thresh

Minimum number of contour points to consider a fascicle candidate.

TYPE: int

calib_dist

Calibration distance in pixels between two 10 mm markers. If given, fascicle lengths are scaled to mm.

TYPE: float or int

RETURNS DESCRIPTION
fascicle_data

A DataFrame containing columns: - 'x_low': int, start x-coordinate - 'x_high': int, end x-coordinate - 'y_low': int, start y-coordinate - 'y_high': int, end y-coordinate - 'coordsX': np.ndarray, x-points along fascicle - 'coordsY': np.ndarray, y-points along fascicle - 'fasc_l': float, fascicle length (in pixels or mm) - 'penn_a': float, fascicle pennation angle (degrees)

If no valid fascicles are found, the DataFrame will be empty with correct column names.

TYPE: DataFrame

Notes
  • Angles are computed relative to the slope of the lower aponeurosis.
  • Fascicle extrapolation uses a 1st-degree polynomial fit.
  • Fascicles extending beyond the extrapolation range are ignored.

Examples:

>>> df = optimize_fascicle_loop(
...     contoursF3=contours,
...     new_Y_UA=upper_y,
...     new_Y_LA=lower_y,
...     new_X_UA=upper_x,
...     new_X_LA=lower_x,
...     width=512,
...     min_pennation=10,
...     max_pennation=40,
...     filter_fascicles_func=my_filter_function,
...     fasc_cont_thresh=40,
...     calib_dist=98
... )
>>> df.head()
   x_low  x_high  y_low  y_high   fasc_l   penn_a
0    125     212    220     280  43.2175  21.3247
Description

This module contains all additional functions used in the module do_calculations_curved

Functions scope

adapted_contourEdge Function to find only the coordinates representing one edge of a contour. contourEdge Function to find only the coordinates representing one edge of a contour. sortContours Function to sort detected contours from proximal to distal. do_curves_intersect Function to detect wheter two curves are intersecting or not. adapted_filter_fascicles Filters out fascicles that intersect with other fascicles. is_point_in_range Function to detect wheter a point is between an upper and a lower boundary or not. find_next_fascicle Function to find the next fascicle contour. find_complete_fascicle Function to find complete fascicles based on connection of single contours. crop Function to crop the frame around ultrasound images.

adapted_contourEdge(edge, contour)

Function to find only the coordinates representing one edge of a contour.

Either the upper or lower edge of the detected contours is calculated. From the contour detected lower in the image, the upper edge is searched. From the contour detected higher in the image, the lower edge is searched. Allows for more points around the end of the contour than contourEdge.

PARAMETER DESCRIPTION
edge

String variable defining the type of edge that is searched. The variable can be either "T" (top) or "B" (bottom).

TYPE: (T, B) DEFAULT: "T"

contour

List variable containing sorted contours.

TYPE: list

RETURNS DESCRIPTION
x

Array variable containing all x-coordinates from the detected contour.

TYPE: ndarray

y

Array variable containing all y-coordinated from the detected contour.

TYPE: ndarray

Examples:

>>> contourEdge(edge="T", contour=[[[195 104]] ... [[196 104]]])
[196 197 198 199 200 ... 952 953 954 955 956 957],
[120 120 120 120 120 ... 125 125 125 125 125 125]

adapted_filter_fascicles(df, tolerance)

Filters out fascicles that intersect with other fascicles

This function counts for each fascicle the number of intersections with other fascicles and ranks them based on the number of intersections. The fascicle with the highest intersection count is excluded. This ranking and exclusion process is repeated until there are no more intersections.

PARAMETER DESCRIPTION
df

A DataFrame containing the fascicle data. Expected columns include 'coordsXY'.

TYPE: DataFrame

tolerance

Tolerance to allow intersection points near the aponeuroses

TYPE: int

RETURNS DESCRIPTION
DataFrame

A DataFrame with the fascicles that do not intersect with other fascicles.

Example

data = {'coordsXY': [[(78, 268), (78, 266), ...], [(43, 265), (42, 264), ...], ...]} tolerance = 100 adapted_filter_fascicles(data, tolerance)

contourEdge(edge, contour)

Function to find only the coordinates representing one edge of a contour.

Either the upper or lower edge of the detected contours is calculated. From the contour detected lower in the image, the upper edge is searched. From the contour detected higher in the image, the lower edge is searched.

PARAMETER DESCRIPTION
edge

String variable defining the type of edge that is searched. The variable can be either "T" (top) or "B" (bottom).

TYPE: (T, B) DEFAULT: "T"

contour

List variable containing sorted contours.

TYPE: list

RETURNS DESCRIPTION
x

Array variable containing all x-coordinates from the detected contour.

TYPE: ndarray

y

Array variable containing all y-coordinated from the detected contour.

TYPE: ndarray

Examples:

>>> contourEdge(edge="T", contour=[[[195 104]] ... [[196 104]]])
[196 197 198 199 200 ... 952 953 954 955 956 957],
[120 120 120 120 120 ... 125 125 125 125 125 125]

crop(original_image, image_fas, image_apo)

Function to crop the frame around ultrasound images

Additionally crops the fascicle and aponeuroses images in order that all three images have the same size

PARAMETER DESCRIPTION
original_image

Image of the original ultrasound image

TYPE: list

image_fas

Binary image of the fascicles within the original image

TYPE: list

image_apo

Binary image of the aponeuroses within the original image

TYPE: list

RETURNS DESCRIPTION
cropped_US

Image of the original ultrasound image without frame around it

TYPE: list

cropped_fas

Cropped binary image of fascicles within the original image

TYPE: list

cropped_apo

Cropped binary image of the aponeuroses within the original image

TYPE: list

Examples:

>>> crop(original_image=array([[[160, 160, 160],[159, 159, 159],[158, 158, 158],...[158, 158, 158],[147, 147, 147],[  1,   1,   1]],...,[[  0,   0,   0],[  0,   0,   0],[  0,   0,   0],...,[  4,   4,   4],[  3,   3,   3],[  3,   3,   3]]], dtype=uint8), image_fas = array([[0, 0, 0, ..., 0, 0, 0],[0, 0, 0, ..., 0, 0, 0],[0, 0, 0, ..., 0, 0, 0],...,[0, 0, 0, ..., 0, 0, 0],[0, 0, 0, ..., 0, 0, 0],[0, 0, 0, ..., 0, 0, 0]], dtype=uint8), image_apo = array([[[0, 0, 0],[0, 0, 0],[0, 0, 0],...,[0, 0, 0],[0, 0, 0],[0, 0, 0]]], dtype=uint8))

do_curves_intersect(curve1, curve2)

Function to detect wheter two curves are intersecting or not.

PARAMETER DESCRIPTION
curve1

List containing (x,y) coordinate pairs representing one curve

TYPE: list

curve2

List containing (x,y) coordinate pairs representing a second curve

TYPE: list

RETURNS DESCRIPTION
Bool

'True' if the curves have an intersection point 'False' if the curves don't have an intersection point

Examples:

>>> do_curves_intersect(curve1=[(98.06, 263.24), (98.26, 263.19), ...],
curve2=[(63.45, 258.82), (63.65, 258.76), ...])

find_complete_fascicle(i, contours_sorted_x, contours_sorted_y, contours_sorted, label, mid, width, tolerance, coeff_limit)

Function to find complete fascicles based on connection of single contours.

The function extrapolates a second order polynomial fit through the first contour. If the coefficients fall outside a specified range, the curve is considered too curved. As a result, a linear fit is calculated and used for subsequent calculations. The next contour is identified if its first point lies within a specified tolerance range in the positive and negative y-direction around the extrapolated fit. If this condition is met, both contours serve as the basis for the next polynomial fit. This process is repeated until no more possible connecting contours are found.

PARAMETER DESCRIPTION
i

Integer value defining the starting contour

TYPE: int

contours_sorted_x

List containing all x-coordinates of each detected contour

TYPE: list

contours_sorted_y

List containing all y-coordinates of each detected contour

TYPE: list

contours_sorted

List containing all (x,y)-coordinates of each detected contour

TYPE: list

label

Dictionnary containing a label true or false for every fascicle contour, true if already used for an extrapolation, false if not

TYPE: dictionnary

mid

Integer value defining the middle of the image

TYPE: int

width

Integer value defining the width of the image

TYPE: int

tolerance

Integer value specifing the permissible range in the positive and negative y-direction within which the next contour can be located to still be considered a part of the extrapolated fascicle

TYPE: int

coeff_limit

Value defining the maximum value of the first coefficient in the second polynomial fit

TYPE: float

RETURNS DESCRIPTION
ex_current_fascicle_x

List containing the x-coordinates of each found and extrapolated fascicle

TYPE: list

ex_current_fascicle_y

List containing the y-coordinates of each found and extrapolated fascicle

TYPE: list

linear_fit

'True' if extrapolated fit is linear 'False' if extrapolated fit follows a second order polynomial

TYPE: bool

inner_number_contours

List containing the indices of each contour that constitute each fascicle

TYPE: list

Examples:

>>> find_complete_fascicle(i=0, contours_sorted_x=[array([ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36],dtype=int32),...,array([481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497],dtype=int32)]), contours_sorted_y=[array([166, 166, 166, 165, 165, 165, 164, 164, 164, 163, 163, 163, 162, 162, 162, 161, 161, 161, 160, 160, 160, 159, 159, 159, 158, 158, 158, 157, 157, 157, 156, 156],dtype=int32),...,array([76, 76, 76, 76, 75, 75, 75, 74, 74, 74, 74, 73, 73, 73, 72, 72, 72],dtype=int32)], contours_sorted=[[array([ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36],dtype=int32),array([166, 166, 166, 165, 165, 165, 164, 164, 164, 163, 163, 163, 162, 162, 162, 161, 161, 161, 160, 160, 160, 159, 159, 159, 158, 158, 158, 157, 157, 157, 156, 156], dtype=int32),...]], label={0: False, 1: False, 2: False, 3: False, 4: False, 5: False, 6: False, 7: False, 8: False, 9: False, 10: False, 11: False, 12: False, 13: False}, mid=256.0, width=512, tolerance=10, coeff_limit=0.000583)

find_complete_fascicle_linear(i, contours_sorted_x, contours_sorted_y, contours_sorted, label, mid, width, tolerance, coeff_limit)

Traces a complete fascicle by iteratively fitting and extrapolating a linear model through connected contour segments in an ultrasound image.

Starting from a seed contour i, the function fits a line, extrapolates it over a defined width, and collects all contour segments that lie within a vertical tolerance range around the extrapolated line. The procedure continues recursively to find connected fascicle segments along the extrapolated path.

PARAMETER DESCRIPTION
i

Index of the initial contour used to start the fascicle tracing.

TYPE: int

contours_sorted_x

List of arrays containing the x-coordinates of each contour segment.

TYPE: list of ndarray

contours_sorted_y

List of arrays containing the y-coordinates of each contour segment.

TYPE: list of ndarray

contours_sorted

List of full contour arrays (used for proximity checking).

TYPE: list of ndarray

label

Dictionary mapping contour indices to a boolean indicating whether they have already been used. Will be updated in-place.

TYPE: dict

mid

Midpoint x-coordinate used as center of extrapolation range.

TYPE: int

width

Half-width of the extrapolation span in pixels (from mid - width to mid + width).

TYPE: int

tolerance

Vertical distance in pixels allowed between the extrapolated line and candidate contour segments.

TYPE: int

coeff_limit

Currently unused; placeholder for limiting slope or intercept values during fitting.

TYPE: float

RETURNS DESCRIPTION
ex_current_fascicle_x

Extrapolated x-coordinates of the complete fascicle.

TYPE: ndarray

ex_current_fascicle_y

Corresponding y-coordinates from the final linear model fit.

TYPE: ndarray

linear_fit

Flag indicating whether a linear fit was successfully computed (always True in current logic).

TYPE: bool

inner_number_contours

List of contour indices that belong to the detected fascicle.

TYPE: list of int

Notes
  • This function modifies the label dictionary in-place to prevent reprocessing contours.
  • The input coeff_limit is accepted but currently not used for filtering.

Examples:

>>> ex_x, ex_y, is_linear, used_contours = find_complete_fascicle_linear(
...     i=0,
...     contours_sorted_x=contour_x_list,
...     contours_sorted_y=contour_y_list,
...     contours_sorted=contour_list,
...     label={j: False for j in range(len(contour_x_list))},
...     mid=256,
...     width=100,
...     tolerance=5,
...     coeff_limit=0.5
... )
>>> plt.plot(ex_x, ex_y)
>>> print(f"Used {len(used_contours)} contour segments.")

find_next_fascicle(all_contours, contours_sorted_x, contours_sorted_y, x_current_fascicle, y_current_fascicle, x_range, upper_bound, lower_bound, label)

Function to find the next fascicle contour

PARAMETER DESCRIPTION
all_contours

List containing all (x,y)-coordinates of each detected contour

TYPE: list

contours_sorted_x

List containing all x-coordinates of each detected contour

TYPE: list

contours_sorted_y

List containing all y-coordinates of each detected contour

TYPE: list

x_current_fascicle

List containing the x-coordinates of the currently examined fascicle

TYPE: list

y_current_fascicle

List containing the y-coordinates of the currently examined fascicle

TYPE: list

x_range

List containing all x-coordinates within the range of the extrapolation

TYPE: list

upper_bound

List containing all y-coordinates of the lower boundary

TYPE: list

lower_bound

List containing all y-coordinates of the upper boundary

TYPE: list

label

Dictionnary containing a label true or false for every fascicle contour, true if already used for an extrapolation, false if not

TYPE: dictionnary

RETURNS DESCRIPTION
new_x

List containing the x-coordinates of the currently examined fascicle merged with the x-coordinates of the next fascicle contour within the boundary if one was found

TYPE: list

new_y

List containing the y-coordinates of the currently examined fascicle merged with the y-coordinates of the next fascicle contour within the boundary if one was found

TYPE: list

found_fascicle

Integer value of the found fascicle contour, -1 if no contour was found

TYPE: int

Examples:

>>> find_next_fascicle(all_contours = , contours_sorted_x=[array([ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36],dtype=int32),...,array([481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493,494, 495, 496, 497],dtype=int32)]), contours_sorted_y=[array([166, 166, 166, 165, 165, 165, 164, 164, 164, 163, 163, 163, 162, 162, 162, 161, 161, 161, 160, 160, 160, 159, 159, 159, 158, 158, 158, 157, 157, 157, 156, 156], dtype=int32),...,array([76, 76, 76, 76, 75, 75, 75, 74, 74, 74, 74, 73, 73, 73, 72, 72, 72],dtype=int32)], x_current_fascicle=array([ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36],dtype=int32), y_current_fascicle=array([166, 166, 166, 165, 165, 165, 164, 164, 164, 163, 163, 163, 162, 162, 162, 161, 161, 161, 160, 160, 160, 159, 159, 159, 158, 158, 158, 157, 157, 157, 156, 156], dtype=int32), x_range=array([-256.   , -255.795, -255.59 , ...,  767.59 ,  767.795,  768.   ]), upper_bound=array([243.137, 243.069, 243.001, ..., -97.372, -97.44 , -97.508]), lower_bound=array([263.137, 263.069, 263.001, ..., -77.372, -77.44 , -77.508]), label={0: True, 1: False, 2: False, 3: False, 4: False, 5: False, 6: False, 7: False, 8: False, 9: False, 10: False, 11: False, 12: False, 13: False})

is_point_in_range(x_point, y_point, x_poly, lb, ub)

Function to detect wheter a point is between an upper and a lower boundary or not.

PARAMETER DESCRIPTION
x_point

Single integer variable representing the x-coordinate of the point to be analyzed

TYPE: int

y_point

Single integer variable representing the y-coordinate of the point to be analyzed

TYPE: integer

x_poly

List containing all x-coordinates of the range where the point could be located

TYPE: list

lb

List containing all y-coordinates of the lower boundary

TYPE: list

ub

List containing all y-coordinates of the upper boundary

TYPE: list

RETURNS DESCRIPTION
Bool

'True' if point is within both boundaries 'False' if point is outside the boundaries

Examples:

>>> is_point_in_range(x_point=250, y_point=227,
x_poly=([-200, ..., 800]), lb=([303.165, ..., 130.044]),
ub=([323.165, ..., 150.044]))

sortContours(cnts)

Function to sort detected contours from proximal to distal.

The input contours belond to the aponeuroses and are sorted based on their coordinates, from smallest to largest. Moreover, for each detected contour a bounding box is built. The bounding boxes are sorted as well. They are however not needed for further analyses.

PARAMETER DESCRIPTION
cnts

List of arrays containing the detected aponeurosis contours.

TYPE: list

RETURNS DESCRIPTION
cnts

Tuple containing arrays of sorted contours.

TYPE: tuple

bounding_boxes

Tuple containing tuples with sorted bounding boxes.

TYPE: tuple

Examples:

>>> sortContours(cnts=[array([[[928, 247]], ... [[929, 247]]],
dtype=int32),
((array([[[228,  97]], ... [[229,  97]]], dtype=int32),
(array([[[228,  97]], ... [[229,  97]]], dtype=int32),
(array([[[928, 247]], ... [[929, 247]]], dtype=int32)),
((201, 97, 747, 29), (201, 247, 750, 96))

Module to filter the data subsequent to the analyses functions.

applyFilters(data, filter_type='median', **kwargs)

Applies a selected filter to the input data.

PARAMETER DESCRIPTION
data

The input data to be filtered.

TYPE: list of lists

filter_type

The type of filter to apply. Options are "median", "gaussian", "savitzky_golay".

TYPE: str DEFAULT: 'median'

kwargs

Additional parameters for the selected filter.

TYPE: dict DEFAULT: {}

RETURNS DESCRIPTION
list of lists

The filtered data.

hampelFilterList(data, win_size=5, num_dev=1, center_win=True)

Applies a Hampel filter to a list of numerical values.

This function detects and replaces outliers with the rolling median within a specified window size.

PARAMETER DESCRIPTION
data

List of numerical values.

TYPE: list

win_size

Window size for rolling median filtering. Default is 5.

TYPE: int DEFAULT: 5

num_dev

Number of standard deviations for outlier detection. Default is 1.

TYPE: int DEFAULT: 1

center_win

Whether the window is centered on the point. Default is True.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION
dict

A dictionary with: - "filtered" : list with filtered values. - "outliers" : list where outliers are replaced with NaN. - "is_outlier" : list of boolean values indicating outliers.

Examples:

>>> data = [10, 12, 100, 14, 13, 15, 300, 18, 16]
>>> result = hampel_filter_list(data, win_size=3, num_dev=2)
>>> print(result["filtered"])
[10, 12, 13, 14, 13, 15, 16, 18, 16]
>>> print(result["is_outlier"])
[False, False, True, False, False, False, True, False, False]
Description

This module contains functions to automatically or manually analyse muscle architecture in longitudinal ultrasonography images of human lower limb muscles. The scope of the automatic method is limited to the vastus lateralis, tibialis anterior, gastrocnemius medialis and soleus muscles due to training data availability. The scope of the manual method is not limited to specific muscles. The module was specifically designed to be executed from a GUI. When used from the GUI, the module saves the analysis results in a .xlsx file to a given directory. The user needs to provide paths to the image, model, and flipflag file directories.

Functions scope

importAndReshapeImage Function to import and reshape an image. Moreover, based upon user specification the image might be flipped. importImageManual Function to import an image. importFlipFlagsList Function to retrieve flip values from a .txt file. compileSaveResults Function to save the analysis results to a .xlsx file. IoU Function to compute the intersection over union score (IoU), a measure of prediction accuracy. This is sometimes also called Jaccard score. calculateBatch Function to calculate muscle architecture in longitudinal ultrasonography images of human lower limb muscles. The values computed are fascicle length (FL), pennation angle (PA), and muscle thickness (MT). calculateBatchManual Function used for manual calculation of fascicle length, muscle thickness and pennation angles in longitudinal ultrasonography images of human lower limb muscles.

Notes

Additional information and usage exaples can be found at the respective functions documentations.

calculateBatch(rootpath, apo_modelpath, fasc_modelpath, flip_file_path, file_type, scaling, spacing, filter_fasc, settings, gui, image_frame=None)

Function to calculate muscle architecture in longitudinal ultrasonography images of human lower limb muscles. The values computed are fascicle length (FL), pennation angle (PA), and muscle thickness (MT).

The scope of this function is limited. Images of the vastus lateralis, tibialis anterior soleus and gastrocnemius muscles can be analyzed. This is due to the limited amount of training data for our convolutional neural networks. This functions makes extensive use of several other functions and was designed to be executed from a GUI.

PARAMETER DESCRIPTION
rootpath

String variable containing the path to the folder where all images to be analyzed are saved.

TYPE: str

apo_modelpath

String variable containing the absolute path to the aponeurosis neural network.

TYPE: str

fasc_modelpath

String variable containing the absolute path to the fascicle neural network.

TYPE: str

flip_file_path

String variabel containing the absolute path to the flip flag .txt file containing the flip flags. Flipping is necessary as the models were trained on images of with specific fascicle orientation.

TYPE: str

file_type

String variable containg the respective type of the images. This is needed to select only the relevant image files in the root directory.

TYPE: str

scaling

String variabel determining the image scaling method. There are three types of scaling available: - scaling = "manual" (user must scale images manually) - sclaing = "bar" (image are scaled automatically. This is done by detecting scaling bars on the right side of the image.) - scaling = "No scaling" (image is not scaled.) Scaling is necessary to compute measurements in centimeter, if "no scaling" is chosen, the results are in pixel units.

TYPE: (bar, manual, 'No scaling') DEFAULT: "bar"

spacing

Distance (in milimeter) between two scaling bars in the image. This is needed to compute the pixel/cm ratio and therefore report the results in centimeter rather than pixel units.

TYPE: (10, 5, 15, 20) DEFAULT: 10

filter_fasc

If True, fascicles will be filtered so that no crossings are included. This may reduce number of totally detected fascicles.

TYPE: bool

settings

Dictionary containing the analysis settings of the GUI.

TYPE: dict

gui

A tkinter.TK class instance that represents a GUI. By passing this argument, interaction with the GUI is possible i.e., stopping the calculation process after each image.

TYPE: TK

See Also

do_calculations.py for exact description of muscle architecture parameter calculation.

Notes

For specific explanations of the included functions see the respective function docstrings in this module. To see an examplenary PDF output and .xlsx file take at look at the examples provided in the "examples" directory. This function is called by the GUI. Note that the functioned was specifically designed to be called from the GUI. Thus, tk.messagebox will pop up when errors are raised even if the GUI is not started.

Examples:

>>> calculateBatch(rootpath="C:/Users/admin/Dokuments/images",
                   apo_modelpath="C:/Users/admin/Dokuments/models/apo_model.h5",
                   fasc_modelpath="C:/Users/admin/Dokuments/models/apo_model.h5",
                   flip_file_path="C:/Users/admin/Dokuments/flip_flags.txt",
                   file_type="/**/*.tif, scaline="bar", spacing=10, filter_fasc=False,
                   settings=settings,
                   gui=<__main__.DL_Track_US object at 0x000002BFA7528190>)

calculateBatchManual(rootpath, filetype, gui)

Function used for manual calculation of fascicle length, muscle thickness and pennation angles in longitudinal ultrasonography images of human lower limb muscles.

This function is not restricted to any specific muscles. However, its use is restricted to a specific method for assessing muscle thickness fascicle length and pennation angles.

  • Muscle thickness: Exactly one segment reaching from the superficial to the deep aponeuroses of the muscle must be drawn. If multiple measurement are drawn, these are averaged. Drawing can be started by clickling the left mouse button and keeping it pressed until it is not further required to draw the line (i.e., the other aponeurosis border is reached). Only the respective y-coordinates of the points where the cursor was clicked and released are considered for calculation of muscle thickness.
  • Fascicle length: Exactly three segments along the fascicleof the muscle must be drawn. If multiple fascicle are drawn, their lengths are averaged. Drawing can be started by clickling the left mouse button and keeping it pressed until one segment is finished (mostly where fascicle curvature occurs the other aponeurosis border is reached). Using the euclidean distance, the total fascicle length is computed as a sum of the segments.
  • Pennation angle: Exactly two segments, one along the fascicle orientation, the other along the aponeurosis orientation must be drawn. The line along the aponeurosis must be started where the line along the fascicle ends. If multiple angle are drawn, they are averaged. Drawing can be started by clickling the left mouse button and keeping it pressed until it is not further required to draw the line (i.e., the aponeurosis border is reached by the fascicle). The angle is calculated using the arc-tan function. In order to scale the frame, it is required to draw a line of length 10 milimeter somewhere in the image. The line can be drawn in the same fashion as for example the muscle thickness. Here however, the euclidean distance is used to calculate the pixel / centimeter ratio. This has to be done for every frame.

We also provide the functionality to extent the muscle aponeuroses to more easily extrapolate fascicles. The lines can be drawn in the same fashion as for example the muscle thickness.

PARAMETER DESCRIPTION
rootpath

String variable containing the path to the folder where all images to be analyzed are saved.

TYPE: str

gui

A tkinter.TK class instance that represents a GUI. By passing this argument, interaction with the GUI is possible i.e., stopping the calculation process after each image.

TYPE: TK

Notes

For specific explanations of the included functions see the respective function docstrings in this module. The function outputs an .xlsx file in rootpath containing the (averaged) analysis results for each image.

Examples:

>>> calculateBatchManual(rootpath="C:/Users/admin/Dokuments/images",
                         filetype="/**/*.tif,
                         gui")

exportToExcel(path, fasc_l_all, pennation_all, x_lows_all, x_highs_all, thickness_all, filename='Results', filtered_fasc=None, filtered_pennation=None, analysis_mode='video', image_filenames=None)

Saves raw and optionally filtered analysis results to an Excel file, including an index column for each frame.

PARAMETER DESCRIPTION
path

Path where the Excel file will be saved.

TYPE: str

filename

Name of the Excel file.

TYPE: str DEFAULT: 'Results'

fasc_l_all

Raw fascicle length data.

TYPE: list of lists

pennation_all

Raw pennation angle data.

TYPE: list of lists

x_lows_all

X-coordinates of lower aponeurosis intersections.

TYPE: list of lists

x_highs_all

X-coordinates of upper aponeurosis intersections.

TYPE: list of lists

thickness_all

Muscle thickness measurements.

TYPE: list of lists

filtered_fasc

Filtered fascicle length data.

TYPE: list of lists DEFAULT: None

filtered_pennation

Filtered pennation angle data.

TYPE: list of lists DEFAULT: None

analysis_mode

Analysis mode used for the calculations. If "video", savgol filter will be appiled.

TYPE: str DEFAULT: 'video'

image_filenames

List of image filenames corresponding to the analysis results.

TYPE: list of str DEFAULT: None

getFlipFlagsList(flip_flag_path, gui)

Function to retrieve flip values from a .txt file.

The flip flags decide wether an image should be flipped or not. The flags can be 0 (image not flipped) or 1 (image is flipped). The flags must be specified in the .txt file and can either be on a seperate line for each image or on a seperate line for each folder. The amount of flip flags must equal the amount of images analyzed.

PARAMETER DESCRIPTION
flip_flag_path

String variabel containing the absolute path to the flip flag .txt file containing the flip flags.

TYPE: str

gui

The GUI object.

TYPE: Tk

RETURNS DESCRIPTION
flip_flags

A list variable containing all flip flags included in the specified .txt file

TYPE: list

Examples:

>>> getFlipFlagsList(flip_flag_path="C:/Desktop/Test/FlipFlags/flags.txt")
[1, 0, 1, 0, 1, 1, 1]

importAndReshapeImage(path_to_image, flip)

Function to import and reshape an image. Moreover, based upon user specification the image might be flipped.

Usually flipping is only required when the imported image is of a specific structure that is incompatible with the trained models provided here

PARAMETER DESCRIPTION
path_to_image

String variable containing the imagepath. This should be an absolute path.

TYPE: str

flip

Integer value defining wheter an image should be flipped. This can be 0 (image is not flipped) or 1 (image is flipped).

TYPE: (0, 1) DEFAULT: 0

RETURNS DESCRIPTION
img

The loaded images is converted to a np.nadarray. This is done using the img_to_array kears functionality. The input image is futhter flipped (if selected), resized, respahed and normalized.

TYPE: ndarray

img_copy

A copy of the input image.

TYPE: ndarray

non_flipped_img

A copy of the input image. This copy is made prior to image flipping.

TYPE: ndarray

height

Integer value containing the image height of the input image.

TYPE: int

width

Integer value containing the image width of the input image.

TYPE: int

filename

String value containing the name of the input image, not the entire path.

TYPE: str

Examples:

>>> importAndReshapeImage(path_to_image="C:/Users/Dokuments/images/img1.tif", flip=0)
[[[[0.10113753 0.09391343 0.09030136] ... [0 0 0]]], [[[28 26 25] ... [ 0  0  0]]], [[[28 26 25] ... [ 0  0  0]]], 512, 512, img1.tif

importImageManual(path_to_image, flip)

Function to import an image.

This function is used when manual analysis of the image is selected in the GUI. For manual analysis, it is not necessary to resize, reshape and normalize the image. The image may be flipped.

PARAMETER DESCRIPTION
path_to_image

String variable containing the imagepath. This should be an absolute path.

TYPE: str

flip

Integer value defining wheter an image should be flipped. This can be 0 (image is not flipped) or 1 (image is flipped).

TYPE: (0, 1) DEFAULT: 0

RETURNS DESCRIPTION
img

The loaded images as a np.nadarray in grayscale.

TYPE: ndarray

filename

String value containing the name of the input image, not the entire path.

TYPE: str

Examples:

>>> importImageManual(path_to_image="C:/Desktop/Test/Img1.tif", flip=0)
[[[28 26 25] [28 26 25] [28 26 25] ... [[ 0  0  0] [ 0  0  0] [ 0  0  0]]],
Img1.tif

preprocess_function(image)

Function to preprocess an image.

PARAMETER DESCRIPTION
image

Image to be preprocessed.

TYPE: ndarray

RETURNS DESCRIPTION
ndarray

Preprocessed image.

Description

This module contains functions to automatically or manually analyse muscle architecture in longitudinal ultrasonography videos of human lower limb muscles. The scope of the automatic method is limited to the vastus lateralis, tibialis anterior, gastrocnemius medialis and soleus muscles due to training data availability. The scope of the manual method is not limited to specific muscles. The module was specifically designed to be executed from a GUI. When used from the GUI, the module saves the analysis results in a .xlsx file to a given directory. The user needs to provide paths to the video, model, and flipflag file directories. With both methods, every frame is analyzed seperately and the results for each frame are saved.

Functions scope

importAndReshapeImage Function to import and reshape an image. Moreover, based upon user specification the image might be flipped. importImageManual Function to import an image. importFlipFlagsList Function to retrieve flip values from a .txt file. compileSaveResults Function to save the analysis results to a .xlsx file. calculateBatch Function to calculate muscle architecture in longitudinal ultrasonography images of human lower limb muscles. The values computed are fascicle length (FL), pennation angle (PA), and muscle thickness (MT). calculateBatchManual Function used for manual calculation of fascicle length, muscle thickness and pennation angles in longitudinal ultrasonography images of human lower limb muscles.

Notes

Additional information and usage examples can be found at the respective functions documentations.

See Also

calculate_architecture.py

calculateArchitectureVideo(rootpath, apo_modelpath, fasc_modelpath, filetype, scaling, flip, step, filter_fasc, settings, gui, display_frame)

Function to calculate muscle architecture in longitudinal ultrasonography videos of human lower limb muscles. The values computed are fascicle length (FL), pennation angle (PA), and muscle thickness (MT).

The scope of this function is limited. videos of the vastus lateralis, tibialis anterior soleus and gastrocnemius muscles can be analyzed. This is due to the limited amount of training data for our convolutional neural networks. This functions makes extensive use of several other functions and was designed to be executed from a GUI.

PARAMETER DESCRIPTION
rootpath

String variable containing the path to the folder where all videos to be analyzed are saved.

TYPE: str

apo_modelpath

String variable containing the absolute path to the aponeurosis neural network.

TYPE: str

fasc_modelpath

String variable containing the absolute path to the fascicle neural network.

TYPE: str

flip

String variable determining wheter all frames of a video are flipped vetically. Flipping is necessary as the models were trained in images of with specific fascicle orientation.

TYPE: str

filetype

String variable containg the respective type of the videos. This is needed to select only the relevant video files in the root directory.

TYPE: str

scaling

String variable determining the image scaling method. There are three types of scaling available: - scaling = "manual" (user must scale the video manually. This only needs to be done in the first frame.) detecting scaling bars on the right side of the image.) - scaling = "No scaling" (video frames are not scaled.) Scaling is necessary to compute measurements in centimeter, if "no scaling" is chosen, the results are in pixel units.

TYPE: str

step

Integer variable containing the step for the range of video frames. If step != 1, frames are skipped according to the size of step. This might decrease processing time but also accuracy.

TYPE: int

filter_fasc

If True, fascicles will be filtered so that no crossings are included. This may reduce number of totally detected fascicles.

TYPE: bool

settings

Dictionary containing the settings of the GUI. These specify the prediction parameters for the neural networks.

TYPE: dict

gui

A tkinter.TK class instance that represents a GUI. By passing this argument, interaction with the GUI is possible i.e., stopping the calculation process after each image.

TYPE: TK

display_frame

Boolean variable determining whether the current frame is displayed in main UI.

TYPE: bool

See Also

do_calculations_video.py for exact description of muscle architecture parameter calculation.

Notes

For specific explanations of the included functions see the respective function docstrings in this module. To see an examplenary video output and .xlsx file take at look at the examples provided in the "examples" directory. This function is called by the GUI. Note that the functioned was specifically designed to be called from the GUI. Thus, tk.messagebox will pop up when errors are raised even if the GUI is not started.

Examples:

>>> calculateBatch(rootpath="C:/Users/admin/Dokuments/images",
                   apo_modelpath="C:/Users/admin/Dokuments/models/apo_model.h5",
                   fasc_modelpath="C:/Users/admin/Dokuments/models/apo_model.h5",
                   flip="Flip", filetype="/**/*.avi, scaline="manual",
                   filter_fasc=False
                   settings=settings,
                   gui=<__main__.DLTrack object at 0x000002BFA7528190>,
                   display_frame=True)

calculateArchitectureVideoManual(videopath, gui)

Function used for manual calculation of fascicle length, muscle thickness and pennation angles in longitudinal ultrasonography videos of human lower limb muscles.

This function is not restricted to any specific muscles. However, its use is restricted to a specific method for assessing muscle thickness fascicle length and pennation angles. Moreover, each video frame is analyzed seperately.

  • Muscle thickness: Exactly one segment reaching from the superficial to the deep aponeuroses of the muscle must be drawn. If multiple measurement are drawn, these are averaged. Drawing can be started by clickling the left mouse button and keeping it pressed until it is not further required to draw the line (i.e., the other aponeurosis border is reached). Only the respective y-coordinates of the points where the cursor was clicked and released are considered for calculation of muscle thickness.
  • Fascicle length: Exactly three segments along the fascicleof the muscle must be drawn. If multiple fascicle are drawn, their lengths are averaged. Drawing can be started by clickling the left mouse button and keeping it pressed until one segment is finished (mostly where fascicle curvature occurs the other aponeurosis border is reached). Using the euclidean distance, the total fascicle length is computed as a sum of the segments.
  • Pennation angle: Exactly two segments, one along the fascicle orientation, the other along the aponeurosis orientation must be drawn. The line along the aponeurosis must be started where the line along the fascicle ends. If multiple angle are drawn, they are averaged. Drawing can be started by clickling the left mouse button and keeping it pressed until it is not further required to draw the line (i.e., the aponeurosis border is reached by the fascicle). The angle is calculated using the arc-tan function. In order to scale the frame, it is required to draw a line of length 10 milimeter somewhere in the image. The line can be drawn in the same fashion as for example the muscle thickness. Here however, the euclidean distance is used to calculate the pixel / centimeter ratio. This has to be done for every frame.

We also provide the functionality to extent the muscle aponeuroses to more easily extrapolate fascicles. The lines can be drawn in the same fashion as for example the muscle thickness.

PARAMETER DESCRIPTION
videopath

String variable containing the absolute path to the video to be analyzed.

TYPE: str

gui

A tkinter.TK class instance that represents a GUI. By passing this argument, interaction with the GUI is possible i.e., stopping the calculation process after each image frame.

TYPE: TK

Notes

For specific explanations of the included functions see the respective function docstrings in this module. The function outputs an .xlsx file in rootpath containing the (averaged) analysis results for each image.

Examples:

>>> calculateBatchManual(videopath="C:/Users/admin/Dokuments/videoss",
                         gui")

importVideo(vpath)

Function to import a video. Video file types should be common ones like .avi or .mp4.

PARAMETER DESCRIPTION
vpath

String variable containing the video. This should be an absolute path.

TYPE: str

RETURNS DESCRIPTION
cap

Object that contains the video in a np.ndarrray format. In this way, seperate frames can be accessed.

TYPE: VideoCapture

vid_len

Integer variable containing the number of frames present in cap.

TYPE: int

width

Integer variable containing the image width of the input image.

TYPE: int

filename

String variable containing the name of the input video, not the entire path.

TYPE: str

vid_out

Object that is stored in the vpath folder. Contains the analyzed video frames and is titled "..._proc.avi" The name can be changed but must be different than the input video.

TYPE: VideoWriter

Examples:

>>> importVideo(vpath="C:/Users/Dokuments/videos/video1.avi")

importVideoManual(vpath)

Function to import a video. Video file types should be common ones like .avi or .mp4. This function is used for manual analysis of videos.

Here, no processed video is saved subsequent to analysis.

PARAMETER DESCRIPTION
vpath

String variable containing the video. This should be an absolute path.

TYPE: str

RETURNS DESCRIPTION
cap : cv2.VideoCapture

Object that contains the video in a np.ndarrray format. In this way, seperate frames can be accessed.

vid_len

A copy of the input image.

TYPE: ndarray

vid_width

Integer value containing the image width of the input video.

TYPE: int

vid_height

Integer value containing the image height of the input video.

TYPE: int

width

Integer value containing the image width of the input image.

TYPE: int

filename

String value containing the name of the input video, not the entire path.

TYPE: str

Examples:

>>> importVideo(vpath="C:/Users/Dokuments/videos/video1.avi")
Description

This module contains functions to automatically scale images. The scope of the automatic method is limited to scaling bars being present in the right side of the image. However, the distance between two selected points in the image required for the scaling must be known.

Functions scope

calibrateDistanceStatic Function to calibrate an image to convert measurements in pixel units to centimeters.

calibrateDistanceStatic(img, spacing)

Function to calibrate an image to convert measurements in pixel units to centimeter.

The function calculates the distance in pixel units between two scaling bars on the input image. The bars should be positioned on the right side of image. The distance (in milimeter) between two bars must be specified by the spacing variable. It is the known distance between two bars in milimeter. Then the ratio of pixel / centimeter is calculated. To get the distance, the median distance between two detected bars is calculated.

PARAMETER DESCRIPTION
img

Input image to be analysed as a numpy array. The image must be loaded prior to calibration, specifying a path is not valid.

TYPE: ndarray

spacing

Integer variable containing the known distance in milimeter between the two scaling bars. This can be 5, 10, 15 or 20 milimeter.

TYPE: (10, 5, 15, 20) DEFAULT: 10

RETURNS DESCRIPTION
calib_dist

Integer variable containing the distance between the two specified point in pixel units.

TYPE: int

scale_statement

String variable containing a statement how many milimeter correspond to how many pixels.

TYPE: str

Examples:

>>> calibrateDistanceStatic(img=([[[[0.22414216 0.19730392 0.22414216] ... [0.2509804  0.2509804  0.2509804 ]]]), 5)
99, 5 mm corresponds to 99 pixels
Description

This module contains a class to manually annotate longitudinal ultrasonography images and videos. When the class is initiated, a graphical user interface is opened. There, the user can annotate muscle fascicle length, pennation angle and muscle thickness. Moreover, the images can be scaled in order to get measurements in centimeters rather than pixels. By clicking the respective buttons in the GUI, the user can switch between the different parameters to analyze. The analysis is not restricted to any specific muscles. However, its use is restricted to a specific method for assessing muscle thickness, fascicle length and pennation angles. Moreover, each video frame is analyzed separately. An .xlsx file is retuned containing the analysis results for muscle fascicle length, pennation angle and muscle thickness.

Functions scope

For scope of the functions see class documentation.

Notes

Additional information and usage examples can be found at the respective functions docstrings.

ManualAnalysis

Python class to manually annotate longitudinal muscle ultrasonography images/videos of human lower limb muscles. An analysis tkinter GUI is opened upon initialization of the class. By clicking the buttons, the user can switch between different parameters to analyze in the images.

  • Muscle thickness: Exactly one segment reaching from the superficial to the deep aponeuroses of the muscle must be drawn. If multiple measurement are drawn, these are averaged. Drawing can be started by clickling the left mouse button and keeping it pressed until it is not further required to draw the line (i.e., the other aponeurosis border is reached). Only the respective y-coordinates of the points where the cursor was clicked and released are considered for calculation of muscle thickness.
  • Fascicle length: Exactly three segments along the fascicleof the muscle must be drawn. If multiple fascicle are drawn, their lengths are averaged. Drawing can be started by clickling the left mouse button and keeping it pressed until one segment is finished (mostly where fascicle curvature occurs the other aponeurosis border is reached). Using the euclidean distance, the total fascicle length is computed as a sum of the segments.
  • Pennation angle: Exactly two segments, one along the fascicle orientation, the other along the aponeurosis orientation must be drawn. The line along the aponeurosis must be started where the line along the fascicle ends. If multiple angle are drawn, they are averaged. Drawing can be started by clickling the left mouse button and keeping it pressed until it is not further required to draw the line (i.e., the aponeurosis border is reached by the fascicle). The angle is calculated using the arc-tan function. In order to scale the image/video frame, it is required to draw a line of length 10 milimeter somewhere in the image. The line can be drawn in the same fashion as for example the muscle thickness. Here however, the euclidean distance is used to calculate the pixel / centimeter ratio. This has to be done for every frame. We also provide the functionality to extend the muscle aponeuroses to more easily extrapolate fascicles. The lines can be drawn in the same fashion as for example the muscle thickness. During the analysis process, care must be taken to not accidentally click the left mouse button as those coordinates might mess up the results given that calculations are based on a strict analysis protocol.
ATTRIBUTE DESCRIPTION
self.image_list

A list variable containing the absolute paths to all images / video to be analyzed.

TYPE: list

self.rootpath

Path to root directory where images / videos for the analysis are saved.

TYPE: str

self.lines

A list variable containing all lines that are drawn upon the image by the user. The list is emptied each time the analyzed parameter is changed.

TYPE: list

self.scale_coords

A list variable containing the xy-coordinates coordinates of the scaling line start- and endpoints to calculate the distance between. The list is emptied each time a new image is scaled.

TYPE: list

self.thick_coords

A list variable containing the xy-coordinates coordinates of the muscle thickness line start- and endpoints to calculate the distance between. The list is emptied each time a new image is scaled. Only the y-coordintes are used for further analysis.

TYPE: list

self.fasc_coords

A list variable containing the xy-coordinates coordinates of the fascicle length line segments start- and endpoints to calculate the total length of the fascicle. The list is emptied each time a new image is analyzed.

TYPE: list

self.pen_coords

A list variable containing the xy-coordinates coordinates of the pennation angle line segments start- and endpoints to calculate the angle of the fascicle. The list is emptied each time a new image is analyzed.

TYPE: list

self.coords

Dictionary variable storing the xy-coordinates of mouse events during analysis. Mouse events are clicking and releasing of the left mouse button as well as dragging of the cursor.

TYPE: dict

self.count

Index of image / video frame currently analysis in the list of image file / video frame paths. The default is 0 as the first image / frame analyzed always has the idex 0 in the list.

TYPE: int, default = 0

self.dataframe

Panadas dataframe that stores the analysis results such as file name, fascicle length, pennation angle and muscle thickness. This dataframe is then saved in an .xlsx file.

TYPE: DataFrame

self.head

tk.Toplevel instance opening a window containing the manual image analysis options.

TYPE: TK

self.mode

tk.Stringvar variable containing the current parameter analysed by the user. The parameters are - muscle thickness : thick - fascicle length : fasc - pennation angle : pen - scaling : scale - aponeurosis drawing : apo The variable is updaten upon selection of the user. The default is muscle thickness.

TYPE: tk.Stringvar, default = thick

self.cavas

tk.Canvas variable representing the canvas the image is plotted on in the GUI. The canvas is used to draw on the image.

TYPE: Canvas

self.img

ImageTk.PhotoImage variable containing the current image that is analyzed. It is necessary to load the image in this way in order to plot the image.

TYPE: PhotoImage

self.dist

Integer variable containing the length of the scaling line in pixel units. This variable is then used to scale the image.

TYPE: int

METHOD DESCRIPTION
__init__

Instance method to initialize the class.

calculateBatchManual

Instance method creating the GUI for manual image analysis.

__init__(img_list, rootpath)

PARAMETER DESCRIPTION
img_list

A list variable containing the absolute paths to all images / video to be analyzed.

TYPE: str

rootpath

Path to root directory where images / videos for the analysis are saved.

TYPE: str

Examples:

>>> man_analysis = ManualAnalysis(
    img_list=["C:/user/Dokuments/images/image1.tif",
    "C:/user/Dokuments/images/image2.tif",
    "C:/user/Dokuments/images/image3.tif"],
    rootpath="C:/user/Dokuments/images")

calculateBatchManual()

Instance method creating a GUI for manual annotation of longitudinal ultrasoud images of human lower limb muscles.

The GUI contains several analysis options for the current image openend. The user is able to switch between analysis of muscle thickness, fascicle length and pennation angle. Moreover, the image can be scaled and the aponeuroses can be extendet to easy fascicle extrapolation. When one image is finished, the GUI updated by clicking "next image". The Results can be saved by clicking "save results". It is possible to save each image seperately. The GUI can be closed by clicking "break analysis" or simply close the window.

Notes

The GUI can be initated from the main DL_Track GUI. It is also possible to initiate the ManualAnalis class from the command promt and interact with its GUI as a standalone. To do so, the lines 231 (self.head = tk.Tk()) and 314 (self.head.mainloop()) must be uncommented and the line 233 (self.head = tk.Toplevel()) must be commented.

calculateFascicles(fasc_list)

Instance method to calculate muscle fascicle legth as a sum of three annotated segments.

The length of three line segment is calculated by summing their individual length. Here, the length of a single annotated fascicle is calculated considering the three drawn segments of the respective fascicle. The euclidean distance between the start and endpoint of each segment is calculated and summed. Then the length of the fascicle is outputted in pixel units.

PARAMETER DESCRIPTION
fasc_list

List variable containing the xy-coordinates of the first mouse click event and the mouse release event of each annotated fascicle segment.

TYPE: list

RETURNS DESCRIPTION
fascicles

List variable containing the fascicle length in pixel units. This value is calculated by summing the euclidean distance of each drawn fascicle segment. If multiple fascicles are drawn, multiple fascicle length values are outputted.

TYPE: list

Examples:

>>> calculateFascicles(fasc_list=[[392.0, 622.0], [632.0, 544.0],
                                  [632.0, 544.0],
                                  [1090.0, 415.0], [1090.0, 415.0],
                                  [1274.0, 381.0],
                                  [449.0, 627.0], [748.0, 541.0],
                                  [748.0, 541.0],
                                  [1109.0, 429.0], [1109.0, 429.0],
                                  [1297.0, 390.0]])
[915.2921723246823, 881.0996335404545]

calculatePennation(pen_list)

Instance method to calculate muscle pennation angle between three points.

The angle between three points is calculated using the arc tangent. Here, the points used for calculation are the start and endpoint of the line segment drawn alongside the fascicle as well as the endpoint of the segment drawn along the aponeurosis. The pennation angle is outputted in degrees.

PARAMETER DESCRIPTION
pen_list

List variable containing the xy-coordinates of the first mouse click event and the mouse release event of each annotated pennation angle segment.

TYPE: list

RETURNS DESCRIPTION
pen_angles

List variable containing the pennation angle in degrees. If multiple pennation angles are drawn, multiple angle values are outputted.

TYPE: list

See Also

self.getAngle()

Examples:

>>> calculateFascicles(pen_list=[[760.0, 579.0], [620.0, 629.0],
                                 [620.0, 629.0],
                                 [780.0, 631.0], [533.0, 571.0],
                                 [378.0, 627.0], [378.0, 627.0],
                                 [558.0, 631.0]] )
[20.369984003523715, 21.137327423466722]

calculateThickness(thick_list)

Instance method to calculate distance between deep and superficial muscle aponeuroses, also known as muscle thickness.

The length of the segment is calculated by determining the absolute distance of the y-coordinates of two points. Here, the muscle thickness is calculated considering only the y-coordinates of the start and end points of the drawn segments. In this way, incorrect placement of the segments by drawing skewed lines can be accounted for. Then the thickness is outputted in pixel units.

PARAMETER DESCRIPTION
thick_list

List variable containing the xy-coordinates of the first mouse click event and the mouse release event of the muscle thickness annotation. This must be the points at the beginning and end of the thickness segment.

TYPE: list

RETURNS DESCRIPTION
thickness

List variable containing the muscle thickness in pixel units. This value is calculated using only the difference of the y-coordinates of the two points. If multiple segments are drawn, multiple thickness values are outputted.

TYPE: list

Examples:

>>> calculateThickness(thick_list=[[450, 41.0], [459, 200]])
[159]

click(event)

Instance method to record mouse clicks on canvas.

When the left mouse button is clicked on the canvas, the xy-coordinates are stored for further analysis. When the button is clicked multiple times, multiple values are stored.

PARAMETER DESCRIPTION
event

tk.Event variable containing the mouse event that is bound to the instance method.

TYPE: str

Examples:

>>> self.canvas.bind("<ButtonPress-1>", self.click)

closeWindow()

Instance method to close window upon call.

This method is evoked by clicking the button "Break Analysis". It is necessary to use a different function, otherwise the window would be destroyed upon starting.

compileSaveResults()

Instance method to save the analysis results.

A pd.DataFrame object must be used. The results inculded in the dataframe are saved to an .xlsx file. Depending on the form of class initialization, the .xlsx file is either saved to self.root (GUI) or self.out (command prompt).

Notes

An .xlsx file is saved to a specified location containing all analysis results.

drag(event)

Instance method to record mouse cursor dragging on canvas.

When the cursor is dragged on the canvas, the xy-coordinates are stored and updated for further analysis. This is used to draw the line that follows the cursor on the screen. Coordinates are only recorded when the left mouse button is pressed.

PARAMETER DESCRIPTION
event

tk.Event variable containing the mouse event that is bound to the instance method.

TYPE: str

Examples:

>>> self.canvas.bind("<B1-Motion>", self.click)

getAngle(a, b, c)

Instance method to calculate angle between three points.

The angle is calculated using the arc tangent. The arc tangent is used to find the slope in radians when Y and X co-ordinates are given. The output is the arc tangent of y/x in radians, which is between PI and -PI. Then the output is converted to degrees.

PARAMETER DESCRIPTION
a

List variable containing the xy-coordinates of the first mouse click event of the pennation angle annotation. This must be the point at the beginning of the fascicle segment.

TYPE: list

b

List variable containing the xy-coordinates of the second mouse click event of the pennation angle annotation. This must be the point at the intersection between fascicle and aponeurosis.

TYPE: list

c

List variable containing the xy-coordinates of the fourth mouse event of the pennation angle annotation. This must be the endpoint of the aponeurosis segment.

TYPE: list

RETURNS DESCRIPTION
ang

Float variable containing the pennation angle in degrees between the segments drawn on the canvas by the user. Only the angle smaller than 180 degrees is returned.

TYPE: float

Examples:

>>> getAngle(a=[904.0, 41.0], b=[450,380], c=[670,385])
25.6

release(event)

Instance method to record mouse button releases on canvas.

When the left mouse button is released on the canvas, the xy-coordinates are stored for further analysis. When the button is released multiple times, multiple values are stored.

PARAMETER DESCRIPTION
event

tk.Event variable containing the mouse event that is bound to the instance method.

TYPE: str

Examples:

>>> self.canvas.bind("<ButtonRelease-1>", self.click)

saveResults()

Instance Method to save the analysis results to a pd.DataFrame.

A list of each variable to be saved must be used. The list must contain the coordinates of the recorded events during parameter analysis. Then, the respective parameters are calculated using the coordinates in each list and inculded in a dataframe. Estimates or fascicle length, pennation angle, muscle thickness are saved.

Notes

In order to correctly calculate the muscle parameters, the amount of coordinates must be specific. See class documentatio of documentation of functions used to calculate parameters.

See Also

self.calculateThickness, self.calculateFascicle, self.calculatePennation

setAngles()

Instance method to display the instructions for pennation angle analysis.

This function is bound to the "Pennation Angle" radiobutton and appears each time the button is selected. In this way, the user is reminded on how to analyze pennation angle.

setApo()

Instance method to display the instructions for aponeuroses extending.

This function is bound to the "Draw Aponeurosis" radiobutton and appears each time the button is selected. In this way, the user is reminded on how to draw aponeurosis extension on the image.

setFascicles()

Instance method to display the instructions for muscle fascicle analysis.

This function is bound to the "Muscle Fascicles" radiobutton and appears each time the button is selected. In this way, the user is reminded on how to analyze muscle fascicles.

setScale()

Instance method to display the instructions for image scaling.

This function is bound to the "Scale Image" radiobutton and appears each time the button is selected. In this way, the user is reminded on how to scale the image.

setThickness()

Instance method to display the instructions for muscle thickness analysis.

This function is bound to the "Muscle Thickness" radiobutton and appears each time the button is selected. In this way, the user is reminded on how to analyze muscle thickness.

stopAnalysis()

Instance method to stop the current analysis on the canvas in the GUI.

The analysis is stopped upon clicking of "Break Analysis" button in the GUI. The current analysis results are saved when the analysis is terminated. The analysis can be terminated at any timepoint during manual annotation. Prior to terminating, the user is asked for confirmation.

updateImage()

Instance method to update the current image displayed on the canvas in the GUI.

The image is updated upon clicking of "Next Image" button in the GUI. Images can be updated until all images have been analyzed. Even when the image is updated, the analysis results are stored.