element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • 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
Artificial Intelligence and Machine Learning
  • Technologies
  • More
Artificial Intelligence and Machine Learning
Blog Person-Sensor First Test
  • Blog
  • Forum
  • Documents
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Artificial Intelligence and Machine Learning to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: ralphjy
  • Date Created: 13 Dec 2022 6:21 PM Date Created
  • Views 2952 views
  • Likes 9 likes
  • Comments 7 comments
  • Face Detection
  • usefulsensors
  • person-sensor
  • wio terminal
Related
Recommended

Person-Sensor First Test

ralphjy
ralphjy
13 Dec 2022

I had posted about a month ago about wanting to try a Person-Sensor: Has Anyone Used a Person Sensor from UsefulSensors?  I had a couple on backorder from SparkFun and I just received them yesterday.  I've started to notice that there has been improvement in availability of development boards and sensors (or maybe just stuff I use).  I just ordered another Pi Pico W and Xiao RP2040 at their normal prices.

UsefulSensors has documentation on github: Person_Sensor_Docs .

I've decided to try using the Person-Sensor with a Wio Terminal using CircuitPython.  I documented my setup in this post: CircuitPython on Wio Terminal.

Here are some pics of the Person-Sensor:

Image sensor on the frontside.

image

The backside has the Himax HX6537-A processor and a QWIIC connector.

image

I decided to 3D print a clip to mount the sensor on the Wio Terminal.  The sensor can mount with the camera facing in the same direction as the LCD screen (selfie mode) or with the camera facing away (camera mode).  The only interface to the sensor is a QWIIC connector and the Wio Terminal has Grove interfaces (pin but not size compatible).  It turns out that I only have QWIIC to GROVE adapter cables in 100mm length which is too short for the way I wanted to mount the sensor.  I used a QWIIC cable and QWIIC breakout board to extend the adapter cable as you can see in the pic.  I can now use this setup on a tripod using a cellphone mount or on a metal surface using the magnets on the back of the Wio Terminal.

image

I am going to run the CircuitPython face detection code: https://github.com/usefulsensors/person_sensor_circuit_python.  This code will also run on a Pi Pico - you can see in the code that it has to use a different I2C setup.

person_sensor_face_detection.py

# Example of accessing the Person Sensor from Useful Sensors on a Pico using
# CircuitPython. See https://usfl.ink/ps_dev for the full developer guide.

import bitmaptools
import board
import busio
import digitalio
import displayio
import struct
import time

# The person sensor has the I2C ID of hex 62, or decimal 98.
PERSON_SENSOR_I2C_ADDRESS = 0x62

# We will be reading raw bytes over I2C, and we'll need to decode them into
# data structures. These strings define the format used for the decoding, and
# are derived from the layouts defined in the developer guide.
PERSON_SENSOR_I2C_HEADER_FORMAT = "BBH"
PERSON_SENSOR_I2C_HEADER_BYTE_COUNT = struct.calcsize(
    PERSON_SENSOR_I2C_HEADER_FORMAT)

PERSON_SENSOR_FACE_FORMAT = "BBBBBBbB"
PERSON_SENSOR_FACE_BYTE_COUNT = struct.calcsize(PERSON_SENSOR_FACE_FORMAT)

PERSON_SENSOR_FACE_MAX = 4
PERSON_SENSOR_RESULT_FORMAT = PERSON_SENSOR_I2C_HEADER_FORMAT + \
    "B" + PERSON_SENSOR_FACE_FORMAT * PERSON_SENSOR_FACE_MAX + "H"
PERSON_SENSOR_RESULT_BYTE_COUNT = struct.calcsize(PERSON_SENSOR_RESULT_FORMAT)

# How long to pause between sensor polls.
PERSON_SENSOR_DELAY = 0.2

# The Pico doesn't support board.I2C(), so check before calling it. If it isn't
# present then we assume we're on a Pico and call an explicit function.
try:
    i2c = board.I2C()
except:
    i2c = busio.I2C(scl=board.GP5, sda=board.GP4)

# Wait until we can access the bus.
while not i2c.try_lock():
    pass

# For debugging purposes print out the peripheral addresses on the I2C bus.
# 98 (0x62 in hex) is the address of our person sensor, and should be
# present in the list. Uncomment the following three lines if you want to see
# what I2C addresses are found.
# while True:
#    print(i2c.scan())
#    time.sleep(PERSON_SENSOR_DELAY)

# Set up the builtin display if there's one available
try:
    display = board.DISPLAY
except:
    display = None
if display:
    bitmap = displayio.Bitmap(display.width, display.height, 2)
    palette = displayio.Palette(2)
    palette[0] = 0x000000
    palette[1] = 0xffffff
    tile_grid = displayio.TileGrid(bitmap, pixel_shader=palette)
    group = displayio.Group()
    group.append(tile_grid)
    display.show(group)

# Keep looping and reading the person sensor results.
while True:
    read_data = bytearray(PERSON_SENSOR_RESULT_BYTE_COUNT)
    i2c.readfrom_into(PERSON_SENSOR_I2C_ADDRESS, read_data)

    offset = 0
    (pad1, pad2, payload_bytes) = struct.unpack_from(
        PERSON_SENSOR_I2C_HEADER_FORMAT, read_data, offset)
    offset = offset + PERSON_SENSOR_I2C_HEADER_BYTE_COUNT

    (num_faces) = struct.unpack_from("B", read_data, offset)
    num_faces = int(num_faces[0])
    offset = offset + 1

    faces = []
    for i in range(num_faces):
        (box_confidence, box_left, box_top, box_right, box_bottom, id_confidence, id,
         is_facing) = struct.unpack_from(PERSON_SENSOR_FACE_FORMAT, read_data, offset)
        offset = offset + PERSON_SENSOR_FACE_BYTE_COUNT
        face = {
            "box_confidence": box_confidence,
            "box_left": box_left,
            "box_top": box_top,
            "box_right": box_right,
            "box_bottom": box_bottom,
            "id_confidence": id_confidence,
            "id": id,
            "is_facing": is_facing,
        }
        faces.append(face)
    checksum = struct.unpack_from("H", read_data, offset)
    print(num_faces, faces)

    # If the board has a display, draw rectangles for the face boxes, and a
    # diagonal cross if the person is facing the sensor.
    if display:
        bitmaptools.fill_region(bitmap, 0, 0, display.width, display.height, 0)
        for face in faces:
            box_left = face["box_left"]
            box_top = face["box_top"]
            box_right = face["box_right"]
            box_bottom = face["box_bottom"]
            x0 = int((box_left * display.width) / 256)
            y0 = int((box_top * display.height) / 256)
            x1 = int((box_right * display.width) / 256)
            y1 = int((box_bottom * display.height) / 256)
            print(x0, y0, x1, y1)
            print(display.width, display.height)
            bitmaptools.draw_line(bitmap, x0, y0, x1, y0, 1)
            bitmaptools.draw_line(bitmap, x1, y0, x1, y1, 1)
            bitmaptools.draw_line(bitmap, x1, y1, x0, y1, 1)
            bitmaptools.draw_line(bitmap, x0, y1, x0, y0, 1)
            if face["is_facing"]:
                bitmaptools.draw_line(bitmap, x0, y0, x1, y1, 1)
                bitmaptools.draw_line(bitmap, x1, y0, x0, y1, 1)

    time.sleep(PERSON_SENSOR_DELAY)

The sensor is designed to operate standalone, so face detection is always running.  You can see in the test video that the green LED will turn on whenever a face is detected.  The CircuitPython program is reading the detection info on the I2C bus and prints to the Serial monitor and also displays bounding boxes on the Wio Terminal screen to show the location(s) of the detected face(s).  If the face is facing the camera the program will draw an X in the bounding box.

The hardest part of documenting this stuff is trying to capture video of the device screen, so I apologize for the poor quality.

You can see from the reflection in the Wio Terminal screen my face when it is detected and how the bounding box moves and changes size with my location and proximity (horizontal movement is reversed in selfie mode).  You can also see the "X" disappear when I turn my head.

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

Here are a couple of captures of data from the Mu Serial Window.  0 [] indicates that a face was not detected.

image

image

  • Sign in to reply

Top Comments

  • ralphjy
    ralphjy over 2 years ago in reply to baldengineer +1
    It is advertised as 150mW @ 3.3V, but have not measured it. I can probably try that later. I need to dig up my QWIIC breadboard cables. Might be this weekend before I get a chance…
  • ralphjy
    ralphjy over 2 years ago in reply to baldengineer +1
    baldengineer Here are a couple of captures from the profiler - first without face detection and second with detection. So, power is somewhat higher that 150 mW but in the ball park. Looks like the inferencing…
  • ralphjy
    ralphjy over 2 years ago in reply to baldengineer

    baldengineer Here are a couple of captures from the profiler - first without face detection and second with detection.  So, power is somewhat higher that 150 mW but in the ball park.  Looks like the inferencing rate is about 3 FPS.  Sorry, hard to get alignment without a sync.

    image

    image

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • ralphjy
    ralphjy over 2 years ago in reply to dang74

    It's the same processor that is used on the Himax WE-I Plus EVB Endpoint AI Development Board.  So, if you could get access to it - you could reprogram the AI model -> HIMAX_WE1_EVB_user_guide.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • ralphjy
    ralphjy over 2 years ago

    An interesting observation.

    I just tried the person-sensor on my wife and the granddog sitting on the couch and the facial detection will detect the granddog most of the time (although not as consistently as my wife).  It also correctly identifies the gaze, so I think the detection is picking up the eyes.  I was running on battery, so I don't have a log of the confidence level.  I think I may add an LED to indicate when it is above a confidence level.  I guess I should print it on the display also.

    So, identifying animal faces could be an issue or feature depending on your application.  The firmware can't be updated, so it is what it is...

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • dang74
    dang74 over 2 years ago

    The Himax HX6537 microcontroller on the little module seems pretty interesting.  Apparently it includes a DSP block that can be clocked at 400MHz.  I guess that might be the secret sauce that allows it to detect a human face.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • ralphjy
    ralphjy over 2 years ago in reply to baldengineer

    It is advertised as 150mW @ 3.3V, but have not measured it.  I can probably try that later.  I need to dig up my QWIIC breadboard cables.  Might be this weekend before I get a chance…

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
>
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