element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Save The Bees Design Challenge
  • Challenges & Projects
  • Design Challenges
  • Save The Bees Design Challenge
  • More
  • Cancel
Save The Bees Design Challenge
Blog ZinnBee Blog#04: First Impression of Arduino Nicla Vision Machine Learning Process
  • Blog
  • Forum
  • Documents
  • Leaderboard
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Save The Bees Design Challenge to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: flyingbean
  • Date Created: 4 Apr 2023 3:36 AM Date Created
  • Views 933 views
  • Likes 10 likes
  • Comments 0 comments
  • save the bees
  • nicla vision
  • openmv
  • edge impulse
Related
Recommended

ZinnBee Blog#04: First Impression of Arduino Nicla Vision Machine Learning Process

flyingbean
flyingbean
4 Apr 2023

Part 01:  Arduino Nicla Vision Module

Arduino Nicla Vision module is a fun breakout board. I really appreciated that Element 14 gave me an opportunity to evaluate this module during the ZinnBee project. You might read all the features about the breakout board from Arduino website if you like. I will focus on the machine vision for ZinnBee project first.

  1. Time-of-Flight sensor, which is a good trouble-shoot application to recovery my bricked Arudino Nicla module. Sometimes, if I updated the OpenMV firmware/library, especially if I need more RAM/flash for bigger dataset, unexpectedly “bricked Nicla Vision” error message might be happening. I am still in the middle of trouble-shooting why I got “bricked Nicla Vision” status as below.

image

Fig 1.  Bricked Arduino Nicla Vision Module (Really?!)

I did not have such issues until I started to select bigger size images under Edge Impulse image training flow last week.

There are two methods to avoid such show-stopper while you exploring the features of ML algorithm on Arduino Nicla Vision module.

Method A: Running Arduino Time-of-Flight sensor application to flash out all the previous contents on the flash. Then start the ML flow on OpenMV IDE.

Method B: Don’t update OpenMV Cam’s firmware after flashing bootloader as below:

image

                        Fig 2.   Upgrade OpenMV Cam’s Firmware or Not ?

                I found that sometime I did need both method A and B to overcome Bricked Nicla Vision Cam issue. I still don’t know the root cause of that at this moment.

           2. More out-of-box examples from OpenMV IDE for Arduino Nicla Vision module are presented as below:

image

                          Fig 3:   OOB Examples of Arduino Nicla Vision from OpenMV IDE

               I planed to use i2c_control.py/spi_control.py/timer_control.py for ZinnBee project if I need.

 Part 02: Edge Impulse  ML Flow

There are many features from Edge Impulse tool. The easiest way to understand Edge Impulse is to reproduce a project from Edge Impulse website. There is a simple demonstration of Analog Meter Reading project on Arduino Nicla Vision (Ref[2]). The greatest value I learned from the reproduction of Analog Meter Reading experiment is how to tune the dataset of images for ML on Edge Impulse tool chain and use Zinne Analog Meter Reading experiment to calibrate ML Edge Impulse flow or troubleshoot the unexpected issues, such as Bricked Nicla Vision module.

Here is the process of ZinnBee Analog Meter Reading experiment.

  1. Setup the bench testing equipment and collect images for the dataset.

            I used a 3D printer to print an enclosure for Arduino Nicla Vision module. Here is my small bench studio:

image

                                 Fig 4:   ZinnBee Bench Photo Studio

2. Image processing of the dataset

I used Python3 to process the temperature meter photos, which were used for the dataset at Edge Impulse ML flow. You might find the source codes from Ref[2], which used Python Jupyter Notebook. The post-process images as the dataset for Edge Impulse are presented in the video.

Here is the updated Python code to post-image dataset processing.

import os
import numpy as np
#import pandas as pd
import matplotlib

import matplotlib.pyplot as plt

from PIL import Image

#matplotlib inline

import matplotlib.pyplot as plt
import matplotlib.image as mpimg



# Declare variables
#NEEDLE = './Meter_images/meter_needle08.jpg'
NEEDLE = './Meter_images/needle01.png'  # front
GAUGE = './Meter_images/meter_03_try02.jpg'


image = Image.open(NEEDLE).convert('RGBA')
image_rot_0 = image.rotate(0, expand=False, resample=Image.BICUBIC) # adjust this value to rotate the needle to the starting (zero) position
image_rot_0.save('./Meter_images/needles/needle_rot_0.png')
plt.imshow(image_rot_0)
plt.show()

 
# Gauge background
image = Image.open(GAUGE).convert('RGBA')
gauge_zero = image.copy()
gauge_zero.paste(image_rot_0.convert('L'), (0, 0), image_rot_0.convert('RGBA'))
    
plt.imshow(gauge_zero)
plt.show()

PATH = "./Meter_images/needles/needle_rot_{0}.png"
def make_needles(angle):
    img = Image.open('./Meter_images/needles/needle_rot_0.png')
    x = img.rotate(-angle, expand=True, resample=Image.BICUBIC)
    # crop the rotated image to the size of the original image
    x = x.crop(box=(x.size[0]/2 - img.size[0]/2,
               x.size[1]/2 - img.size[1]/2,
               x.size[0]/2 + img.size[0]/2,
               x.size[1]/2 + img.size[1]/2))
    
    dash = str(angle).replace(".","-")
    filename = PATH.format(dash)

    x.save(filename)

for angle in np.arange(0, 360.0,4.5):
    make_needles(angle)
    
    
NEEDLES_PATH = "./Meter_images/needles/needle_rot_{0}.png"
EDA_GAUGES = "./Meter_images/gauges/{0}"

