Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exp 02 time-lapse videos #1

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
2 changes: 2 additions & 0 deletions env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ dependencies:
- pathlib
- imageio
- scikit-learn
- scikit-video
- ffmpeg
- jupyterlab
1,001 changes: 1,001 additions & 0 deletions make_h5s_by_frame_index_arabidopsis_20250225.v002.ipynb

Large diffs are not rendered by default.

1,036 changes: 1,036 additions & 0 deletions make_h5s_by_frame_index_one_frame_per_day_arabidopsis_20250226.v001.ipynb

Large diffs are not rendered by default.

976 changes: 976 additions & 0 deletions make_h5s_by_frame_index_one_frame_per_day_sorghum_20250227.v001.ipynb

Large diffs are not rendered by default.

820 changes: 820 additions & 0 deletions make_h5s_by_frame_index_rice_20250225.v002.ipynb

Large diffs are not rendered by default.

189 changes: 189 additions & 0 deletions make_h5s_by_frame_index_sorghum_20250225.v002.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"import numpy as np\n",
"import h5py\n",
"from pathlib import Path\n",
"import imageio as iio\n",
"import re\n",
"import logging"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# set up logging\n",
"logging.basicConfig(level=logging.INFO)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"def natural_sort(l):\n",
" \"\"\"Sort a list of strings in a way that considers numerical values within the strings.\n",
" \n",
" For example, natural_sort([\"img2.png\", \"img10.png\", \"img1.png\"])\n",
" will return [\"img1.png\", \"img2.png\", \"img10.png\"].\n",
" \n",
" Args:\n",
" l (list): List of strings to sort.\n",
" \n",
" Returns:\n",
" list: List of sorted strings.\n",
" \"\"\"\n",
" l = [x.as_posix() if isinstance(x, Path) else x for x in l]\n",
" convert = lambda text: int(text) if text.isdigit() else text.lower()\n",
" alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]\n",
" return sorted(l, key=alphanum_key)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"base_src_dir = \"H:/users/eberrigan/20250225_Elohim_Bello_Exp02_timelapse_images/Sorghum\" # Adjust to your source directory\n",
"base_dst_dir = \"H:/users/eberrigan/20250225_Elohim_Bello_Exp02_timelapse_images/Sorghum_time_lapse_videos_20250225/h5s_preds_by_frame\" # Adjust to your destination directory\n",
"genotypes = range(1,7) # 1 to 6\n",
"img_numbers = range(1, 73) # 1 to 72\n",
"days = range(1, 17) # 1 to 16\n",
"replicates = range(1, 7) # 1 to 6\n",
"overwrite = False # When overwrite=True existing files are overwritten\n",
"logging.info(f\"genotypes: {genotypes}\")\n",
"logging.info(f\"image numbers: {img_numbers}\")\n",
"logging.info(f\"days: {days}\")"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\Elizabeth\\AppData\\Local\\Temp\\ipykernel_29232\\4202304162.py:55: DeprecationWarning: Starting with ImageIO v3 the behavior of this function will switch to that of iio.v3.imread. To keep the current behavior (and make this warning disappear) use `import imageio.v2 as imageio` or call `imageio.v2.imread` directly.\n",
" img = iio.imread(img_path)\n"
]
}
],
"source": [
"# This dataset is organized as genotype -> replicate -> timepoint -> image\n",
"# genotypes are numbered 1 to 6\n",
"# replicates are numbered 1 to 6\n",
"# timepoints are numbered 1 to 16\n",
"# images are numbered 1 to 72\n",
"\n",
"base_src_dir = Path(base_src_dir)\n",
"base_dst_dir = Path(base_dst_dir)\n",
"\n",
"# Create the destination directory if it doesn't exist\n",
"base_dst_dir.mkdir(parents=True, exist_ok=True)\n",
"logging.info(f\"Destination directory: {base_dst_dir}\")\n",
"\n",
"# Iterate over genotypes and replicates\n",
"for genotype in genotypes:\n",
" for replicate in replicates:\n",
" h5_name = base_dst_dir / f\"g{genotype}_r{replicate}.h5\"\n",
" logging.info(f\"\\nProcessing genotype {genotype}, replicate {replicate}\")\n",
"\n",
" if not overwrite and h5_name.exists():\n",
" logging.info(f\"Skipping {h5_name} as it already exists and overwrite is False.\")\n",
" continue\n",
"\n",
" images = []\n",
"\n",
" # Iterate over days\n",
" for day in days:\n",
" day_dir = base_src_dir / str(genotype) / str(replicate) / str(day)\n",
" logging.info(f\"Day directory: {day_dir}\")\n",
" if not day_dir.exists():\n",
" continue\n",
" \n",
" # Collect image paths for the current day\n",
" day_images = []\n",
" missing_images = False\n",
" for img_number in img_numbers:\n",
" img_path = day_dir / f\"{img_number}.png\"\n",
" if img_path.exists():\n",
" day_images.append(img_path)\n",
" else:\n",
" logging.warning(f\"Missing image: {img_path}\")\n",
" missing_images = True\n",
"\n",
" # Skip this day if any images are missing\n",
" if missing_images:\n",
" logging.warning(f\"Skipping day {day} for genotype {genotype}, replicate {replicate} due to missing images.\")\n",
" continue\n",
" \n",
" # Sort the images for the current day\n",
" day_images = natural_sort(day_images)\n",
" \n",
" # Read and append images to the list\n",
" for img_path in day_images:\n",
" try:\n",
" img = iio.imread(img_path)\n",
" images.append(img)\n",
" except Exception as e:\n",
" logging.error(f\"Error reading {img_path}: {e}\")\n",
" continue\n",
"\n",
" if images:\n",
" try:\n",
" vol = np.stack(images, axis=0) # Stack images to create a volume (slices, height, width)\n",
"\n",
" # Save as h5\n",
" with h5py.File(h5_name, \"w\") as f:\n",
" f.create_dataset(\n",
" \"vol\",\n",
" data=np.expand_dims(vol, axis=-1), # Add channel dimension\n",
" compression=\"gzip\", # Using gzip compression\n",
" compression_opts=1 # Higher compression level\n",
" )\n",
" logging.info(f\"Time-lapse video for genotype {genotype}, replicate {replicate} saved successfully as {h5_name}.\")\n",
" except ValueError as e:\n",
" logging.error(f\"Error stacking images for {h5_name}: {e}\")\n",
" else:\n",
" logging.info(f\"No images found for genotype {genotype}, replicate {replicate}. Skipping.\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "time_lapse_videos",
"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.11.11"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Loading