Kevin Richmond
Published © GPL3+

Forkin' Great: The Ultimate Cutlery Classifier

Machine Learning and image manipulation to compare model performances

IntermediateFull instructions provided2 hours1,546
Forkin' Great: The Ultimate Cutlery Classifier

Things used in this project

Hardware components

Arduino Portenta H7
Arduino Portenta H7
Arduino Portenta H7 Vision Shield
×1
Arduino Portenta Vision Shield - Ethernet
Arduino Portenta Vision Shield - Ethernet
×1

Software apps and online services

Edge Impulse Studio
Edge Impulse Studio
MicroPython
MicroPython

Story

Read more

Schematics

TensorFlow Lite (int8 quantized)

Machine Learning code to support main.py file. Should also be uploaded to the Arduino Portenta H7

Code

JPG Image editor - Filters.py

Python
Code to apply filters to JPG images. Its assuming that the JPG images are the only files in the same folder than the code
#!/usr/bin/env python
# coding: utf-8

import os
import numpy as np
import PIL
from PIL import Image
from PIL import ImageFilter
from PIL import ImageEnhance
from PIL import ImageOps

files_in_path = os.listdir()
files_in_path_lst = []

for fip in files_in_path:
    files_in_path_lst.append(fip)

for i in files_in_path_lst:

    aux = i[-4:]
    name = i[:-4]
    ext = ".jpg"

    if aux == ext:

        orig = Image.open(i)

        moreEdgeEnahnced = orig.filter(ImageFilter.EDGE_ENHANCE_MORE)  # If image quality is high the enhance of the edges works better!
        edges_strong = moreEdgeEnahnced.filter(ImageFilter.FIND_EDGES)
        ty = "edges "
        fn = ty + name + ext
        edges_strong.save(fn)

        emboss = orig.filter(ImageFilter.EMBOSS)
        ty = "emboss "
        fn = ty + name + ext
        emboss.save(fn)

        contour = orig.filter(ImageFilter.CONTOUR)
        ty = "contour "
        fn = ty + name + ext
        contour.save(fn)

main.py

Python
Upload this file directly to the Arduino Portenta H7
# https://www.hackster.io/mjrobot/mug-or-not-mug-that-is-the-question-d4062a#toc-connecting-portenta-with-edge-impulse-studio-11

import sensor, image, time, tf
import pyb

ledForkRed = pyb.LED(1)  # Initiates the red led when it recognises a fork
ledKnifeGreen = pyb.LED(2)  # Initiates the green led when it recognises a knife
ledSpoonBlue = pyb.LED(3)  # Initiates the blue led when it recognises a spoon

model_file = "ei-image-classifier_-cutlery-(grayscale)-transfer-learning-tensorflow-lite-int8-quantized-model.lite"

labels = ["background", "fork", "knife", "spoon"]  # Edge Impulse usually keeps labels in alphabetical order

sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)  # Set pixel format for Portenta H7 Vision Shield
sensor.set_framesize(sensor.QVGA)  # Set frame size to QVGA
sensor.set_windowing((96, 96))  # Crop to Edge Impulse model resolution
sensor.skip_frames(time=2000)  # Let the camera adjust

clock = time.clock()  # Start clock (for measureing FPS)

while (True):

    # Update timer
    clock.tick()

    # Get image from camera
    img = sensor.snapshot()
    img.set(h_mirror=True)

    # Do inference and get predictions
    objs = tf.classify(model_file, img)
    predictions = objs[0].output()

    # Find label with the highest probability
    max_val = max(predictions)
    max_idx = predictions.index(max_val)

    if max_idx == 0:  # turn on all the leds to show a white blink for background
        ledForkRed.on()
        ledKnifeGreen.on()
        ledSpoonBlue.on()

    elif max_idx == 1:  # turn on red LED for forks
        ledForkRed.on()
        ledKnifeGreen.off()
        ledSpoonBlue.off()

    elif max_idx == 2:  # turn on green LED for knifes
        ledForkRed.off()
        ledKnifeGreen.on()
        ledSpoonBlue.off()

    else:  # turn on blue LED for spoons
        ledForkRed.off()
        ledKnifeGreen.off()
        ledSpoonBlue.on()

    # Draw label with highest probability to image viewer
    img.draw_string(0, 0, labels[max_idx] + "\n{:.2f}".format(round(max_val, 2)), mono_space=False, scale=1)

    # Print all the probabilities
    print("-----")
    for i, label in enumerate(labels):
        print(str(label) + ": " + str(predictions[i]))
    print("FPS:", clock.fps())

Credits

Kevin Richmond

Kevin Richmond

7 projects • 2 followers
Engineer passionate about automation, IoT, Machine Learning and sustainability.

Comments