def save_gauge(item, num):
    img_gauge = Image.open(GAUGE, 'r')

    filename = NEEDLES_PATH.format(str(item).replace(".","-"))
    img_needle = Image.open(filename, 'r')
    img_copy = img_gauge.copy()

    img_copy.paste(img_needle.convert('L'), (0, 0), img_needle.convert('RGBA'))
    
    # Save the synthetic image to the class folder
    string_num = str(num)
    dash = string_num.replace(".","-")

    # Save PNG for EDA
    eda_name = "gauge_{0}.png".format(dash)
    img_copy.save( EDA_GAUGES.format(eda_name) )

def iterate_gauge(mapping):
    for idx, item in enumerate(mapping):
        save_gauge(mapping[item], item)
        
        
# Define a mapping between degrees in circle and gauge readings

# adjust this according to your gauge (value:angle)
gaugeDegreeMap = {
    0.0:0.0, 0.1:4.5, 0.2:9.0, 0.3:13.5, 0.4:18.0, 0.5:22.5, 0.6:27.0, 0.7:31.5, 0.8:36.0, 0.9:40.5, 
    1.0:45.0, 1.1:49.5, 1.2:54.0, 1.3:58.5, 1.4:63.0, 1.5:67.5, 1.6:72.0, 1.7:76.5, 1.8:81.0, 1.9:85.5, 
    2.0:90.0, 2.1:94.5, 2.2:99.0, 2.3:103.5, 2.4:108.0, 2.5:112.5, 2.6:117.0, 2.7:121.5, 2.8:126.0, 2.9:130.5, 
    3.0:135.0, 3.1:139.5, 3.2:144.0, 3.3:148.5, 3.4:153.0, 3.5:157.5, 3.6:162.0, 3.7:166.5, 3.8:171.0, 3.9:175.5, 
    4.0:180.0, 4.1:184.5, 4.2:189.0, 4.3:193.5, 4.4:198.0, 4.5:202.5, 4.6:207.0, 4.7:211.5, 4.8:216.0, 4.9:220.5, 
    5.0:225.0, 5.1:229.5, 5.2:234.0, 5.3:238.5, 5.4:243.0, 5.5:247.5, 5.6:252.0, 5.7:256.5, 5.8:261.0, 5.9:265.5, 
    6.0:270.0, 6.1:274.5, 6.2:279.0, 6.3:283.5, 6.4:288.0, 6.5:292.5, 6.6:297.0, 6.7:301.5, 6.8:306.0, 6.9:310.5,
    7.0:315.0, 7.1:319.5, 7.2:324.0, 7.3:328.5, 7.4:333.0, 7.5:337.5, 7.6:342.0, 7.7:346.5, 7.8:351.0, 7.9:355.5,
    8.0:360.0
}

# Iterate through the lookup map
iterate_gauge(gaugeDegreeMap)

You might watch the video for the final image candidates for Edge Impulse.

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

              3. Performance evaluation of Edge Impulse

             I did multiple iterations to get a good ML result on the bench testing. I selected 3 Edge Impulse training cases for this blog.

             Edge Impulse training case 01: exact procedure as Ref[3]. The training accuracy is about 81.8% for my dataset.

image

Fig 5: Edge Impulse training case 01: RGB Image + 20 Training Cycles

            Edge Impulse training case 02: updated the image from RGB to grayscale. The accuracy  of the training model is 90.9%.

image

Fig 6: Edge Impulse training case 02: Graycale Image + 20 Training Cycles

             Edge Impulse training case 03:  the image is set as grayscale and upgrade the number of training cycles from 20(default) to 40. The accuracy of ML training model is 100%.

image

Fig 7: Edge Impulse training case 03: Graycale Image + 40 Training Cycles

 I took a short video for the bench testing of the deployed case 03.Edge Impulse training case 03

Part 03:  ZinnBee  Analog Meter Reading Experiment Summary

I reviewed the dataset I uploaded into Edge Impulse and the corresponding labeled images as below:

image

image

                                                 Fig 8: Images Labeled Normal and High (no other image between these two)

These two images are at the edge for the classification between High and Normal. I did give Edge Impulse ML flow a challenge for the classification of the experiment. The bench testing on case 03 shew that Arduino Nicla Vision module thought the temperature was constant high from all the angle of the camera view. More work will be needed for ML flow on my next blog.

  Part 04:  Kick off ZinnBee Lego-lab ML Experiment

I kicked off ZinnBee Lego-lab ML experiment last week. However, there were some interested results from the Edge Impulse ML flow I could not understand well. So I came back to finish the blog on ZinnBee Temperature Meter experiment, which could be an aid to guide me to finish ZinnBee Lego-lab ML experiment. Here is my ZinnBee Lego-lab content.

image

Fig 9:  ZinnBee Lego-Lab ML Experiment Setup

There are 4 objects: boy, mice, big dinosaur and tiny dinosaur. ZinnBee Lego-lab experiment need to identify 4 different objects properly. I will describe the process of the experiment on my next blog.

References:

Ref [1]  https://docs.arduino.cc/tutorials/mkr-iot-carrier/mkr-iot-carrier-01-technical-reference#humidity--temperature-sensor

Ref [2]  https://docs.edgeimpulse.com/experts/featured-machine-learning-projects/analog-meter-reading-with-nicla-vision

 

ZinnBee Blogs as below:

 ZinnBee Blog#01: Introduction of the Project

ZinnBee Blog#02: Initial Project Structure

ZinnBee Blog#03: LoRa WAN Communication Framework

  • Sign in to reply
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube