Project in progress
MacroImager

MacroImager

A raspberry pi based cereal phenotyping device

  • 280 views
  • 0 comments
  • 4 respects

Components and supplies

770a4970 1 1 1619x1080 mla7tedwjy
Raspberry Pi 3 Model B+
×1
Pi camera front u1bkw3ybg1
Raspberry Pi Camera Module V2
×1
Pimoroni Raspberry Pi HDMI connectors
×1
4154657
Stepper Motor, Mini Step
×3
4764573
Audio / Video Cable Assembly, HDMI A Plug
×1
12v power supply (generic)
×1
MDF board (generic)
×1
M6 nuts, bolts, washers (generic)
×4
M5 nuts, bolts, washers (generic)
×30
M3 nuts, bolts, washers (generic)
×12
M4 bolts (generic)
×24
Lead screw bearings and housing
×6
Lead screw rod
×3
Copper lead screw rod nut
×3
Linear rail shaft mounts
×12
Linear rail shaft
×6
SC8UU linear bearings
×6
Flexible shaft coupling
×3
55t0399 40
Electrolytic Capacitor, 100 µF
×1
Stepper motor driver board DRV8825
×3
12002 04
Breadboard (generic)
×3
PLA 3D printer filament (generic)
×1
A000066 iso both
Arduino UNO & Genuino UNO
×3

Necessary tools and machines

3drag
3D Printer (generic)

About this project

Plant phenotyping is time consuming, hence costly. Where data collection is not automated it is highly prone to human error. Incredibly complex phenotypes are often condensed to single digit scoring, leading to data loss. Where data is captured by sight, we propose a multi-purpose high-resolution phenotyping station to improve the efficiency, accuracy and volume of data captured.

We plan to develop a low cost, multi-purpose large area macro photography phenotyping station, allowing users to build a full scale, incredibly high resolution, final image of large biological structures which we will leverage for phenotyping crop and non-crop plant species. The MACRO-IMAGER system will be designed to work on any plane of axis so that it is fully adaptable to the study of crop/plant physiology. We believe the MACRO-IMAGER platform could be rapidly adopted as a standard research tool for integration into experimental pipelines that investigate the genetics that underpin plant phenotypes.

Building our prototype

Getting our gantry moving for the first time and taking images

The very first version of our prototype had the raspberry pi mounted to the gantry, however we then found raspberry pi HDMI connectors, which meant we could take the raspberry pi off the gantry, leaving the camera tidily connected with a single HDMI cable.

Testing the MacroImager

We first tested the raspberry pi depth of field using small printed font and bank notes (as they have such an intricate design).

To test our MacroImager prototype we build a "mini-rhizotron". This is several pieces of clear colourless acrylic with agar (with MS salts) set in-between and (wheat) seeds inserted into the top of the agar to grow. This is then covered in foil so that the roots can grow in the dark. 3-6 days later we can uncover the mini-rhizotron and use the MacroImager to image the roots, so we will have our first plant-based test data set.


Making it two-dimensional



To add greater coverage of the subject we decided to upgrade the MacroImager to being a two dimensional device. We started by adding two new gantries in parallel with the original fixed to them using to the custom parts seen in the image below.

As you can see in the image below, the MacroImager is now a 2D device, with three stepper motors and one Raspberry pi camera. However now that there are three motors to control, we switched to arduinos to control the motors.


Stitching our images together

Going to our bank notes from earlier. We now stitch our images together using the gantry coordinates. But this took some playing around with, as the first attempts looked like the image below. Not a perfect match and the seam is clearly visible.


However with some editing of our scripts, the seams are now practically invisible (see image below).


When aligning many images, this results in an image like the one below.

Now that we had the MacroImager working with the Raspberry Pi camera, it was then time to try adapting it to a DSLR. So that subjects with a varying depth of field --- such as shoots or leaves --- could also be captured using the MacroImager.


Code

image_stitch.pyPython
To stitch images together
import sys
from PIL import Image
import numpy as np

list_im = []

f = open(sys.argv[1])
for x in f:
    list_im.append(x.replace("\n",""))
f.close()

imgs    = [Image.open(i) for i in list_im ]

imgs2 = []
for i in imgs:
    imgs2.append(i.rotate(0).crop((int(sys.argv[2]),0,int(sys.argv[3]),2464)))

imgs = imgs2

# pick the image which is the smallest, and resize the others to match it (can be arbitrary image shape here)
min_shape = sorted( [(np.sum(i.size), i.size ) for i in imgs])[0][1]
imgs_comb = np.hstack( (np.asarray( i.resize(min_shape) ) for i in imgs ) )

