Non-Destructive Crop Growth Assessment Using Image-Based PVC Framework

We designed an image analysis framework in the agrivoltaics field to assess crop growth using non-destructive methods. The key was to remove background noise, as the pictures were taken in the field. Our idea was to connect the Photoroom API to our R code, and by using the AI background removal feature of Photoroom, we successfully removed all noise, including weeds.

1) Design of PVC Framework

# OpenSCAD
// ===============================================
// PVC / Wire Frame Structure (English Version)
// Dimensions: Width 0.75m, Depth 0.75m, Height 1.0m
// ===============================================

// [Unit: mm] (1m = 1000mm, 0.75m = 750mm)
width  = 750;        // Base Width: 0.75m (750mm)
depth  = 750;        // Base Depth: 0.75m (750mm)
height = 1000;       // Frame Height: 1.0m (1000mm)

sq_size = 180;       // Center Small Square Size
pipe_radius = 12;    // Pipe Thickness / Radius
fn_val = 32;         // Cylinder Resolution ($fn)

show_text = true;    // Toggle Dimension Text (true / false)

module pipe(p1, p2, r = pipe_radius) {
    hull() {
        translate(p1) sphere(r = r, $fn = fn_val);
        translate(p2) sphere(r = r, $fn = fn_val);
    }
}

module pvc_frame() {
    // ------------------------------------
    // Coordinates Setup
    // ------------------------------------
    // 1. Front Main Rectangle Frame (XZ Plane)
    A = [0, 0, 0];
    B = [width, 0, 0];
    C = [width, 0, height];
    D = [0, 0, height];

    // 2. Base & Back Connection Frame (YZ Plane)
    E = [0, depth, 0];
    F = [0, depth, height];

    // 3. Center Upper Square & Orthogonal Points (Z = height)
    cx = width / 2;
    cy = depth / 2;
    hs = sq_size / 2;

    SQ1 = [cx - hs, cy - hs, height]; // Inner Square: Front-Left
    SQ2 = [cx + hs, cy - hs, height]; // Inner Square: Front-Right
    SQ3 = [cx + hs, cy + hs, height]; // Inner Square: Back-Right
    SQ4 = [cx - hs, cy + hs, height]; // Inner Square: Back-Left

    // ------------------------------------
    // Pipe Connections (Orthogonal Structure)
    // ------------------------------------

    // [Front Rectangle Frame]
    pipe(A, B);
    pipe(B, C);
    pipe(C, D);
    pipe(D, A);

    // [Base Connection & Back Vertical Pillar]
    pipe(A, E);
    pipe(E, F);

    // [Front Upper Center -> Center Square Front]
    pipe([cx, 0, height], [cx, cy - hs, height]);

    // [Center Small Square Frame]
    pipe(SQ1, SQ2);
    pipe(SQ2, SQ3);
    pipe(SQ3, SQ4);
    pipe(SQ4, SQ1);

    // [Center Square Back -> Back Pillar (Right-Angle Bend)]
    pipe([cx, cy + hs, height], [cx, depth, height]);
    pipe([cx, depth, height], F);

    // ------------------------------------
    // 3D Text Dimension Display
    // ------------------------------------
    if (show_text) {
        // [Base Dimensions (2 Edges)]
        // 1. Front Base Width (0.75m)
        color("red")
        translate([width / 2, -40, 20])
        rotate([90, 0, 0])
        text("0.75m", size=45, halign="center", valign="center");

        // 2. Left Base Depth (0.75m)
        color("red")
        translate([-40, depth / 2, 20])
        rotate([90, 0, 90])
        text("0.75m", size=45, halign="center", valign="center");

        // [Height Dimensions (3 Vertical Pillars)]
        // 1. Front-Left Pillar (1m)
        color("red")
        translate([-40, 0, height / 2])
        rotate([90, 0, 90])
        text("1m", size=45, halign="center", valign="center");

        // 2. Front-Right Pillar (1m)
        color("red")
        translate([width + 40, 0, height / 2])
        rotate([90, 0, 90])
        text("1m", size=45, halign="center", valign="center");

        // 3. Back-Left Pillar (1m)
        color("red")
        translate([-40, depth, height / 2])
        rotate([90, 0, 90])
        text("1m", size=45, halign="center", valign="center");
    }
}

// Execute Rendering
pvc_frame();

2) Pilot test in the field

04/09/2026 @ Albany, NY

3) Taking pictures in the field


4) Image processing