{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":112509,"databundleVersionId":14254895,"sourceType":"competition"}],"dockerImageVersionId":31153,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"Published on October 28, 2025. By Prata, Marília (mpwolke)","metadata":{}},{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-10-29T00:32:28.659382Z","iopub.execute_input":"2025-10-29T00:32:28.659660Z","iopub.status.idle":"2025-10-29T00:32:28.672805Z","shell.execute_reply.started":"2025-10-29T00:32:28.659638Z","shell.execute_reply":"2025-10-29T00:32:28.671516Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"_kg_hide-input":true,"_kg_hide-output":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Biomass from Top-View Images - task of pasture biomass estimation\n\n\" Accurate estimation of pasture biomass is important for decision-making in livestock production\n systems. Estimates of pasture biomass can be used to manage stocking rates to maximise pasture\n utilisation, while minimising the risk of overgrazing and promoting overall system health. The authors presented a comprehensive dataset of 1,162 annotated top-view images of pastures collected across 19 locations in Australia. The images were taken across multiple seasons and include a range of temperate pasture species.\"\n \n\"Each image is paired with on-ground measurements including biomass sorted by component (green, dead, and legume fraction), vegetation height, and Normalized Difference Vegetation Index (NDVI) from Active Optical Sensors (AOS). The multidimensional nature of the data, which combines visual, spectral, and structural information.\"\n\n\"Reflecting real-world complexity, the dataset presents technical challenges such as extreme biomass **density variation, occlusion in dense canopies, and complex spatial patterns in mixed species** swards. While comprehensive in scope, limitations include a geographic focus on Australian temperate systems, an emphasis on six major pasture species, and a fixed quadrat size, which may not capture broader landscape-scale patterns.\" \n\n**Citation:**\n\n@misc{liao2025estimatingpasturebiomasstopview,\n\n      title={Estimating Pasture Biomass from Top-View Images: A Dataset for Precision Agriculture},\n\n      author={Qiyu Liao and Dadong Wang and Rebecca Haling and Jiajun Liu and Xun Li and Martyna Plomecka and Andrew Robson and Matthew Pringle and Rhys Pirie and Megan Walker and Joshua Whelan},\n\n      year={2025},\n\n      eprint={2510.22916},\n\n      archivePrefix={arXiv},\n\n      primaryClass={cs.CV},\n\n      url={https://arxiv.org/abs/2510.22916},\n\n}\n\nhttps://arxiv.org/pdf/2510.22916","metadata":{}},{"cell_type":"markdown","source":"## Load submission file","metadata":{}},{"cell_type":"code","source":"sub = pd.read_csv('/kaggle/input/csiro-biomass/sample_submission.csv')\nsub.tail()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-29T00:35:32.606790Z","iopub.execute_input":"2025-10-29T00:35:32.607100Z","iopub.status.idle":"2025-10-29T00:35:32.650595Z","shell.execute_reply.started":"2025-10-29T00:35:32.607079Z","shell.execute_reply":"2025-10-29T00:35:32.649637Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Test images (only one image)","metadata":{}},{"cell_type":"code","source":"from PIL import Image\n\nimgs_dir = '../input/csiro-biomass/test/'\nImage.open(imgs_dir + 'ID1001187975.jpg')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-29T00:36:04.200501Z","iopub.execute_input":"2025-10-29T00:36:04.200852Z","iopub.status.idle":"2025-10-29T00:36:04.945923Z","shell.execute_reply.started":"2025-10-29T00:36:04.200827Z","shell.execute_reply":"2025-10-29T00:36:04.944892Z"},"_kg_hide-input":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## About Competition\n\n\"This competition challenges you to bring greener solutions to the field: build a model that predicts pasture biomass from images, ground-truth measures, and publicly available datasets. You’ll work with a professionally annotated dataset covering Australian pastures across different seasons, regions, and species mixes, along with NDVI values to enhance your models.\"\n\nhttps://www.kaggle.com/competitions/csiro-biomass","metadata":{}},{"cell_type":"code","source":"import cv2\nimport glob\nfrom glob import glob","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-29T00:39:14.426683Z","iopub.execute_input":"2025-10-29T00:39:14.427036Z","iopub.status.idle":"2025-10-29T00:39:14.795323Z","shell.execute_reply.started":"2025-10-29T00:39:14.427011Z","shell.execute_reply":"2025-10-29T00:39:14.793674Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\ndef plotImages(tools,directory):\n    print(tools)\n    multipleImages = glob(directory)\n    plt.rcParams['figure.figsize'] = (8, 8) #Original is 15,15. Since we have 18 veggies I decreased the size\n    plt.subplots_adjust(wspace=0, hspace=0)\n    i_ = 0\n    for l in multipleImages[:25]: #Original is 25\n        im = cv2.imread(l)\n        im = cv2.resize(im, (256, 256)) \n        plt.subplot(5, 5, i_+1) #.set_title(l)\n        plt.imshow(cv2.cvtColor(im, cv2.COLOR_BGR2RGB)); plt.axis('off')\n        i_ += 1\n\nplotImages(\"Biomass train images\",\"../input/csiro-biomass/train/**\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-29T00:40:06.124327Z","iopub.execute_input":"2025-10-29T00:40:06.124735Z","iopub.status.idle":"2025-10-29T00:40:09.339494Z","shell.execute_reply.started":"2025-10-29T00:40:06.124709Z","shell.execute_reply":"2025-10-29T00:40:09.338364Z"},"_kg_hide-input":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Competition citation\n\n@misc{csiro-biomass,\n\nauthor = {Qiyu Liao and Dadong Wang and Rhys Pirie and Joshua Whelan and Rebecca Haling and Jiajun Liu and Rizwan Khokher and Xun Li and Martyna Plomecka and Addison Howard},\n\ntitle = {CSIRO - Image2Biomass Prediction},\nyear = {2025},\n\nhowpublished = {\\url{https://kaggle.com/competitions/csiro-biomass}},\nnote = {Kaggle}\n}","metadata":{}},{"cell_type":"markdown","source":"## Load test file","metadata":{}},{"cell_type":"code","source":"test = pd.read_csv('/kaggle/input/csiro-biomass/test.csv')\ntest.tail()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-29T00:40:54.959015Z","iopub.execute_input":"2025-10-29T00:40:54.959818Z","iopub.status.idle":"2025-10-29T00:40:54.974712Z","shell.execute_reply.started":"2025-10-29T00:40:54.959783Z","shell.execute_reply":"2025-10-29T00:40:54.973697Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Load train file","metadata":{}},{"cell_type":"code","source":"train = pd.read_csv('/kaggle/input/csiro-biomass/train.csv')\ntrain.tail()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-29T00:41:39.890986Z","iopub.execute_input":"2025-10-29T00:41:39.891361Z","iopub.status.idle":"2025-10-29T00:41:39.917753Z","shell.execute_reply.started":"2025-10-29T00:41:39.891334Z","shell.execute_reply":"2025-10-29T00:41:39.916635Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## info() method","metadata":{}},{"cell_type":"code","source":"train.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-29T00:42:48.575315Z","iopub.execute_input":"2025-10-29T00:42:48.575653Z","iopub.status.idle":"2025-10-29T00:42:48.594273Z","shell.execute_reply.started":"2025-10-29T00:42:48.575629Z","shell.execute_reply":"2025-10-29T00:42:48.593306Z"},"_kg_hide-output":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Five key biomass components\n\n\"Your task is to use pasture images to predict five key biomass components critical for grazing and feed management:\"\n\n* Dry green vegetation (excluding clover)\n\n* Dry dead material\n\n* Dry clover biomass\n\n* Green dry matter (GDM)\n\n* Total dry biomass\n\n\"Accurately predicting these quantities will help farmers and researchers monitor pasture growth, optimize feed availability, and improve the sustainability of livestock systems.\"\n\nhttps://www.kaggle.com/competitions/csiro-biomass","metadata":{}},{"cell_type":"code","source":"train['target_name'].value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-29T00:41:45.267114Z","iopub.execute_input":"2025-10-29T00:41:45.267460Z","iopub.status.idle":"2025-10-29T00:41:45.280591Z","shell.execute_reply.started":"2025-10-29T00:41:45.267435Z","shell.execute_reply":"2025-10-29T00:41:45.279572Z"},"_kg_hide-input":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Australian state where sample was collected.\n\nTasmania (Tas), Victoria (Vic), New South Wales (NSW) and Western Austalia (WA)","metadata":{}},{"cell_type":"code","source":"train['State'].value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-29T00:43:41.296038Z","iopub.execute_input":"2025-10-29T00:43:41.296357Z","iopub.status.idle":"2025-10-29T00:43:41.304373Z","shell.execute_reply.started":"2025-10-29T00:43:41.296336Z","shell.execute_reply":"2025-10-29T00:43:41.303209Z"},"_kg_hide-input":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"labels = 'Tas', 'Vic', 'NSW', 'WA' # Tasmania, Victoria,New South Wales and Western Australia\nsizes = [690, 560, 375, 160]  #must have same number labels, sizes and explode\nexplode = (0, 0.2, 0, 0)  # only \"explode\" the 2nd slice \n\nfig1, ax1 = plt.subplots(figsize=(6,6))\nax1.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',\n        shadow=True, startangle=90)\nax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-29T00:44:08.123069Z","iopub.execute_input":"2025-10-29T00:44:08.123397Z","iopub.status.idle":"2025-10-29T00:44:08.278401Z","shell.execute_reply.started":"2025-10-29T00:44:08.123370Z","shell.execute_reply":"2025-10-29T00:44:08.277292Z"},"_kg_hide-input":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Species — Pasture species present, ordered by biomass (underscore-separated).\n\nWe have 15 pasture species","metadata":{}},{"cell_type":"code","source":"import seaborn as sns\n\n#By Pedro Andrade https://www.kaggle.com/code/pbizil/datahackers-managers-radiografia-dos-gestores\n\nspecies_counts = train[\"Species\"].value_counts().head(15)#Try different values of head\nsns.set(style=\"white\")\nplt.figure(figsize=(8, 6))\n#x=type_counts.index, y=loc_counts.values\nax = sns.barplot(x=species_counts.index, y=species_counts.values, color=sns.color_palette(\"Greens\", n_colors=5)[3])\nplt.title(\"Distribution of Pasture Species\", fontsize=16)\nplt.xlabel(\"Tags\", fontsize=12)\nplt.ylabel(\"Frequency\", fontsize=12)\nplt.xticks(rotation=60, fontsize=11)\nplt.yticks(fontsize=11)\nsns.despine()\n\n#+2 is good if chart is vertical. +20 worked for horizontal\nfor i, v in enumerate(species_counts.values):\n    ax.text(i, v + 2, str(v), ha='center', va='bottom', fontsize=10)\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-29T00:45:16.512287Z","iopub.execute_input":"2025-10-29T00:45:16.512647Z","iopub.status.idle":"2025-10-29T00:45:18.083587Z","shell.execute_reply.started":"2025-10-29T00:45:16.512623Z","shell.execute_reply":"2025-10-29T00:45:18.082386Z"},"_kg_hide-input":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"numerical_cols = ['Pre_GSHH_NDVI', 'Height_Ave_cm', 'target']","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-29T00:45:38.062944Z","iopub.execute_input":"2025-10-29T00:45:38.063379Z","iopub.status.idle":"2025-10-29T00:45:38.068311Z","shell.execute_reply.started":"2025-10-29T00:45:38.063354Z","shell.execute_reply":"2025-10-29T00:45:38.067154Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Pre_GSHH_NDVI** — Normalized Difference Vegetation Index (GreenSeeker) reading.\n\n**Height_Ave_cm** — Average pasture height measured by falling plate (cm).","metadata":{}},{"cell_type":"code","source":"#Original figsize 15,10\ntrain[numerical_cols].hist(figsize=(10,8), bins=30, color='Green', edgecolor='black')\nplt.suptitle(\"Histogram of Numeric Features\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-29T00:46:06.620715Z","iopub.execute_input":"2025-10-29T00:46:06.621006Z","iopub.status.idle":"2025-10-29T00:46:07.450852Z","shell.execute_reply.started":"2025-10-29T00:46:06.620983Z","shell.execute_reply":"2025-10-29T00:46:07.449926Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### target and Height_Ave_cm are right skewed","metadata":{}},{"cell_type":"code","source":"import random\nfrom PIL import Image  # Pillow library for image handling\nimport tensorflow as tf\nfrom tensorflow.keras import layers, models\nfrom sklearn.model_selection import train_test_split","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-29T00:47:02.570770Z","iopub.execute_input":"2025-10-29T00:47:02.571071Z","iopub.status.idle":"2025-10-29T00:47:21.612469Z","shell.execute_reply.started":"2025-10-29T00:47:02.571051Z","shell.execute_reply":"2025-10-29T00:47:21.611470Z"},"_kg_hide-output":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#By @jocelyndumlao\n\nDATA_DIR = \"../input/csiro-biomass\"  \nIMAGE_SIZE = (128, 128)  # Reduced size for faster training; adjust as needed\nBATCH_SIZE = 32\nSEED = 42  # For reproducibility","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-29T00:48:16.451764Z","iopub.execute_input":"2025-10-29T00:48:16.452370Z","iopub.status.idle":"2025-10-29T00:48:16.458047Z","shell.execute_reply.started":"2025-10-29T00:48:16.452347Z","shell.execute_reply":"2025-10-29T00:48:16.456755Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#By @jocelyndumlao\n\ndef load_and_preprocess_data(data_dir, image_size):\n    \"\"\"\n    Loads images from the specified directory, resizes them, and converts them to numpy arrays.\n\n    Assumes that all files in the directory are images.  No subdirectories are supported in this basic example.\n\n    Args:\n        data_dir (str): Path to the directory containing the images.\n        image_size (tuple): The desired size of the images (width, height).\n\n    Returns:\n        tuple: A tuple containing:\n            - A numpy array of image data (shape: (num_images, height, width, channels)).\n            - A numpy array of corresponding labels (all zeros in this case, since it's a single class).\n    \"\"\"\n    image_paths = [os.path.join(data_dir, f) for f in os.listdir(data_dir) if f.endswith(\".jpg\")] #also change to gif\n    images = []\n    for image_path in image_paths:\n        try:\n            img = Image.open(image_path).convert('RGB').resize(image_size)  # Handle GIFs, convert to RGB\n            img_array = np.array(img) / 255.0  # Normalize pixel values\n            images.append(img_array)\n        except Exception as e:\n            print(f\"Error processing {image_path}: {e}\")\n            continue #skip to the next image\n\n    if not images:\n        raise ValueError(\"No images were loaded from the directory.\")\n\n    images = np.array(images)\n    labels = np.zeros(len(images))  # All images are from the same class (Quran page)\n\n    return images, labels","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-29T00:48:42.459868Z","iopub.execute_input":"2025-10-29T00:48:42.460626Z","iopub.status.idle":"2025-10-29T00:48:42.467629Z","shell.execute_reply.started":"2025-10-29T00:48:42.460598Z","shell.execute_reply":"2025-10-29T00:48:42.466579Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#By @jocelyndumlao\n\ntry:\n    images, labels = load_and_preprocess_data(DATA_DIR, IMAGE_SIZE)\nexcept ValueError as e:\n    print(e)  # Print the error message and exit\n    exit()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-29T00:49:03.640522Z","iopub.execute_input":"2025-10-29T00:49:03.640876Z","iopub.status.idle":"2025-10-29T00:49:03.647357Z","shell.execute_reply.started":"2025-10-29T00:49:03.640853Z","shell.execute_reply":"2025-10-29T00:49:03.646379Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### The initial notebook froze, the Draft is starting again till now : ) Then I deleted it.","metadata":{}},{"cell_type":"markdown","source":"## Okey,dokey! Done\n\n![](https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQdbcwSYH4Vmy6qgtRw5zAmcA4_v7X2upq8qw&s)EcoMENA","metadata":{}},{"cell_type":"markdown","source":"#Acknowledgements:\n\nPedro Andrade https://www.kaggle.com/code/pbizil/datahackers-managers-radiografia-dos-gestores","metadata":{}}]}