# save that beautiful picture
imgs_comb = Image.fromarray( imgs_comb)
imgs_comb.save(sys.argv[4] + '.jpg' )
image_stitch2.pyPython
to stitch images together
import sys
from PIL import Image
import numpy as np
from scipy import stats

list_im = []

f = open(sys.argv[1])
for x in f:
    list_im.append(x.replace("\n",""))
f.close()

imgs = [Image.open(i) for i in list_im ]

imgs2 = []
for i in imgs:
    imgs2.append(i.rotate(0).crop((int(sys.argv[2]),0,int(sys.argv[3]),2464)))

ud_dist = 7
lr_dist = 30


all_fronts = []
all_backs = []
for i in imgs:
    rgb_im = i.convert('RGB')
    im_fronts = []
    im_rears = []
    for k in range(int(sys.argv[2]) - lr_dist,int(sys.argv[2]) + lr_dist):
        fronts = []
        for j in range(0, 2464):
            fronts.append(sum(rgb_im.getpixel((k, j))))
        im_fronts.append(fronts)
    for k in range(int(sys.argv[3]) - lr_dist,int(sys.argv[3]) + lr_dist):
        rears = []
        for j in range(0, 2464):
            rears.append(sum(rgb_im.getpixel((k, j))))
        im_rears.append(rears)

    all_fronts.append(im_fronts)
    all_backs.append(im_rears)

#pic_num = int(sys.argv[5])

up_list = []
down_list = []
front_list = [0]
rear_list = []
for pic_num in range(len(imgs)-1):
    best = 0
    counter1 = int(sys.argv[2])-lr_dist
    counter2 = int(sys.argv[3])+lr_dist
    for x,y in zip(all_fronts[pic_num+1], all_backs[pic_num][::-1]):
        r1 = range(-ud_dist, ud_dist)
        r2 = range(-ud_dist, ud_dist)
        for a,b in zip(r1,r2[::-1]):
            slope, intercept, r_value, p_value, std_err = stats.linregress(x[400 + a:2064 + a], y[400 + b:2064 + b])
            if r_value > best:
                best = r_value
                bestc1 = counter1
                bestc2 = counter2
                besta = a
                bestb = b
        counter1 += 1
        counter2 -= 1

    print(best)
    print(bestc1)
    front_list.append(bestc1)
    rear_list.append(bestc2)
    print(bestc2)
    print(besta)
    print(bestb)
    up_list.append(besta)
    down_list.append(bestb)

rear_list.append(3280)

print(front_list)
print(rear_list)
print(up_list)
print(down_list)
print(len(front_list))
print(len(rear_list))

imgs2 = []
county = 0
for i in imgs:
    imgs2.append(i.rotate(0).crop((front_list[county],0,rear_list[county],2464)))
    county += 1


imgs = imgs2

# pick the image which is the smallest, and resize the others to match it (can be arbitrary image shape here)
min_shape = sorted( [(np.sum(i.size), i.size ) for i in imgs])[0][1]
imgs_comb = np.hstack( (np.asarray( i.resize(min_shape) ) for i in imgs ) )

# save that beautiful picture
imgs_comb = Image.fromarray( imgs_comb)
imgs_comb.save(sys.argv[4] + "_" + sys.argv[2] + "-" + sys.argv[3] + '.jpg' )

Custom parts and enclosures

Gantry part 1
Housing for the motor
Gantry part 2
Gantry part 3
Gantry part 4
Camera mount
Camera protector
Foot for gantry

Schematics

circuit diagram with arduino
Macro imager3 bb 8n1y03i16l
MacroImager prototype circuit diagram
Macro imager schem 2biploee8p
2D circuit diagram
Macro imager4 schem yv3fszis8o

Comments

Similar projects you might like

UW-Makeathon Bio-View: A modular bioreactor for cell culture

Project in progress by 3 developers

  • 1,853 views
  • 0 comments
  • 15 respects

Microbial Bioreactor

Project in progress by Team Open Bioeconomy Lab

  • 14,346 views
  • 11 comments
  • 67 respects

Aquaneers

Project in progress by Eric Lowe

  • 4,070 views
  • 2 comments
  • 6 respects

Where's my stuff?? - Find your misplaced things with Alexa!

Project in progress by Team Crakers

  • 3,018 views
  • 0 comments
  • 8 respects

Automated Microbial Fuel Cell

Project in progress by Fransie Streicher and Kaamil-Inaam Naicker

  • 1,204 views
  • 0 comments
  • 7 respects

Tito - Arduino UNO 3D-printed robot

Project tutorial by Camilo Parra Palacio

  • 18,797 views
  • 20 comments
  • 52 respects
Add projectSign up / Login