Face detection with OpenMV M7 and Arduino UNO

Good day, I am new in IOT field. Allow me to ask some question. I am planning to design a smart obejct which could tracking human face by using Openmv M7 and 360 high speed parallax servo motor. The function of servo motor is to rotate the smart object until it is facing the centre of human face. Only one face will be detected at the same time. For now, my Arduino UNO gained the information of the rectangle drawn on the human face in string form. How to get only the x coordinate and the width of the rectangle drawn in order to find its centre? As I will design a pair of artificial eyes to provide feedback to user, Arduino UNO is needed. Any solution could be provided to help in my project? The script attached is the coding I am using currently. Thanks for helping.

In OpenMV IDE:

import sensor, time, image, pyb
from pyb import UART
uart = UART(3, 9600, timeout_char = 1000)
# Reset sensor
sensor.reset()

# Sensor settings
sensor.set_contrast(1)
sensor.set_gainceiling(16)
# HQVGA and GRAYSCALE are the best for face tracking.
sensor.set_framesize(sensor.HQVGA)
sensor.set_pixformat(sensor.GRAYSCALE)

# Load Haar Cascade
# By default this will use all stages, lower satges is faster but less accurate.
face_cascade = image.HaarCascade("frontalface", stages=25)
print(face_cascade)

# FPS clock
clock = time.clock()

while (True):
    clock.tick()

    # Capture snapshot
    img = sensor.snapshot()

    # Find objects.
    # Note: Lower scale factor scales-down the image more and detects smaller objects.
    # Higher threshold results in a higher detection rate, with more false positives.
    objects = img.find_features(face_cascade, threshold=0.75, scale_factor=1.25)

    # Draw objects

    for a in objects:
        img.draw_rectangle(a)
        print(str(a))
        uart.write(str(a))
        uart.write('\n')

In Arduino UNO:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX


void getline(char *buffer, int max_len)
{
  uint8_t idx = 0;
  char c;
  do
  {
    if(idx >= max_len) return;
    while (mySerial.available() == 0) ; // wait for a char this causes the blocking
    c = mySerial.read();
    buffer[idx++] = c;
  }
  while (c != '\n' && c != '\r'); 
  if(idx >= max_len) return;
  buffer[idx] = 0;
}

void setup() {
Serial.begin(9600);
mySerial.begin(9600); 
}

void loop(){
  char buffer [63+1];
  int max_len = 63;
  getline(buffer, max_len);
  Serial.print(buffer);
}

http://docs.openmv.io/library/omv.image.html?highlight=find_features#image.image.find_features

This method searches the image for all areas that match the passed in Haar Cascade and returns a list of bounding box rectangles tuples (x, y, w, h) around those features. Returns an empty list if no features are found.

so a[0] and a[2]

Thks for teaching me this, I gained what data I want. However, how do i separate the x coordinate and width received by the Arduino UNO into an two integers so that i could do some coding to get the center of the objecy if my coding is changed as follow?
Your help is really appreciated. Thank you so much.

OpenMV coding:

    for a in objects:
        img.draw_rectangle(a)
        print(a[0],a[2])
        uart.writechar(a[0])
        uart.writechar(a[2])
        uart.write('\n')

Arduino coding:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  while (!Serial) {
    ; 
  }
}

void loop() {
  while (mySerial.available() > 0) {
    int inChar = mySerial.read();
    Serial.println(inChar);
  }
}

Hi, please see the ustruct pack docs:

https://docs.micropython.org/en/latest/library/ustruct.html?highlight=ustruct%20pack#ustruct.pack

Actually ustruct might not work here, try something like this

uart.write(a[0]))
or
uart.write("%d\n"%(a[0])

And on Arduino see https://www.arduino.cc/en/Tutorial.StringToIntExample


Note this is a general Arduino issue you can find more examples if you google.

Thank you for your help, this really helped me a lot!
I already figure out the solution. Thanks again.

Hi, sorry for troubling again. May I know is it possible to detect only the first face and ignore the second one? Thanks for helping.

No the whole image is scanned, left to right and top to bottom.