diff --git a/UltrasoundSegmentation/test_extract_scanlines.ipynb b/UltrasoundSegmentation/test_extract_scanlines.ipynb new file mode 100644 index 0000000..38449be --- /dev/null +++ b/UltrasoundSegmentation/test_extract_scanlines.ipynb @@ -0,0 +1,223 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "input_folder = r\"i:\\SpineUs\\2024_Segmentation\\03_ScanlinesArrays_2pre\"\n", + "\n", + "num_sample_scans = 4\n", + "num_sample_frames = 3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Check files in the input_folder. Filenames follow this pattern: \"PatientID_Orientation_Type.npy\"\n", + "# PatientID is a string of numerical digits of arbitrary length\n", + "# ScanID is a string, e.g., \"Ax\", \"Sa\", \"SaL\", \"SaT\", \"Sa-LU\", etc.\n", + "# Type is a string that can only have the following values: \"segmentation\", \"transform\", or \"ultrasound\"\n", + "\n", + "# Count how many unique PatientID ScanID pairs there are in the input_folder that have all four types of files\n", + "\n", + "import os\n", + "import re\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "# Get all files in the input_folder\n", + "files = os.listdir(input_folder)\n", + "\n", + "# Print how many files are in the input_folder in total\n", + "print(f\"Total number of files: {len(files)}\")\n", + "\n", + "# Create a dictionary to store the files\n", + "file_dict = {}\n", + "\n", + "# Loop through all files\n", + "\n", + "for file in files:\n", + " # Extract the PatientID, ScanID, and Type from the filename. Extension can either be npy or npz.\n", + " match = re.match(r\"(\\d+)_([A-Za-z-]+)_(segmentation|transform|ultrasound)\\.(npy|npz)\", file)\n", + " if match:\n", + " PatientID = match.group(1)\n", + " ScanID = match.group(2)\n", + " Type = match.group(3)\n", + " \n", + " # If the PatientID is not in the dictionary, add it\n", + " if PatientID not in file_dict:\n", + " file_dict[PatientID] = {}\n", + " \n", + " # If the Orientation is not in the dictionary, add it\n", + " if ScanID not in file_dict[PatientID]:\n", + " file_dict[PatientID][ScanID] = set()\n", + " \n", + " # Add the Type to the set\n", + " file_dict[PatientID][ScanID].add(Type)\n", + "\n", + "# Count how many unique PatientID ScanID pairs have all four types of files\n", + "count = 0\n", + "for PatientID in file_dict:\n", + " for ScanID in file_dict[PatientID]:\n", + " if len(file_dict[PatientID][ScanID]) == 3:\n", + " count += 1\n", + "\n", + "# Remove all ScanIDs that do not have all four types of files.\n", + "# Remove all PatientIDs that do not have any ScanIDs left.\n", + "count_scans_removed = 0\n", + "for PatientID in list(file_dict.keys()):\n", + " for ScanID in list(file_dict[PatientID].keys()):\n", + " if len(file_dict[PatientID][ScanID]) != 3:\n", + " del file_dict[PatientID][ScanID]\n", + " count_scans_removed += 1\n", + " if len(file_dict[PatientID]) == 0:\n", + " del file_dict[PatientID]\n", + "print(f\"Number of scans removed for missing file types: {count_scans_removed}\")\n", + "\n", + "print(f\"Number of PatientID_Scan pairs with all types of files: {count}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Read the indices, segmentation, transform, and ultrasound files for one of the PatientID_Scan pairs\n", + "PatientID = list(file_dict.keys())[0]\n", + "ScanID = list(file_dict[PatientID].keys())[0]\n", + "segmentation = np.load(os.path.join(input_folder, f\"{PatientID}_{ScanID}_segmentation.npy\"))\n", + "transform = np.load(os.path.join(input_folder, f\"{PatientID}_{ScanID}_transform.npy\"))\n", + "ultrasound = np.load(os.path.join(input_folder, f\"{PatientID}_{ScanID}_ultrasound.npy\"))\n", + "\n", + "print(f\"PatientID: {PatientID}\")\n", + "print(f\"ScanID: {ScanID}\")\n", + "print()\n", + "# Print the shapes of the arrays\n", + "print(f\"transform shape: {transform.shape}\")\n", + "print()\n", + "print(f\"segmentation shape: {segmentation.shape}\")\n", + "print(f\"segmentation dtype: {segmentation.dtype}\")\n", + "print(f\"segmentation min: {segmentation.min()}\")\n", + "print(f\"segmentation max: {segmentation.max()}\")\n", + "print()\n", + "print(f\"ultrasound shape: {ultrasound.shape}\")\n", + "print(f\"ultrasound dtype: {ultrasound.dtype}\")\n", + "print(f\"ultrasound min: {ultrasound.min()}\")\n", + "print(f\"ultrasound max: {ultrasound.max()}\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def display_random_frames(ultrasound, segmentation, num_sample_frames):\n", + " \"\"\"\n", + " Display random frames from ultrasound and segmentation data.\n", + "\n", + " Parameters:\n", + " ultrasound (numpy.ndarray): The ultrasound data with dimensions [frame count, height, width, channels].\n", + " segmentation (numpy.ndarray): The segmentation data with dimensions [frame count, height, width, channels].\n", + " num_sample_frames (int): The number of random frames to display.\n", + " \"\"\"\n", + " # Pick a num_sample_frames random frame numbers between 0 and the frame count\n", + " frame_indices = np.random.choice(ultrasound.shape[0], num_sample_frames, replace=False)\n", + "\n", + " # Determine the number of channels in the ultrasound image\n", + " num_channels = ultrasound.shape[-1]\n", + "\n", + " # Show the ultrasound frames and corresponding segmentations side by side\n", + " fig, axs = plt.subplots(num_sample_frames, num_channels + 2, figsize=(2 * (num_channels + 2), num_sample_frames * 2))\n", + " for i, frame_index in enumerate(frame_indices):\n", + " # Display each channel of the ultrasound frame\n", + " for ch in range(num_channels):\n", + " axs[i, ch].imshow(ultrasound[frame_index, ..., ch], cmap=\"gray\")\n", + " axs[i, ch].set_title(f\"US Frame {frame_index} - Ch {ch}\")\n", + " axs[i, ch].axis(\"off\")\n", + " \n", + " # Display segmentation frame\n", + " axs[i, num_channels].imshow(segmentation[frame_index, ..., 0], cmap=\"gray\")\n", + " axs[i, num_channels].set_title(f\"Seg Frame {frame_index}\")\n", + " axs[i, num_channels].axis(\"off\")\n", + " \n", + " # Create combined image\n", + " combined_image = np.stack([ultrasound[frame_index, ..., 0]]*3, axis=-1) # Copy the first channel of the ultrasound frame three times\n", + " combined_image[..., 2] = np.maximum(combined_image[..., 2], segmentation[frame_index, ..., 0] * 255) # Overlay segmentation in blue\n", + " \n", + " # Display combined image\n", + " axs[i, num_channels + 1].imshow(combined_image)\n", + " axs[i, num_channels + 1].set_title(f\"Combined Frame {frame_index}\")\n", + " axs[i, num_channels + 1].axis(\"off\")\n", + "\n", + " plt.tight_layout()\n", + " plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "display_random_frames(ultrasound, segmentation, 3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Select num_sample_scans random PatientID_Scan pairs and display num_sample_frames random frames from each\n", + "\n", + "# Select num_sample_scans random PatientID_Scan pairs\n", + "random_patient_ids = np.random.choice(list(file_dict.keys()), num_sample_scans, replace=False)\n", + "\n", + "for PatientID in random_patient_ids:\n", + " print(f\"PatientID: {PatientID}\")\n", + " ScanID = np.random.choice(list(file_dict[PatientID].keys()))\n", + " print(f\"ScanID: {ScanID}\")\n", + " segmentation = np.load(os.path.join(input_folder, f\"{PatientID}_{ScanID}_segmentation.npy\"))\n", + " transform = np.load(os.path.join(input_folder, f\"{PatientID}_{ScanID}_transform.npy\"))\n", + " ultrasound = np.load(os.path.join(input_folder, f\"{PatientID}_{ScanID}_ultrasound.npy\"))\n", + " display_random_frames(ultrasound, segmentation, num_sample_frames)\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "pt2", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.18" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}