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:
|
contour
|
List variable containing sorted contours.
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
x
|
Array variable containing all x-coordinates from the detected contour.
TYPE:
|
y
|
Array variable containing all y-coordinated from the detected contour.
TYPE:
|
Examples:
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
|
TYPE:
|
img_copy
|
A copy of the input image.
TYPE:
|
h
|
Integer variable containing the height of the input image (img).
TYPE:
|
w
|
Integer variable containing the width of the input image (img).
TYPE:
|
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:
|
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:
|
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:
|
filter_fasc
|
If True, fascicles will be filtered so that no crossings are included. This may reduce number of totally detected fascicles.
TYPE:
|
image_callback
|
Callback function to update the image display. If None, no callback is used.
DEFAULT:
|
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:
|
pennation
|
List variable containing the estimated pennation angles based on the segmented fascicle fragments and aponeuroses as float.
TYPE:
|
x_low1
|
List variable containing the estimated x-coordinates of the lower edge from the upper aponeurosis as integers.
TYPE:
|
x_high1
|
List variable containing the estimated x-coordinates of the upper edge from the lower aponeurosis as integers.
TYPE:
|
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:
|
fig
|
Figure including the input image, the segmented aponeurosis and the extrapolated fascicles.
TYPE:
|
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:
|
RETURNS | DESCRIPTION |
---|---|
DataFrame
|
A DataFrame with the fascicles that do not intersect with their neighbors. |
Examples:
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:
|
RETURNS | DESCRIPTION |
---|---|
cnts
|
Tuple containing arrays of sorted contours.
TYPE:
|
bounding_boxes
|
Tuple containing tuples with sorted bounding boxes.
TYPE:
|
Examples:
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:
|
contour
|
List variable containing sorted contours.
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
x
|
Array variable containing all x-coordinates from the detected contour.
TYPE:
|
y
|
Array variable containing all y-coordinated from the detected contour.
TYPE:
|
Examples:
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:
|
tolerance
|
Tolerance to allow intersection points near the aponeuroses
TYPE:
|
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:
|
contour
|
List variable containing sorted contours.
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
x
|
Array variable containing all x-coordinates from the detected contour.
TYPE:
|
y
|
Array variable containing all y-coordinated from the detected contour.
TYPE:
|
Examples:
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:
|
image_fas
|
Binary image of the fascicles within the original image
TYPE:
|
image_apo
|
Binary image of the aponeuroses within the original image
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
cropped_US
|
Image of the original ultrasound image without frame around it
TYPE:
|
cropped_fas
|
Cropped binary image of fascicles within the original image
TYPE:
|
cropped_apo
|
Cropped binary image of the aponeuroses within the original image
TYPE:
|
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:
|
ex_x_LA
|
List containing all x-values of the extrapolated lower aponeurosis
TYPE:
|
ex_y_LA
|
List containing all y-values of the extrapolated lower aponeurosis
TYPE:
|
ex_x_UA
|
List containing all x-values of the extrapolated upper aponeurosis
TYPE:
|
ex_y_UA
|
List containing all y-values of the extrapolated upper aponeurosis
TYPE:
|
original_image
|
Ultrasound image to be analysed
TYPE:
|
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:
|
filter_fasc
|
If True, fascicles will be filtered so that no crossings are included. This may reduce number of totally detected fascicles.
TYPE:
|
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:
|
RETURNS | DESCRIPTION |
---|---|
data
|
Dictionary containing the fascicle length and pennation angle for each fascicle.
TYPE:
|
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:
|
img_copy
|
A copy of the input image.
TYPE:
|
h
|
Integer variable containing the height of the input image (original image).
TYPE:
|
w
|
Integer variable containing the width of the input image (original image).
TYPE:
|
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:
|
filter_fasc
|
If True, fascicles will be filtered so that no crossings are included. This may reduce number of totally detected fascicles.
TYPE:
|
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:
|
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:
|
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:
|
image_callback
|
Callback function for displaying the image. If None, no image is displayed.
DEFAULT:
|
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:
|
pennation_angle
|
List variable containing the estimated pennation angles based on the segmented fascicle fragments and aponeuroses as float.
TYPE:
|
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:
|
x_low
|
List variable containing the intersection points between the fascicles and the lower aponeurosis
TYPE:
|
x_high
|
List variable containing the intersection points between the fascicles and the upper aponeurosis
TYPE:
|
fig
|
Figure including the input ultrasound image, the segmented aponeuroses and the found fascicles extrapolated between the two aponeuroses.
TYPE:
|
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:
|
curve2
|
List containing (x,y) coordinate pairs representing a second curve
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
Bool
|
'True' if the curves have an intersection point 'False' if the curves don't have an intersection point |
Examples:
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:
|
contours_sorted_x
|
List containing all x-coordinates of each detected contour
TYPE:
|
contours_sorted_y
|
List containing all y-coordinates of each detected contour
TYPE:
|
contours_sorted
|
List containing all (x,y)-coordinates of each detected contour
TYPE:
|
label
|
Dictionnary containing a label true or false for every fascicle contour, true if already used for an extrapolation, false if not
TYPE:
|
mid
|
Integer value defining the middle of the image
TYPE:
|
width
|
Integer value defining the width of the image
TYPE:
|
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:
|
coeff_limit
|
Value defining the maximum value of the first coefficient in the second polynomial fit
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
ex_current_fascicle_x
|
List containing the x-coordinates of each found and extrapolated fascicle
TYPE:
|
ex_current_fascicle_y
|
List containing the y-coordinates of each found and extrapolated fascicle
TYPE:
|
linear_fit
|
'True' if extrapolated fit is linear 'False' if extrapolated fit follows a second order polynomial
TYPE:
|
inner_number_contours
|
List containing the indices of each contour that constitute each fascicle
TYPE:
|
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:
|
contours_sorted_x
|
List of arrays containing the x-coordinates of each contour segment.
TYPE:
|
contours_sorted_y
|
List of arrays containing the y-coordinates of each contour segment.
TYPE:
|
contours_sorted
|
List of full contour arrays (used for proximity checking).
TYPE:
|
label
|
Dictionary mapping contour indices to a boolean indicating whether they have already been used. Will be updated in-place.
TYPE:
|
mid
|
Midpoint x-coordinate used as center of extrapolation range.
TYPE:
|
width
|
Half-width of the extrapolation span in pixels (from
TYPE:
|
tolerance
|
Vertical distance in pixels allowed between the extrapolated line and candidate contour segments.
TYPE:
|
coeff_limit
|
Currently unused; placeholder for limiting slope or intercept values during fitting.
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
ex_current_fascicle_x
|
Extrapolated x-coordinates of the complete fascicle.
TYPE:
|
ex_current_fascicle_y
|
Corresponding y-coordinates from the final linear model fit.
TYPE:
|
linear_fit
|
Flag indicating whether a linear fit was successfully computed (always
TYPE:
|
inner_number_contours
|
List of contour indices that belong to the detected fascicle.
TYPE:
|
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:
|
contours_sorted_x
|
List containing all x-coordinates of each detected contour
TYPE:
|
contours_sorted_y
|
List containing all y-coordinates of each detected contour
TYPE:
|
x_current_fascicle
|
List containing the x-coordinates of the currently examined fascicle
TYPE:
|
y_current_fascicle
|
List containing the y-coordinates of the currently examined fascicle
TYPE:
|
x_range
|
List containing all x-coordinates within the range of the extrapolation
TYPE:
|
upper_bound
|
List containing all y-coordinates of the lower boundary
TYPE:
|
lower_bound
|
List containing all y-coordinates of the upper boundary
TYPE:
|
label
|
Dictionnary containing a label true or false for every fascicle contour, true if already used for an extrapolation, false if not
TYPE:
|
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:
|
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:
|
found_fascicle
|
Integer value of the found fascicle contour, -1 if no contour was found
TYPE:
|
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:
|
y_point
|
Single integer variable representing the y-coordinate of the point to be analyzed
TYPE:
|
x_poly
|
List containing all x-coordinates of the range where the point could be located
TYPE:
|
lb
|
List containing all y-coordinates of the lower boundary
TYPE:
|
ub
|
List containing all y-coordinates of the upper boundary
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
Bool
|
'True' if point is within both boundaries 'False' if point is outside the boundaries |
Examples:
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:
|
apo_image
|
Mask of aponeuroses
TYPE:
|
g
|
Containing coefficients to calculate second order polynomial fit for upper aponeurosis
TYPE:
|
h
|
Containing coefficients to calculate second order polynomial fit for lower aponeurosis
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
split_angles_deg_median
|
List variable containing the estimated pennation angles for the six parts of the image
TYPE:
|
fig
|
Figure showing the estimated slope at different points in the region between the two aponeuroses as a heat map
TYPE:
|
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:
|
RETURNS | DESCRIPTION |
---|---|
cnts
|
Tuple containing arrays of sorted contours.
TYPE:
|
bounding_boxes
|
Tuple containing tuples with sorted bounding boxes.
TYPE:
|
Examples:
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:
|
cap
|
Object that contains the video in a np.ndarrray format. In this way, seperate frames can be accessed.
TYPE:
|
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:
|
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:
|
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:
|
dic
|
Dictionary variable containing analysis parameters. These include must include apo_threshold, fasc_threshold, fasc_cont_threshold, min_width, max_pennation, min_pennation.
TYPE:
|
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:
|
filter_fasc
|
If True, fascicles will be filtered so that no crossings are included. This may reduce number of totally detected fascicles.
TYPE:
|
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:
|
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:
|
frame_callback
|
Boolean variable determining whether the current frame is displayed in main UI.
TYPE:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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
TYPE:
|
new_Y_UA
|
Y-values of the extrapolated upper aponeurosis curve (from polynomial fit).
TYPE:
|
new_Y_LA
|
Y-values of the extrapolated lower aponeurosis curve (from polynomial fit).
TYPE:
|
new_X_UA
|
X-values corresponding to
TYPE:
|
new_X_LA
|
X-values corresponding to
TYPE:
|
width
|
Image width, used to define extrapolation range.
TYPE:
|
min_pennation
|
Minimum allowable pennation angle for valid fascicle inclusion (in degrees).
TYPE:
|
max_pennation
|
Maximum allowable pennation angle for valid fascicle inclusion (in degrees).
TYPE:
|
filter_fascicles_func
|
Optional function to apply filtering to remove overlapping or invalid fascicles.
Should accept and return a
TYPE:
|
fasc_cont_thresh
|
Minimum number of contour points to consider a fascicle candidate.
TYPE:
|
calib_dist
|
Calibration distance in pixels between two 10 mm markers. If given, fascicle lengths are scaled to mm.
TYPE:
|
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:
|
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:
|
contour
|
List variable containing sorted contours.
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
x
|
Array variable containing all x-coordinates from the detected contour.
TYPE:
|
y
|
Array variable containing all y-coordinated from the detected contour.
TYPE:
|
Examples:
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:
|
tolerance
|
Tolerance to allow intersection points near the aponeuroses
TYPE:
|
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:
|
contour
|
List variable containing sorted contours.
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
x
|
Array variable containing all x-coordinates from the detected contour.
TYPE:
|
y
|
Array variable containing all y-coordinated from the detected contour.
TYPE:
|
Examples:
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:
|
image_fas
|
Binary image of the fascicles within the original image
TYPE:
|
image_apo
|
Binary image of the aponeuroses within the original image
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
cropped_US
|
Image of the original ultrasound image without frame around it
TYPE:
|
cropped_fas
|
Cropped binary image of fascicles within the original image
TYPE:
|
cropped_apo
|
Cropped binary image of the aponeuroses within the original image
TYPE:
|
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:
|
curve2
|
List containing (x,y) coordinate pairs representing a second curve
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
Bool
|
'True' if the curves have an intersection point 'False' if the curves don't have an intersection point |
Examples:
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:
|
contours_sorted_x
|
List containing all x-coordinates of each detected contour
TYPE:
|
contours_sorted_y
|
List containing all y-coordinates of each detected contour
TYPE:
|
contours_sorted
|
List containing all (x,y)-coordinates of each detected contour
TYPE:
|
label
|
Dictionnary containing a label true or false for every fascicle contour, true if already used for an extrapolation, false if not
TYPE:
|
mid
|
Integer value defining the middle of the image
TYPE:
|
width
|
Integer value defining the width of the image
TYPE:
|
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:
|
coeff_limit
|
Value defining the maximum value of the first coefficient in the second polynomial fit
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
ex_current_fascicle_x
|
List containing the x-coordinates of each found and extrapolated fascicle
TYPE:
|
ex_current_fascicle_y
|
List containing the y-coordinates of each found and extrapolated fascicle
TYPE:
|
linear_fit
|
'True' if extrapolated fit is linear 'False' if extrapolated fit follows a second order polynomial
TYPE:
|
inner_number_contours
|
List containing the indices of each contour that constitute each fascicle
TYPE:
|
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:
|
contours_sorted_x
|
List of arrays containing the x-coordinates of each contour segment.
TYPE:
|
contours_sorted_y
|
List of arrays containing the y-coordinates of each contour segment.
TYPE:
|
contours_sorted
|
List of full contour arrays (used for proximity checking).
TYPE:
|
label
|
Dictionary mapping contour indices to a boolean indicating whether they have already been used. Will be updated in-place.
TYPE:
|
mid
|
Midpoint x-coordinate used as center of extrapolation range.
TYPE:
|
width
|
Half-width of the extrapolation span in pixels (from
TYPE:
|
tolerance
|
Vertical distance in pixels allowed between the extrapolated line and candidate contour segments.
TYPE:
|
coeff_limit
|
Currently unused; placeholder for limiting slope or intercept values during fitting.
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
ex_current_fascicle_x
|
Extrapolated x-coordinates of the complete fascicle.
TYPE:
|
ex_current_fascicle_y
|
Corresponding y-coordinates from the final linear model fit.
TYPE:
|
linear_fit
|
Flag indicating whether a linear fit was successfully computed (always
TYPE:
|
inner_number_contours
|
List of contour indices that belong to the detected fascicle.
TYPE:
|
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:
|
contours_sorted_x
|
List containing all x-coordinates of each detected contour
TYPE:
|
contours_sorted_y
|
List containing all y-coordinates of each detected contour
TYPE:
|
x_current_fascicle
|
List containing the x-coordinates of the currently examined fascicle
TYPE:
|
y_current_fascicle
|
List containing the y-coordinates of the currently examined fascicle
TYPE:
|
x_range
|
List containing all x-coordinates within the range of the extrapolation
TYPE:
|
upper_bound
|
List containing all y-coordinates of the lower boundary
TYPE:
|
lower_bound
|
List containing all y-coordinates of the upper boundary
TYPE:
|
label
|
Dictionnary containing a label true or false for every fascicle contour, true if already used for an extrapolation, false if not
TYPE:
|
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:
|
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:
|
found_fascicle
|
Integer value of the found fascicle contour, -1 if no contour was found
TYPE:
|
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:
|
y_point
|
Single integer variable representing the y-coordinate of the point to be analyzed
TYPE:
|
x_poly
|
List containing all x-coordinates of the range where the point could be located
TYPE:
|
lb
|
List containing all y-coordinates of the lower boundary
TYPE:
|
ub
|
List containing all y-coordinates of the upper boundary
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
Bool
|
'True' if point is within both boundaries 'False' if point is outside the boundaries |
Examples:
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:
|
RETURNS | DESCRIPTION |
---|---|
cnts
|
Tuple containing arrays of sorted contours.
TYPE:
|
bounding_boxes
|
Tuple containing tuples with sorted bounding boxes.
TYPE:
|
Examples:
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:
|
filter_type
|
The type of filter to apply. Options are "median", "gaussian", "savitzky_golay".
TYPE:
|
kwargs
|
Additional parameters for the selected filter.
TYPE:
|
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:
|
win_size
|
Window size for rolling median filtering. Default is 5.
TYPE:
|
num_dev
|
Number of standard deviations for outlier detection. Default is 1.
TYPE:
|
center_win
|
Whether the window is centered on the point. Default is True.
TYPE:
|
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:
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:
|
apo_modelpath
|
String variable containing the absolute path to the aponeurosis neural network.
TYPE:
|
fasc_modelpath
|
String variable containing the absolute path to the fascicle neural network.
TYPE:
|
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:
|
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:
|
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:
|
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:
|
filter_fasc
|
If True, fascicles will be filtered so that no crossings are included. This may reduce number of totally detected fascicles.
TYPE:
|
settings
|
Dictionary containing the analysis settings of the GUI.
TYPE:
|
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:
|
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:
|
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:
|
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:
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:
|
filename
|
Name of the Excel file.
TYPE:
|
fasc_l_all
|
Raw fascicle length data.
TYPE:
|
pennation_all
|
Raw pennation angle data.
TYPE:
|
x_lows_all
|
X-coordinates of lower aponeurosis intersections.
TYPE:
|
x_highs_all
|
X-coordinates of upper aponeurosis intersections.
TYPE:
|
thickness_all
|
Muscle thickness measurements.
TYPE:
|
filtered_fasc
|
Filtered fascicle length data.
TYPE:
|
filtered_pennation
|
Filtered pennation angle data.
TYPE:
|
analysis_mode
|
Analysis mode used for the calculations. If "video", savgol filter will be appiled.
TYPE:
|
image_filenames
|
List of image filenames corresponding to the analysis results.
TYPE:
|
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:
|
gui
|
The GUI object.
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
flip_flags
|
A list variable containing all flip flags included in the specified .txt file
TYPE:
|
Examples:
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:
|
flip
|
Integer value defining wheter an image should be flipped. This can be 0 (image is not flipped) or 1 (image is flipped).
TYPE:
|
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:
|
img_copy
|
A copy of the input image.
TYPE:
|
non_flipped_img
|
A copy of the input image. This copy is made prior to image flipping.
TYPE:
|
height
|
Integer value containing the image height of the input image.
TYPE:
|
width
|
Integer value containing the image width of the input image.
TYPE:
|
filename
|
String value containing the name of the input image, not the entire path.
TYPE:
|
Examples:
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:
|
flip
|
Integer value defining wheter an image should be flipped. This can be 0 (image is not flipped) or 1 (image is flipped).
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
img
|
The loaded images as a np.nadarray in grayscale.
TYPE:
|
filename
|
String value containing the name of the input image, not the entire path.
TYPE:
|
Examples:
preprocess_function(image)
¶
Function to preprocess an image.
PARAMETER | DESCRIPTION |
---|---|
image
|
Image to be preprocessed.
TYPE:
|
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:
|
apo_modelpath
|
String variable containing the absolute path to the aponeurosis neural network.
TYPE:
|
fasc_modelpath
|
String variable containing the absolute path to the fascicle neural network.
TYPE:
|
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:
|
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:
|
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:
|
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:
|
filter_fasc
|
If True, fascicles will be filtered so that no crossings are included. This may reduce number of totally detected fascicles.
TYPE:
|
settings
|
Dictionary containing the settings of the GUI. These specify the prediction parameters for the neural networks.
TYPE:
|
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:
|
display_frame
|
Boolean variable determining whether the current frame is displayed in main UI.
TYPE:
|
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:
|
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:
|
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:
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:
|
RETURNS | DESCRIPTION |
---|---|
cap
|
Object that contains the video in a np.ndarrray format. In this way, seperate frames can be accessed.
TYPE:
|
vid_len
|
Integer variable containing the number of frames present in cap.
TYPE:
|
width
|
Integer variable containing the image width of the input image.
TYPE:
|
filename
|
String variable containing the name of the input video, not the entire path.
TYPE:
|
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:
|
Examples:
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:
|
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:
|
vid_width
|
Integer value containing the image width of the input video.
TYPE:
|
vid_height
|
Integer value containing the image height of the input video.
TYPE:
|
width
|
Integer value containing the image width of the input image.
TYPE:
|
filename
|
String value containing the name of the input video, not the entire path.
TYPE:
|
Examples:
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:
|
spacing
|
Integer variable containing the known distance in milimeter between the two scaling bars. This can be 5, 10, 15 or 20 milimeter.
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
calib_dist
|
Integer variable containing the distance between the two specified point in pixel units.
TYPE:
|
scale_statement
|
String variable containing a statement how many milimeter correspond to how many pixels.
TYPE:
|
Examples:
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:
|
self.rootpath |
Path to root directory where images / videos for the analysis are saved.
TYPE:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
self.head |
tk.Toplevel instance opening a window containing the manual image analysis options.
TYPE:
|
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:
|
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:
|
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:
|
self.dist |
Integer variable containing the length of the scaling line in pixel units. This variable is then used to scale the image.
TYPE:
|
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:
|
rootpath
|
Path to root directory where images / videos for the analysis are saved.
TYPE:
|
Examples:
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:
|
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:
|
Examples:
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:
|
RETURNS | DESCRIPTION |
---|---|
pen_angles
|
List variable containing the pennation angle in degrees. If multiple pennation angles are drawn, multiple angle values are outputted.
TYPE:
|
See Also
self.getAngle()
Examples:
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:
|
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:
|
Examples:
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:
|
Examples:
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:
|
Examples:
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:
|
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:
|
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:
|
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:
|
Examples:
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:
|
Examples:
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.