{"@context":"https://schema.org","@type":"TechArticle","id":"TR-IMG-001","slug":"imaging-plant-health","canonical_url":"https://flavorotor.com/research/imaging-plant-health","machine_readable_url":"https://flavorotor.com/research/data/chapters/imaging-plant-health.json","markdown_url":"https://flavorotor.com/research/markdown/imaging-plant-health","title":"Camera, plant phenotyping and machine learning","description":"Indexed camera geometry, longitudinal plant measurements, real image datasets, reproducible augmentation, grouped validation and measured MobileNetV2, EfficientNetB0 and ResNet50 performance.","chapter":"Experimental platform","version":"3.0","updated":"2026-07-29","table_of_contents":[{"id":"camera-geometry","label":"Camera geometry"},{"id":"acquisition-record","label":"What is stored with each image"},{"id":"dataset-design","label":"Images used for model development"},{"id":"split-policy","label":"Split by physical leaf"},{"id":"augmentation","label":"Image augmentation"},{"id":"model-architecture","label":"MobileNetV2 and the MLP classifier"},{"id":"model-choice","label":"Why this model fits the camera task"},{"id":"mlp-head","label":"The classifier head"},{"id":"backbone-comparison","label":"Encoder comparison"},{"id":"grouped-cross-validation","label":"Five-fold grouped cross-validation"},{"id":"training-procedure","label":"Model fitting"},{"id":"controlled-benchmark","label":"Controlled-image benchmark"},{"id":"performance-uncertainty","label":"Uncertainty around the measured scores"},{"id":"natural-background-check","label":"Natural-background check"},{"id":"evaluation","label":"Metric definitions"},{"id":"temporal-phenotyping","label":"Following one plant through time"},{"id":"longitudinal-datasets","label":"Datasets used to test longitudinal methods"},{"id":"model-by-endpoint","label":"A separate model for each measured endpoint"},{"id":"inference-record","label":"Stored model output"}],"html":"<section aria-label=\"Article summary\" class=\"fr-article-summary\"><div><span>Plant imaging</span><p>The central camera photographs the same plant position repeatedly and stores every image with its plant, cultivation cycle and camera settings.</p></div></section>\n<div class=\"fr-research-figure-grid\"><figure class=\"fr-research-figure\"><img alt=\"FlavoRotor plant-health camera mounted in the central optical module\" loading=\"lazy\" decoding=\"async\" src=\"/features/plant-health-camera.webp\"/><figcaption><strong>Central camera.</strong><span>The camera remains stationary while the rotor brings each plant to its recorded image position. <button aria-label=\"Open source record I02\" class=\"research-source-trigger\" data-research-source=\"I02\" type=\"button\">[I02]</button></span></figcaption></figure><figure class=\"fr-research-figure\"><img alt=\"FlavoRotor central lighting and imaging module engineering view\" loading=\"lazy\" decoding=\"async\" src=\"/research/original/central-light-imaging-module.webp\"/><figcaption><strong>Camera and light module.</strong><span>One acquisition record identifies camera pose, plant position and illumination state. <button aria-label=\"Open source record I02\" class=\"research-source-trigger\" data-research-source=\"I02\" type=\"button\">[I02]</button></span></figcaption></figure></div>\n<h2 id=\"camera-geometry\">Camera geometry</h2>\n<p>The camera is fixed to the central module. The rotor stops at a known encoder position and presents one plant module to the lens. At that position, the optical axis meets the local plant plane at 90°. The distance, lens and framing therefore remain comparable when the same plant returns for its next image. The acquisition record stores camera version, lens, focus, working distance, encoder position and image dimensions. <button aria-label=\"Open source record I02\" class=\"research-source-trigger\" data-research-source=\"I02\" type=\"button\">[I02]</button> <button aria-label=\"Open source record R52\" class=\"research-source-trigger\" data-research-source=\"R52\" type=\"button\">[R52]</button></p>\n<div data-research-visual=\"ai-camera-geometry\"></div>\n<h2 id=\"acquisition-record\">What is stored with each image</h2>\n<p>The image file alone is not enough. Its record identifies the plant, growth cycle, rotor position, exposure, gain, white balance and light state. A scale reference makes pixel measurements comparable. A colour target reveals changes in illumination or camera response. Focus, clipping and occlusion are stored as visible image-quality fields.</p>\n<div class=\"table-wrap\"><table><thead><tr><th>Field group</th><th>Stored values</th><th>Reason</th></tr></thead><tbody>\n<tr><td>Plant</td><td>plant_id, crop, cultivar, seed lot, cycle_id</td><td>keeps repeated images attached to one biological specimen</td></tr>\n<tr><td>Position</td><td>position_id, encoder index, camera pose, working distance</td><td>shows where and how the image was taken</td></tr>\n<tr><td>Camera</td><td>camera_version, lens, focus, exposure, gain, white balance</td><td>separates plant change from camera change</td></tr>\n<tr><td>Growing conditions</td><td>recipe_version, light state, temperature, pH, EC, rotation state</td><td>connects the image to the measured environment</td></tr>\n<tr><td>File history</td><td>timestamp_utc, SHA-256, annotation version, operator</td><td>identifies the exact file and label version</td></tr>\n</tbody></table></div>\n<h2 id=\"dataset-design\">Images used for model development</h2>\n<p>Three image sources have different jobs. ImageNet supplies the general visual weights used to initialise MobileNetV2. PlantVillage supplies clean, labelled leaf images. PlantDoc adds leaves photographed with natural backgrounds and changing viewpoints. FlavoRotor images represent the camera, lighting and plant geometry in which the model operates. Results from these sources remain separate because a clean single-leaf photograph is different from a plant growing inside the machine. <button aria-label=\"Open source record R30\" class=\"research-source-trigger\" data-research-source=\"R30\" type=\"button\">[R30]</button> <button aria-label=\"Open source record R51\" class=\"research-source-trigger\" data-research-source=\"R51\" type=\"button\">[R51]</button> <button aria-label=\"Open source record R53\" class=\"research-source-trigger\" data-research-source=\"R53\" type=\"button\">[R53]</button> <button aria-label=\"Open source record R56\" class=\"research-source-trigger\" data-research-source=\"R56\" type=\"button\">[R56]</button></p>\n<div class=\"table-wrap\"><table><thead><tr><th>Images</th><th>Content</th><th>Use</th></tr></thead><tbody>\n<tr><td>ImageNet-1K <button aria-label=\"Open source record R53\" class=\"research-source-trigger\" data-research-source=\"R53\" type=\"button\">[R53]</button></td><td>general photographs from many object classes</td><td>initial weights for edges, textures and shapes</td></tr>\n<tr><td>PlantVillage <button aria-label=\"Open source record R30\" class=\"research-source-trigger\" data-research-source=\"R30\" type=\"button\">[R30]</button></td><td>54,306 controlled RGB leaf images covering healthy tissue and plant diseases</td><td>controlled leaf-classification benchmark</td></tr>\n<tr><td>PlantDoc <button aria-label=\"Open source record R51\" class=\"research-source-trigger\" data-research-source=\"R51\" type=\"button\">[R51]</button></td><td>2,598 plant images from 13 species and 27 healthy or disease classes</td><td>comparison under natural backgrounds and variable framing</td></tr>\n<tr><td>FlavoRotor <button aria-label=\"Open source record I02\" class=\"research-source-trigger\" data-research-source=\"I02\" type=\"button\">[I02]</button></td><td>indexed images from the central camera</td><td>device-specific plant tracking and evaluation</td></tr>\n</tbody></table></div>\n<p>The reproducible web example downloads the complete PlantVillage Strawberry RGB subset at repository commit <code>7f7ecc7</code>: 456 healthy images and 1,109 leaf-scorch images. The repository's published leaf map identifies 1,232 of those images as observations of 190 physical leaves. The Python script records every selected filename, SHA-256 hash, class, leaf group and transform parameter.</p>\n<div data-research-visual=\"plantvillage-strawberry-samples\"></div>\n<div data-research-visual=\"plantvillage-strawberry-distribution\"></div>\n<h2 id=\"split-policy\">Split by physical leaf</h2>\n<p>Photographs of the same physical leaf stay together. The deterministic seed <code>20260729</code> assigns leaf groups to 70% training, 15% validation and 15% test partitions. This prevents near-duplicate photographs of one leaf from appearing in both training and test data.</p>\n<div class=\"table-wrap\"><table><thead><tr><th>Class</th><th>Training</th><th>Validation</th><th>Test</th></tr></thead><tbody>\n<tr><td>Healthy</td><td>316 images / 80 leaves</td><td>68 images / 17 leaves</td><td>72 images / 18 leaves</td></tr>\n<tr><td>Leaf scorch</td><td>534 images / 52 leaves</td><td>115 images / 11 leaves</td><td>127 images / 12 leaves</td></tr>\n<tr><td>Total</td><td>850 images / 132 leaves</td><td>183 images / 28 leaves</td><td>199 images / 30 leaves</td></tr>\n</tbody></table></div>\n<h2 id=\"augmentation\">Image augmentation</h2>\n<p>The Python preprocessing script creates the examples below from one published leaf-scorch image. Rotation, scale, brightness, contrast, saturation, blur and sensor noise change the complete frame by a recorded amount. They do not paint new spots or remove existing tissue. Only the training partition receives random augmentation; validation and test images keep their original pixels apart from the fixed resize and normalisation. <button aria-label=\"Open source record R54\" class=\"research-source-trigger\" data-research-source=\"R54\" type=\"button\">[R54]</button></p>\n<div data-research-visual=\"ai-augmentation-gallery\"></div>\n<h2 id=\"model-architecture\">MobileNetV2 and the MLP classifier</h2>\n<p>The reference model receives a 224 × 224 sRGB image. MobileNetV2, initialised with ImageNet-1K weights, converts the image into a 7 × 7 × 1,280 feature map. Global average pooling produces a 1,280-value vector. The MLP maps that vector to 256 ReLU6 units, applies dropout 0.25, and produces one logit for every declared plant-health class. <button aria-label=\"Open source record R31\" class=\"research-source-trigger\" data-research-source=\"R31\" type=\"button\">[R31]</button> <button aria-label=\"Open source record R53\" class=\"research-source-trigger\" data-research-source=\"R53\" type=\"button\">[R53]</button></p>\n<div class=\"table-wrap\"><table><thead><tr><th>Stage</th><th>Shape</th><th>Operation</th></tr></thead><tbody>\n<tr><td>Input</td><td>224 × 224 × 3</td><td>sRGB image with ImageNet normalisation</td></tr>\n<tr><td>Encoder</td><td>7 × 7 × 1,280</td><td>MobileNetV2 features</td></tr>\n<tr><td>Pooling</td><td>1,280</td><td>global average pooling</td></tr>\n<tr><td>Hidden layer</td><td>256</td><td>linear layer, ReLU6 and dropout 0.25</td></tr>\n<tr><td>Output</td><td>C</td><td>one logit per class</td></tr>\n<tr><td>Probability</td><td>C</td><td>softmax followed by validation-set temperature scaling</td></tr>\n</tbody></table></div>\n<h3 id=\"model-choice\">Why this model fits the camera task</h3>\n<p>MobileNetV2 uses depthwise convolutions and inverted residual blocks. With the 256-unit classifier, it contains 2,586,434 parameters. The same camera is evaluated at every indexed plant position, so model size and single-image latency matter alongside classification performance. <button aria-label=\"Open source record R31\" class=\"research-source-trigger\" data-research-source=\"R31\" type=\"button\">[R31]</button></p>\n<h3 id=\"mlp-head\">The classifier head</h3>\n<p>Global average pooling converts the 7 × 7 × 1,280 encoder output into one 1,280-value feature vector. The multilayer perceptron learns combinations of those features that separate the declared classes. ReLU6 bounds each hidden activation between 0 and 6; dropout removes 25% of hidden activations at random during fitting. The final linear layer returns two logits, which softmax converts into class probabilities.</p>\n<div class=\"equation\"><div class=\"equation-label\">CV-MLP</div><div class=\"equation-text\">h = Dropout(ReLU6(W₁z + b₁), 0.25), &nbsp; ℓ = W₂h + b₂</div><div class=\"equation-desc\">z is the 1,280-value MobileNetV2 feature vector, h contains 256 hidden activations and ℓ contains one logit per class.</div></div>\n<p>The 1,280 × 256 hidden layer has 327,680 weights and 256 biases. The 256 × 2 output has 512 weights and 2 biases. The MLP therefore contributes 328,450 trainable parameters.</p>\n<h3 id=\"backbone-comparison\">Encoder comparison</h3>\n<p>MobileNetV2, EfficientNetB0 and ResNet50 were tested with the same frozen ImageNet protocol, 256-unit ReLU6 MLP, physical-leaf split and three deterministic seeds. All three reached 100% mean accuracy on the 199-image controlled test. The natural-background PlantDoc check separated them: mean healthy-class recall was 84.38% for MobileNetV2, 74.65% for EfficientNetB0 and 55.90% for ResNet50.</p>\n<div data-research-visual=\"plantvision-backbone-benchmark\"></div>\n<p>MobileNetV2 also required the fewest parameters and had the lowest measured CPU latency: 2.59 million parameters and 60.59 ms median, compared with 4.38 million and 83.35 ms for EfficientNetB0, and 24.11 million and 171.27 ms for ResNet50. Latency was measured with TensorFlow 2.18 inside a three-core Docker limit on an Intel Xeon E5-2699 v3. Processor choice changes throughput, not the mathematical definition of accuracy.</p>\n<h3 id=\"grouped-cross-validation\">Five-fold grouped cross-validation</h3>\n<p>A second test used all 1,232 images tied to 190 physical leaves. The folds were stratified by class; every leaf appeared in one test fold and never in that fold’s training or validation data. MobileNetV2 and the MLP were refitted in every fold. Aggregate accuracy was 99.84%, balanced accuracy 99.87% and macro F1 99.83%; two of 776 leaf-scorch images were assigned healthy and all 456 healthy images were assigned correctly. Mean PlantDoc healthy recall across the five fitted models was 80.00% with a standard deviation of 8.38 percentage points.</p>\n<div data-research-visual=\"plantvision-grouped-cv\"></div>\n<p>The image classifier assigns one of its declared visual labels to the current frame. Biomass forecasting, nutrient-state estimation and stress attribution use separate models with repeated images and measured cultivation variables.</p>\n<div data-research-visual=\"ai-camera-pipeline\"></div>\n<h2 id=\"training-procedure\">Model fitting</h2>\n<ol class=\"fr-method-steps\">\n<li><strong>Fit the MLP.</strong><span>The ImageNet encoder remains frozen while the classifier learns from the grouped training images.</span></li>\n<li><strong>Fine-tune the final encoder blocks.</strong><span>A lower learning rate adjusts the highest-level visual features; validation macro F1 controls early stopping.</span></li>\n<li><strong>Calibrate probability.</strong><span>One temperature value is fitted to validation logits after the model weights stop changing. <button aria-label=\"Open source record R55\" class=\"research-source-trigger\" data-research-source=\"R55\" type=\"button\">[R55]</button></span></li>\n<li><strong>Lock the test.</strong><span>Architecture, preprocessing, class thresholds and the low-confidence rule are fixed before test images are opened.</span></li>\n<li><strong>Report each image domain separately.</strong><span>PlantVillage, PlantDoc and FlavoRotor results use separate tables, because their camera conditions differ.</span></li>\n</ol>\n<div data-research-visual=\"plantvillage-training-history\"></div>\n<h2 id=\"controlled-benchmark\">Controlled-image benchmark</h2>\n<p>The reproducible TensorFlow 2.18.0 run completed on 29 July 2026. After five epochs, the locked model classified all 199 images in the grouped PlantVillage test partition correctly: 72 healthy and 127 leaf scorch. The test partition contains 30 physical leaf groups that were absent from training and validation. Accuracy, macro F1 and balanced accuracy are each 1.0000 for this controlled two-class benchmark. The fitted temperature is 0.500584 and the ten-bin expected calibration error is 0.0000361.</p>\n<div data-research-visual=\"plantvillage-confusion-matrix\"></div>\n<p>PlantVillage photographs isolated leaves against a controlled background. The result above therefore measures discrimination between those two published Strawberry classes under the same acquisition style; it is not substituted for a measurement from the FlavoRotor camera. <button aria-label=\"Open source record R30\" class=\"research-source-trigger\" data-research-source=\"R30\" type=\"button\">[R30]</button> <button aria-label=\"Open source record R56\" class=\"research-source-trigger\" data-research-source=\"R56\" type=\"button\">[R56]</button></p>\n<h3 id=\"performance-uncertainty\">Uncertainty around the measured scores</h3>\n<p>Every classification score is estimated from a finite test set. The controlled test observed 199 correct assignments from 199 images, but its exact two-sided 95% interval is 98.16–100%. Class recall has wider intervals because each class contains fewer observations: 95.01–100% for 72 healthy images and 97.14–100% for 127 leaf-scorch images. The interval states how much precision the test count provides; it does not change the observed confusion matrix.</p>\n<div data-research-visual=\"plantvision-performance-intervals\"></div>\n<h2 id=\"natural-background-check\">Natural-background check</h2>\n<p>The frozen model was then applied without retraining to all 96 images in PlantDoc's <em>Strawberry leaf</em> class. These photographs contain natural backgrounds, changing scale, partial leaves and varied lighting. The model assigned 79 images to healthy and 17 to leaf scorch, which gives healthy-class recall of 79 / 96 = 0.8229. PlantDoc does not publish a matching Strawberry leaf-scorch class, so this check reports recall for its healthy class rather than two-class accuracy. <button aria-label=\"Open source record R51\" class=\"research-source-trigger\" data-research-source=\"R51\" type=\"button\">[R51]</button> <button aria-label=\"Open source record R56\" class=\"research-source-trigger\" data-research-source=\"R56\" type=\"button\">[R56]</button></p>\n<div data-research-visual=\"plantdoc-strawberry-samples\"></div>\n<div data-research-visual=\"plantdoc-domain-check\"></div>\n<h2 id=\"evaluation\">Metric definitions</h2>\n<p>Precision answers: of the images assigned to one class, how many are correct? Recall answers: of the images that truly belong to that class, how many were found? F1 combines both values. Macro F1 gives every class the same weight, so the larger leaf-scorch class cannot hide weak performance on healthy leaves. The report also contains the complete confusion matrix, balanced accuracy, image count and physical-leaf count for every class. <button aria-label=\"Open source record R55\" class=\"research-source-trigger\" data-research-source=\"R55\" type=\"button\">[R55]</button> <button aria-label=\"Open source record R56\" class=\"research-source-trigger\" data-research-source=\"R56\" type=\"button\">[R56]</button></p>\n<div class=\"equation\"><div class=\"equation-label\">CV-F1</div><div class=\"equation-text\">F1 = 2 · precision · recall / (precision + recall)</div><div class=\"equation-desc\">F1 combines precision and recall. Macro F1 is the arithmetic mean of the class-level F1 values, so a large class cannot hide poor performance on a smaller class.</div></div>\n<div class=\"equation\"><div class=\"equation-label\">CV-ECE</div><div class=\"equation-text\">ECE = Σ |Bm| / n · |accuracy(Bm) − confidence(Bm)|</div><div class=\"equation-desc\">Predictions are grouped into confidence bins. ECE measures the weighted difference between observed accuracy and mean reported confidence in those bins.</div></div>\n<h2 id=\"temporal-phenotyping\">Following one plant through time</h2>\n<p>Repeated images of the same plant form a time series. Projected canopy area, calibrated colour, developmental stage and image quality are stored beside temperature, light, pH, EC and recipe version at the same timestamp. Growth rate compares the same plant at two recorded times. It does not compare unrelated plants photographed on different days. <button aria-label=\"Open source record R52\" class=\"research-source-trigger\" data-research-source=\"R52\" type=\"button\">[R52]</button></p>\n<div class=\"table-wrap\"><table><thead><tr><th>Output</th><th>Reference annotation</th><th>Use</th></tr></thead><tbody>\n<tr><td>Canopy area and growth rate</td><td>manual masks and a physical scale reference</td><td>tracks the plant's visible growth</td></tr>\n<tr><td>Developmental stage</td><td>crop-specific, expert-reviewed labels</td><td>aligns treatment timing with plant development</td></tr>\n<tr><td>Colour index</td><td>colour target and matching laboratory measurements</td><td>measures visible colour change</td></tr>\n<tr><td>Plant-health class</td><td>expert label and supporting laboratory result where required</td><td>records class and probability for review</td></tr>\n<tr><td>Image quality</td><td>focus, exposure, occlusion and pose labels</td><td>identifies unsuitable images</td></tr>\n</tbody></table></div>\n<h3 id=\"longitudinal-datasets\">Datasets used to test longitudinal methods</h3>\n<div class=\"table-wrap\"><table><thead><tr><th>Dataset</th><th>Repeated observations</th><th>Role in the research programme</th></tr></thead><tbody>\n<tr><td>Aalto lettuce <button aria-label=\"Open source record R57\" class=\"research-source-trigger\" data-research-source=\"R57\" type=\"button\">[R57]</button></td><td>18 identified heads, 30 biomass days, 731 canopy images and 1,443 environmental records</td><td>implemented three-day biomass forecast with plant-wise validation</td></tr>\n<tr><td>HydroGrowNet <button aria-label=\"Open source record R61\" class=\"research-source-trigger\" data-research-source=\"R61\" type=\"button\">[R61]</button></td><td>three 30-day Batavia cycles and more than 390,000 segmented images aligned with pH, EC and water temperature</td><td>independent multimodal growth and anomaly dataset</td></tr>\n<tr><td>Multi-sensor lettuce phenotyping <button aria-label=\"Open source record R62\" class=\"research-source-trigger\" data-research-source=\"R62\" type=\"button\">[R62]</button></td><td>45 plants over 42 days, two cultivars, three nitrogen levels and two irrigation rates</td><td>external RGB, 3D, multispectral, SPAD, fluorescence and morphology dataset</td></tr>\n</tbody></table></div>\n<h3 id=\"model-by-endpoint\">A separate model for each measured endpoint</h3>\n<div class=\"table-wrap\"><table><thead><tr><th>Question</th><th>Model</th><th>Reason</th><th>Reference value</th></tr></thead><tbody>\n<tr><td>Does the current leaf image match a declared visual class?</td><td>MobileNetV2 + 256-unit MLP</td><td>compact image encoder; class probabilities can be calibrated and reviewed</td><td>expert or published class label</td></tr>\n<tr><td>What fresh biomass is expected three days from now?</td><td>ridge autoregression</td><td>uses repeated mass and recent growth increments while regularising a small dataset</td><td>measured fresh biomass <button aria-label=\"Open source record R57\" class=\"research-source-trigger\" data-research-source=\"R57\" type=\"button\">[R57]</button></td></tr>\n<tr><td>How did cultivar and nutrient solution change tissue chemistry?</td><td>factorial ANOVA</td><td>tests cultivar, treatment and their interaction directly</td><td>laboratory nitrogen, sulphate, organic acid and chlorophyll measurements <button aria-label=\"Open source record R59\" class=\"research-source-trigger\" data-research-source=\"R59\" type=\"button\">[R59]</button></td></tr>\n<tr><td>Is the plant departing from its expected trajectory?</td><td>forecast residual plus consecutive-capture rule</td><td>requires persistence through time and retains the sensor and image context</td><td>next measured observation</td></tr>\n</tbody></table></div>\n<h2 id=\"inference-record\">Stored model output</h2>\n<p>Every model output stores the image hash, plant ID, model version, preprocessing version, probability for every class, calibrated confidence and image-quality score. A low-quality or low-confidence image is marked for review together with the reason. The original image and complete class-probability vector remain available beside the final label.</p>","text":"Plant imaging The central camera photographs the same plant position repeatedly and stores every image with its plant, cultivation cycle and camera settings. Central camera. The camera remains stationary while the rotor brings each plant to its recorded image position. [I02] Camera and light module. One acquisition record identifies camera pose, plant position and illumination state. [I02] Camera geometry The camera is fixed to the central module. The rotor stops at a known encoder position and presents one plant module to the lens. At that position, the optical axis meets the local plant plane at 90°. The distance, lens and framing therefore remain comparable when the same plant returns for its next image. The acquisition record stores camera version, lens, focus, working distance, encoder position and image dimensions. [I02] [R52] What is stored with each image The image file alone is not enough. Its record identifies the plant, growth cycle, rotor position, exposure, gain, white balance and light state. A scale reference makes pixel measurements comparable. A colour target reveals changes in illumination or camera response. Focus, clipping and occlusion are stored as visible image-quality fields. Field group Stored values Reason Plant plant_id, crop, cultivar, seed lot, cycle_id keeps repeated images attached to one biological specimen Position position_id, encoder index, camera pose, working distance shows where and how the image was taken Camera camera_version, lens, focus, exposure, gain, white balance separates plant change from camera change Growing conditions recipe_version, light state, temperature, pH, EC, rotation state connects the image to the measured environment File history timestamp_utc, SHA-256, annotation version, operator identifies the exact file and label version Images used for model development Three image sources have different jobs. ImageNet supplies the general visual weights used to initialise MobileNetV2. PlantVillage supplies clean, labelled leaf images. PlantDoc adds leaves photographed with natural backgrounds and changing viewpoints. FlavoRotor images represent the camera, lighting and plant geometry in which the model operates. Results from these sources remain separate because a clean single-leaf photograph is different from a plant growing inside the machine. [R30] [R51] [R53] [R56] Images Content Use ImageNet-1K [R53] general photographs from many object classes initial weights for edges, textures and shapes PlantVillage [R30] 54,306 controlled RGB leaf images covering healthy tissue and plant diseases controlled leaf-classification benchmark PlantDoc [R51] 2,598 plant images from 13 species and 27 healthy or disease classes comparison under natural backgrounds and variable framing FlavoRotor [I02] indexed images from the central camera device-specific plant tracking and evaluation The reproducible web example downloads the complete PlantVillage Strawberry RGB subset at repository commit 7f7ecc7 : 456 healthy images and 1,109 leaf-scorch images. The repository's published leaf map identifies 1,232 of those images as observations of 190 physical leaves. The Python script records every selected filename, SHA-256 hash, class, leaf group and transform parameter. Split by physical leaf Photographs of the same physical leaf stay together. The deterministic seed 20260729 assigns leaf groups to 70% training, 15% validation and 15% test partitions. This prevents near-duplicate photographs of one leaf from appearing in both training and test data. Class Training Validation Test Healthy 316 images / 80 leaves 68 images / 17 leaves 72 images / 18 leaves Leaf scorch 534 images / 52 leaves 115 images / 11 leaves 127 images / 12 leaves Total 850 images / 132 leaves 183 images / 28 leaves 199 images / 30 leaves Image augmentation The Python preprocessing script creates the examples below from one published leaf-scorch image. Rotation, scale, brightness, contrast, saturation, blur and sensor noise change the complete frame by a recorded amount. They do not paint new spots or remove existing tissue. Only the training partition receives random augmentation; validation and test images keep their original pixels apart from the fixed resize and normalisation. [R54] MobileNetV2 and the MLP classifier The reference model receives a 224 × 224 sRGB image. MobileNetV2, initialised with ImageNet-1K weights, converts the image into a 7 × 7 × 1,280 feature map. Global average pooling produces a 1,280-value vector. The MLP maps that vector to 256 ReLU6 units, applies dropout 0.25, and produces one logit for every declared plant-health class. [R31] [R53] Stage Shape Operation Input 224 × 224 × 3 sRGB image with ImageNet normalisation Encoder 7 × 7 × 1,280 MobileNetV2 features Pooling 1,280 global average pooling Hidden layer 256 linear layer, ReLU6 and dropout 0.25 Output C one logit per class Probability C softmax followed by validation-set temperature scaling Why this model fits the camera task MobileNetV2 uses depthwise convolutions and inverted residual blocks. With the 256-unit classifier, it contains 2,586,434 parameters. The same camera is evaluated at every indexed plant position, so model size and single-image latency matter alongside classification performance. [R31] The classifier head Global average pooling converts the 7 × 7 × 1,280 encoder output into one 1,280-value feature vector. The multilayer perceptron learns combinations of those features that separate the declared classes. ReLU6 bounds each hidden activation between 0 and 6; dropout removes 25% of hidden activations at random during fitting. The final linear layer returns two logits, which softmax converts into class probabilities. CV-MLP h = Dropout(ReLU6(W₁z + b₁), 0.25), ℓ = W₂h + b₂ z is the 1,280-value MobileNetV2 feature vector, h contains 256 hidden activations and ℓ contains one logit per class. The 1,280 × 256 hidden layer has 327,680 weights and 256 biases. The 256 × 2 output has 512 weights and 2 biases. The MLP therefore contributes 328,450 trainable parameters. Encoder comparison MobileNetV2, EfficientNetB0 and ResNet50 were tested with the same frozen ImageNet protocol, 256-unit ReLU6 MLP, physical-leaf split and three deterministic seeds. All three reached 100% mean accuracy on the 199-image controlled test. The natural-background PlantDoc check separated them: mean healthy-class recall was 84.38% for MobileNetV2, 74.65% for EfficientNetB0 and 55.90% for ResNet50. MobileNetV2 also required the fewest parameters and had the lowest measured CPU latency: 2.59 million parameters and 60.59 ms median, compared with 4.38 million and 83.35 ms for EfficientNetB0, and 24.11 million and 171.27 ms for ResNet50. Latency was measured with TensorFlow 2.18 inside a three-core Docker limit on an Intel Xeon E5-2699 v3. Processor choice changes throughput, not the mathematical definition of accuracy. Five-fold grouped cross-validation A second test used all 1,232 images tied to 190 physical leaves. The folds were stratified by class; every leaf appeared in one test fold and never in that fold’s training or validation data. MobileNetV2 and the MLP were refitted in every fold. Aggregate accuracy was 99.84%, balanced accuracy 99.87% and macro F1 99.83%; two of 776 leaf-scorch images were assigned healthy and all 456 healthy images were assigned correctly. Mean PlantDoc healthy recall across the five fitted models was 80.00% with a standard deviation of 8.38 percentage points. The image classifier assigns one of its declared visual labels to the current frame. Biomass forecasting, nutrient-state estimation and stress attribution use separate models with repeated images and measured cultivation variables. Model fitting Fit the MLP. The ImageNet encoder remains frozen while the classifier learns from the grouped training images. Fine-tune the final encoder blocks. A lower learning rate adjusts the highest-level visual features; validation macro F1 controls early stopping. Calibrate probability. One temperature value is fitted to validation logits after the model weights stop changing. [R55] Lock the test. Architecture, preprocessing, class thresholds and the low-confidence rule are fixed before test images are opened. Report each image domain separately. PlantVillage, PlantDoc and FlavoRotor results use separate tables, because their camera conditions differ. Controlled-image benchmark The reproducible TensorFlow 2.18.0 run completed on 29 July 2026. After five epochs, the locked model classified all 199 images in the grouped PlantVillage test partition correctly: 72 healthy and 127 leaf scorch. The test partition contains 30 physical leaf groups that were absent from training and validation. Accuracy, macro F1 and balanced accuracy are each 1.0000 for this controlled two-class benchmark. The fitted temperature is 0.500584 and the ten-bin expected calibration error is 0.0000361. PlantVillage photographs isolated leaves against a controlled background. The result above therefore measures discrimination between those two published Strawberry classes under the same acquisition style; it is not substituted for a measurement from the FlavoRotor camera. [R30] [R56] Uncertainty around the measured scores Every classification score is estimated from a finite test set. The controlled test observed 199 correct assignments from 199 images, but its exact two-sided 95% interval is 98.16–100%. Class recall has wider intervals because each class contains fewer observations: 95.01–100% for 72 healthy images and 97.14–100% for 127 leaf-scorch images. The interval states how much precision the test count provides; it does not change the observed confusion matrix. Natural-background check The frozen model was then applied without retraining to all 96 images in PlantDoc's Strawberry leaf class. These photographs contain natural backgrounds, changing scale, partial leaves and varied lighting. The model assigned 79 images to healthy and 17 to leaf scorch, which gives healthy-class recall of 79 / 96 = 0.8229. PlantDoc does not publish a matching Strawberry leaf-scorch class, so this check reports recall for its healthy class rather than two-class accuracy. [R51] [R56] Metric definitions Precision answers: of the images assigned to one class, how many are correct? Recall answers: of the images that truly belong to that class, how many were found? F1 combines both values. Macro F1 gives every class the same weight, so the larger leaf-scorch class cannot hide weak performance on healthy leaves. The report also contains the complete confusion matrix, balanced accuracy, image count and physical-leaf count for every class. [R55] [R56] CV-F1 F1 = 2 · precision · recall / (precision + recall) F1 combines precision and recall. Macro F1 is the arithmetic mean of the class-level F1 values, so a large class cannot hide poor performance on a smaller class. CV-ECE ECE = Σ |Bm| / n · |accuracy(Bm) − confidence(Bm)| Predictions are grouped into confidence bins. ECE measures the weighted difference between observed accuracy and mean reported confidence in those bins. Following one plant through time Repeated images of the same plant form a time series. Projected canopy area, calibrated colour, developmental stage and image quality are stored beside temperature, light, pH, EC and recipe version at the same timestamp. Growth rate compares the same plant at two recorded times. It does not compare unrelated plants photographed on different days. [R52] Output Reference annotation Use Canopy area and growth rate manual masks and a physical scale reference tracks the plant's visible growth Developmental stage crop-specific, expert-reviewed labels aligns treatment timing with plant development Colour index colour target and matching laboratory measurements measures visible colour change Plant-health class expert label and supporting laboratory result where required records class and probability for review Image quality focus, exposure, occlusion and pose labels identifies unsuitable images Datasets used to test longitudinal methods Dataset Repeated observations Role in the research programme Aalto lettuce [R57] 18 identified heads, 30 biomass days, 731 canopy images and 1,443 environmental records implemented three-day biomass forecast with plant-wise validation HydroGrowNet [R61] three 30-day Batavia cycles and more than 390,000 segmented images aligned with pH, EC and water temperature independent multimodal growth and anomaly dataset Multi-sensor lettuce phenotyping [R62] 45 plants over 42 days, two cultivars, three nitrogen levels and two irrigation rates external RGB, 3D, multispectral, SPAD, fluorescence and morphology dataset A separate model for each measured endpoint Question Model Reason Reference value Does the current leaf image match a declared visual class? MobileNetV2 + 256-unit MLP compact image encoder; class probabilities can be calibrated and reviewed expert or published class label What fresh biomass is expected three days from now? ridge autoregression uses repeated mass and recent growth increments while regularising a small dataset measured fresh biomass [R57] How did cultivar and nutrient solution change tissue chemistry? factorial ANOVA tests cultivar, treatment and their interaction directly laboratory nitrogen, sulphate, organic acid and chlorophyll measurements [R59] Is the plant departing from its expected trajectory? forecast residual plus consecutive-capture rule requires persistence through time and retains the sensor and image context next measured observation Stored model output Every model output stores the image hash, plant ID, model version, preprocessing version, probability for every class, calibrated confidence and image-quality score. A low-quality or low-confidence image is marked for review together with the reason. The original image and complete class-probability vector remain available beside the final label.","source_ids":["I02","R30","R31","R51","R52","R53","R54","R55","R56","R57","R59","R61","R62"],"visuals":[{"id":"ai-camera-geometry","type":"Mermaid-compatible optical-geometry diagram","title":"Indexed camera geometry","article":"imaging-plant-health","source_ids":["I02","R52"],"mermaid":"/research/data/diagrams/ai-camera-geometry.mmd"},{"id":"plantvillage-strawberry-samples","type":"interactive source-image gallery","title":"PlantVillage strawberry images used in the reproducible example","article":"imaging-plant-health","source_ids":["R30"],"data":"/research/datasets/plantvillage-strawberry/manifest.json"},{"id":"plantvillage-strawberry-distribution","type":"interactive bar chart","title":"Strawberry subset and leaf-group coverage","article":"imaging-plant-health","source_ids":["R30"],"csv":"/research/datasets/plantvillage-strawberry/class-distribution.csv"},{"id":"ai-camera-pipeline","type":"Mermaid-compatible machine-learning pipeline","title":"Image capture, model and review","article":"imaging-plant-health","source_ids":["R30","R31","R51","R53","R55","R56"],"mermaid":"/research/data/diagrams/ai-camera-pipeline.mmd"},{"id":"ai-augmentation-gallery","type":"Python-generated image augmentation gallery","title":"Deterministic augmentation examples","article":"imaging-plant-health","source_ids":["R30","R54"],"data":"/research/datasets/plantvillage-strawberry/manifest.json"},{"id":"plantvillage-training-history","type":"interactive training-history chart","title":"Training and validation accuracy by epoch","article":"imaging-plant-health","source_ids":["R30","R31","R53"],"csv":"/research/datasets/plantvillage-strawberry/training-history.csv","image":"/research/datasets/plantvillage-strawberry/training-accuracy.webp","svg":"/research/datasets/plantvillage-strawberry/training-accuracy.svg","generated_by":"scripts/train-plantvision-reference.py"},{"id":"plantvillage-confusion-matrix","type":"interactive confusion matrix","title":"Controlled Strawberry test-set classifications","article":"imaging-plant-health","source_ids":["R30","R31"],"csv":"/research/datasets/plantvillage-strawberry/confusion-matrix.csv","summary":"/research/datasets/plantvillage-strawberry/training-summary.json","image":"/research/datasets/plantvillage-strawberry/confusion-matrix.webp","svg":"/research/datasets/plantvillage-strawberry/confusion-matrix.svg","generated_by":"scripts/train-plantvision-reference.py"},{"id":"plantdoc-strawberry-samples","type":"interactive source-image and prediction gallery","title":"Natural-background Strawberry images from PlantDoc","article":"imaging-plant-health","source_ids":["R51"],"data":"/research/datasets/plantdoc-strawberry/summary.json","generated_by":"scripts/evaluate-plantvision-crossdomain.py"},{"id":"plantdoc-domain-check","type":"interactive prediction-count chart","title":"PlantDoc healthy-class predictions","article":"imaging-plant-health","source_ids":["R51"],"csv":"/research/datasets/plantdoc-strawberry/predictions.csv","summary":"/research/datasets/plantdoc-strawberry/summary.json","image":"/research/datasets/plantdoc-strawberry/healthy-class-predictions.webp","svg":"/research/datasets/plantdoc-strawberry/healthy-class-predictions.svg","generated_by":"scripts/evaluate-plantvision-crossdomain.py"},{"id":"plantvision-performance-intervals","type":"interactive exact confidence-interval plot","title":"Performance estimates with exact 95% confidence intervals","article":"imaging-plant-health","source_ids":["R30","R51","R55"],"csv":"/research/datasets/plantvision-performance/performance-intervals.csv","generated_by":"scripts/analyze-plant-monitoring-evidence.py"},{"id":"plantvision-backbone-benchmark","type":"interactive encoder performance and compute table","title":"Image encoder comparison","article":"imaging-plant-health","source_ids":["R30","R31","R51","R53"],"csv":"/research/datasets/plantvision-performance/backbone-benchmark/model-comparison.csv","summary":"/research/datasets/plantvision-performance/backbone-benchmark/summary.json","generated_by":"scripts/benchmark-plantvision-backbones.py and scripts/merge-plantvision-backbone-benchmark.py"},{"id":"plantvision-grouped-cv","type":"interactive five-fold physical-leaf validation chart","title":"Five-fold physical-leaf cross-validation","article":"imaging-plant-health","source_ids":["R30","R31","R51"],"csv":"/research/datasets/plantvision-performance/grouped-cv/fold-results.csv","summary":"/research/datasets/plantvision-performance/grouped-cv/summary.json","generated_by":"scripts/benchmark-plantvision-grouped-cv.py"}],"sources":[{"id":"I02","authors":"FlavoRotor project team","year":2026,"title":"FlavoRotor v2.0 system architecture","publication":"Internal engineering design report","doi":null,"url":"/research/platform","source_type":"internal primary record","relevance":"Documents the proposed magnetic drive, axial lighting, four-channel peristaltic dosing and imaging architecture.","verification":"Derived from the original FlavoRotor v2.0 engineering document","verified_on":"2026-07-26","verification_status":"INTERNAL PRIMARY RECORD","verified_against":"Original internal project file and extracted media"},{"id":"R30","authors":"Mohanty, Sharada P.; Hughes, David P.; Salathé, Marcel","year":2016,"title":"Using Deep Learning for Image-Based Plant Disease Detection","publication":"Frontiers in Plant Science","doi":"10.3389/fpls.2016.01419","source_type":"peer-reviewed research","relevance":"Provides a canonical controlled-image plant-disease classification benchmark and documents generalisation limitations.","verification":"Publisher, PubMed, ISO or official proceedings metadata checked 2026-07-26","url":"https://doi.org/10.3389/fpls.2016.01419","verified_on":"2026-07-26","verification_status":"DOI METADATA CHECKED","verified_against":"Publisher, DOI landing page, PubMed or official repository where available"},{"id":"R31","authors":"Sandler, Mark; Howard, Andrew; Zhu, Menglong; Zhmoginov, Andrey; Chen, Liang-Chieh","year":2018,"title":"MobileNetV2: Inverted Residuals and Linear Bottlenecks","publication":"2018 IEEE/CVF Conference on Computer Vision and Pattern Recognition","doi":"10.1109/CVPR.2018.00474","source_type":"peer-reviewed conference paper","relevance":"Provides the architecture basis for an efficient edge-image classifier.","verification":"Publisher, PubMed, ISO or official proceedings metadata checked 2026-07-26","url":"https://doi.org/10.1109/CVPR.2018.00474","verified_on":"2026-07-26","verification_status":"DOI METADATA CHECKED","verified_against":"Publisher, DOI landing page, PubMed or official repository where available"},{"id":"R51","authors":"Singh, Davinder; Jain, Naman; Jain, Pranjali; Kayal, Pratik; Kumawat, Sudhakar; Batra, Nipun","year":2020,"title":"PlantDoc: A Dataset for Visual Plant Disease Detection","publication":"Proceedings of the 7th ACM IKDD CoDS and 25th COMAD, 249–253","doi":"10.1145/3371158.3371196","url":"https://doi.org/10.1145/3371158.3371196","source_type":"peer-reviewed conference paper and dataset","relevance":"Provides a 2,598-image, 13-species, 27-class plant-disease dataset with real backgrounds and documents the gap between controlled and field-like imagery.","verification":"ACM proceedings metadata and the authors' dataset paper checked 2026-07-29","verified_on":"2026-07-29","verification_status":"DOI AND PRIMARY PAPER CHECKED","verified_against":"ACM Digital Library and author manuscript"},{"id":"R52","authors":"Arend, Daniel; Lange, Matthias; Pape, Jean-Michel; Weigelt-Fischer, Kathleen; Arana-Ceballos, Fernando; Mücke, Ingo; Klukas, Christian; Altmann, Thomas; Scholz, Uwe; Junker, Astrid","year":2016,"title":"Quantitative monitoring of Arabidopsis thaliana growth and development using high-throughput plant phenotyping","publication":"Scientific Data, 3, 160055","doi":"10.1038/sdata.2016.55","url":"https://doi.org/10.1038/sdata.2016.55","source_type":"peer-reviewed data descriptor","relevance":"Documents repeatable top and side RGB acquisition, image-linked metadata, reference measurements and quality validation for longitudinal plant phenotyping.","verification":"Nature Scientific Data metadata, methods and data-record sections checked 2026-07-29","verified_on":"2026-07-29","verification_status":"DOI AND PRIMARY PAPER CHECKED","verified_against":"Nature Scientific Data and PubMed Central full text"},{"id":"R53","authors":"Deng, Jia; Dong, Wei; Socher, Richard; Li, Li-Jia; Li, Kai; Fei-Fei, Li","year":2009,"title":"ImageNet: A Large-Scale Hierarchical Image Database","publication":"2009 IEEE Conference on Computer Vision and Pattern Recognition, 248–255","doi":"10.1109/CVPR.2009.5206848","url":"https://doi.org/10.1109/CVPR.2009.5206848","source_type":"peer-reviewed conference paper and dataset","relevance":"Defines the large-scale natural-image dataset used to initialise the generic visual encoder in the documented transfer-learning baseline.","verification":"IEEE proceedings metadata and official paper checked 2026-07-29","verified_on":"2026-07-29","verification_status":"DOI AND PRIMARY PAPER CHECKED","verified_against":"IEEE Xplore and the official CVPR paper"},{"id":"R54","authors":"Buslaev, Alexander; Iglovikov, Vladimir I.; Khvedchenya, Eugene; Parinov, Alex; Druzhinin, Mikhail; Kalinin, Alexandr A.","year":2020,"title":"Albumentations: Fast and Flexible Image Augmentations","publication":"Information, 11(2), 125","doi":"10.3390/info11020125","url":"https://doi.org/10.3390/info11020125","source_type":"peer-reviewed software paper","relevance":"Provides the reproducible image-transform framework used to define and log bounded training-only augmentations.","verification":"Publisher metadata, methods and software record checked 2026-07-29","verified_on":"2026-07-29","verification_status":"DOI AND PRIMARY PAPER CHECKED","verified_against":"MDPI Information and the official software repository"},{"id":"R55","authors":"Guo, Chuan; Pleiss, Geoff; Sun, Yu; Weinberger, Kilian Q.","year":2017,"title":"On Calibration of Modern Neural Networks","publication":"Proceedings of the 34th International Conference on Machine Learning, PMLR 70, 1321–1330","doi":null,"url":"https://proceedings.mlr.press/v70/guo17a.html","source_type":"peer-reviewed conference paper","relevance":"Defines confidence calibration analysis and supports temperature scaling as a simple post-hoc calibration method.","verification":"Official Proceedings of Machine Learning Research record and paper checked 2026-07-29","verified_on":"2026-07-29","verification_status":"PRIMARY PROCEEDINGS RECORD CHECKED","verified_against":"Proceedings of Machine Learning Research"},{"id":"R56","authors":"Xiang, Kun; Shi, Danxi; Zhu, Xiangbo","year":2026,"title":"Quantifying the reliability gap in cross-domain plant disease classification: benchmarking the limited efficacy of standard mitigation techniques under controlled-to-field shift","publication":"Frontiers in Plant Science, 17, 1826962","doi":"10.3389/fpls.2026.1826962","url":"https://doi.org/10.3389/fpls.2026.1826962","source_type":"peer-reviewed research","relevance":"Quantifies controlled-to-field domain shift using PlantVillage and PlantDoc and supports explicit target-domain evaluation and calibrated abstention.","verification":"Publisher metadata, methods and results checked 2026-07-29","verified_on":"2026-07-29","verification_status":"DOI AND PRIMARY PAPER CHECKED","verified_against":"Frontiers in Plant Science full text"},{"id":"R57","authors":"Karimzadeh, Sara; Ahamed, M. Shamim","year":2025,"title":"Lettuce Dataset with RGB Canopy Images, Biomass, Nutrient Solution, and Environmental Variables for Machine Learning Model Development","publication":"Zenodo, Version 1","doi":"10.5281/zenodo.16912088","url":"https://doi.org/10.5281/zenodo.16912088","source_type":"longitudinal experimental dataset","relevance":"Links 731 daily RGB canopy images, 540 non-destructive biomass observations from 18 identified lettuce heads, and 1,443 environmental records for longitudinal growth analysis.","verification":"Zenodo archive, Aalto University metadata record, workbook structure, file hashes and licence checked 2026-07-29","verified_on":"2026-07-29","verification_status":"PRIMARY DATASET AND FILES CHECKED","verified_against":"Zenodo and Aalto University Research Portal"},{"id":"R59","authors":"El-Nakhel, Christophe; Pannico, Antonio; Kyriacou, Marios C.; Petropoulos, Spyridon A.; Giordano, Maria; Colla, Giuseppe; Troise, Antonio Dario; Vitaglione, Paola; De Pascale, Stefania; Rouphael, Youssef","year":2020,"title":"Dataset on the organic acids, sulphate, total nitrogen and total chlorophyll contents of two lettuce cultivars grown hydroponically using nutrient solutions of variable macrocation ratios","publication":"Data in Brief, 29, 105135","doi":"10.1016/j.dib.2020.105135","url":"https://doi.org/10.1016/j.dib.2020.105135","source_type":"peer-reviewed data descriptor and dataset","relevance":"Reports all 18 observations in a balanced two-cultivar by three-solution experiment, including nitrogen, sulphate, organic acids and total chlorophyll.","verification":"Publisher article, Mendeley dataset 10.17632/tksv49dxtg.1, workbook and licence checked 2026-07-29","verified_on":"2026-07-29","verification_status":"DOI, PRIMARY PAPER AND DATASET CHECKED","verified_against":"Elsevier Data in Brief and Mendeley Data"},{"id":"R61","authors":"Shalash, Omar; Hassan, Nayira; Métwalli, Ahmed; Elhefny, Alia","year":2025,"title":"HydroGrowNet of Batavia Dataset","publication":"Mendeley Data, Version 5","doi":"10.17632/g6cm3v3wdp.5","url":"https://doi.org/10.17632/g6cm3v3wdp.5","source_type":"multimodal longitudinal dataset","relevance":"Contains more than 390,000 segmented lettuce images from three 30-day cycles aligned with water temperature, EC and pH measurements; useful for external growth and anomaly-model evaluation.","verification":"Mendeley Data version record, data-composition file and licence checked 2026-07-29","verified_on":"2026-07-29","verification_status":"PRIMARY DATASET METADATA CHECKED","verified_against":"Mendeley Data"},{"id":"R62","authors":"Rodrigues, Leandro; Terra, Francisco; Rodrigues, Pedro; Moreira, Germano; Oliveira, Francisco; Moura, Pedro; Pinheiro, Isabel; Santos, Filipe; Cunha, Mário","year":2026,"title":"Multi-Sensor High-Throughput Phenotyping Dataset of Hydroponic Lettuce under Variable Fertigation Conditions","publication":"Zenodo","doi":"10.5281/zenodo.20759414","url":"https://doi.org/10.5281/zenodo.20759414","source_type":"multimodal longitudinal phenotyping dataset","relevance":"Follows 45 lettuce plants from two cultivars through a 42-day crop cycle under three nitrogen concentrations and two irrigation rates, linking RGB, 3D, multispectral, SPAD, fluorescence and morphology records.","verification":"Zenodo metadata, file inventory, experimental factors and licence record checked 2026-07-29","verified_on":"2026-07-29","verification_status":"PRIMARY DATASET METADATA CHECKED","verified_against":"Zenodo"}]}
