這里寫目錄標題
- 作品要求:
- 一、作品設計與模塊選擇
- 1.可以感應人臉
- 2.感應到人臉時開啟顯示屏顯示
- 3.顯示溫度、速度等
- 實驗效果
作品要求:

一、作品設計與模塊選擇
1.可以感應人臉
人臉識別模塊選用openmv模塊,因為opencv用起來相對復雜,
用官方人臉識別示例代碼進行修改,得出以下代碼:
獲取照片:
像素點是92,112的,并且是灰度圖,pgm格式,存在singtown中,然后在singtown檔案夾中再新建n個名為s1,s2,s3…sn的子檔案夾,其中n為整個影像庫中的人數,
#快照示例
#
#注意:你需要一個SD卡來運行這個例子,
#
#你可以使用你的OpenMV攝像機來保存影像檔案,
import sensor, image, pyb
RED_LED_PIN = 1
BLUE_LED_PIN = 3
sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.GRAYSCALE) # or sensor.GRAYSCALE
sensor.set_framesize(sensor.B128X128) # or sensor.QQVGA (or others)
sensor.set_windowing((92,112))
sensor.skip_frames(10) # Let new settings take affect.
sensor.skip_frames(time = 2000)
num = 1 #設定被拍攝者序號,第一個人的圖片保存到s1檔案夾,第二個人的圖片保存到s2檔案夾,以此類推,每次更換拍攝者時,修改num值,
n = 20 #設定每個人拍攝圖片數量,
#連續拍攝n張照片,每間隔3s拍攝一次,
while(n):
#紅燈亮
pyb.LED(RED_LED_PIN).on()
sensor.skip_frames(time = 3000) # Give the user time to get ready.等待3s,準備一下表情,
#紅燈滅,藍燈亮
pyb.LED(RED_LED_PIN).off()
pyb.LED(BLUE_LED_PIN).on()
#保存截取到的圖片到SD卡
print(n)
sensor.snapshot().save("singtown/s%s/%s.pgm" % (num, n) ) # or "example.bmp" (or others)
n -= 1
pyb.LED(BLUE_LED_PIN).off()
print("Done! Reset the camera to see the saved image.")
其原理是根據圖片和現在拍攝的相似度去判斷識別人臉
LBP人臉識別代碼:
NUM_SUBJECTS = 1 #影像庫中不同人數,一共1人
你要識別幾張臉,就改為幾
import sensor, time, image, pyb
from pyb import UART #添加串口
sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.GRAYSCALE) # or sensor.GRAYSCALE
sensor.set_framesize(sensor.B128X128) # or sensor.QQVGA (or others)
sensor.set_windowing((92,112))
sensor.skip_frames(10) # Let new settings take affect.
sensor.skip_frames(time = 5000) #等待5s
uart = UART(3, 9600) #設定好串口通信協議
#SUB = "s1"
NUM_SUBJECTS = 1 #影像庫中不同人數,一共6人
NUM_SUBJECTS_IMGS = 20 #每人有20張樣本圖片
def min(pmin, a, s):
global num
if a<pmin:
pmin=a
num=s
return pmin
while(1):
# 拍攝當前人臉,
img = sensor.snapshot()
#img = image.Image("singtown/%s/1.pgm"%(SUB))
d0 = img.find_lbp((0, 0, img.width(), img.height()))
#d0為當前人臉的lbp特征
img = None
pmin = 999999
num=0
for s in range(1, NUM_SUBJECTS+1):
dist = 0
for i in range(2, NUM_SUBJECTS_IMGS+1):
img = image.Image("singtown/s%d/%d.pgm"%(s, i))
d1 = img.find_lbp((0, 0, img.width(), img.height()))
#d1為第s檔案夾中的第i張圖片的lbp特征
dist += image.match_descriptor(d0, d1)#計算d0 d1即樣本影像與被檢測人臉的特征差異度,
print("Average dist for subject %d: %d"%(s, dist/NUM_SUBJECTS_IMGS))
pmin = min(pmin, dist/NUM_SUBJECTS_IMGS, s)#特征差異度越小,被檢測人臉與此樣本更相似更匹配,
print(pmin)
print(num) # num為當前最匹配的人的編號,
if(num==1 and pmin<=5000): #如果是第一個人,并且差異度小于5000
print("adan") #則列印我的名字出來
uart.write("adan") #則用串口列印我的名字給arduino,然后就可以用arduino進行判斷了

實際上可以用openmv進行操作顯示屏和獲取溫濕度,速度等等操作,因為它本身就是個STM32單片機,但是操作起來相對麻煩,所以選用了arduino進行通信控制,openmv只當一個視覺識別模塊處理,
2.感應到人臉時開啟顯示屏顯示
螢屏我選用oled顯示屏,oled顯示屏示例代碼(簡潔):
//顯示中英文字符程式
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
//#define LOGO16_GLCD_HEIGHT 16 //定義顯示高度
//#define LOGO16_GLCD_WIDTH 16 //定義顯示寬度
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
void setup() {
Serial.begin(9600);
// 默認情況下,我們將從3.3v線內部產生高電壓!
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //初始化I2C地址0x3D(對于128x64)
//初始化完成
display.clearDisplay(); //清屏
//英文字符顯示,直接用display.println或print顯示字串就行
//println換行,print不換行
display.setTextSize(1); //設定字體大小
display.setTextColor(WHITE); //設定字體顏色白色
display.setCursor(0,0); //設定字體的起始位置
display.println("Hello, world!"); //輸出字符并換行
display.setTextColor(BLACK, WHITE); //設定字體黑色,字體背景白色
display.println(3.141592); //輸出數字并換行
display.setTextSize(2); //設定字體大小
display.setTextColor(WHITE); //設定字體白色
display.print("0x"); //輸出字符
display.println(0xDEADBEEF, HEX); //輸出為ASCII編碼的十六進制
display.display(); //顯示以上
}
void loop() {
}
根據oled顯示代碼,加個串口中斷,然后在串口中斷執行顯示,我們的效果就出來了:
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
volatile int flag;
String shuju;
int xs_biaozhi; //顯示標志
unsigned long delay_data; //延時資料
void setup() {
Serial.begin(9600);
// 默認情況下,我們將從3.3v線內部產生高電壓!
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //初始化I2C地址0x3D(對于128x64)
//初始化完成
display.clearDisplay(); //清屏
flag = 0;
shuju = "0";
Serial.begin(9600);
display.setTextSize(3); //字體大小
display.setTextColor(SSD1306_WHITE); //字體顏色
display.setCursor(0, 0); //字體位置
display.println("Hello, world!"); //輸出字符并換行
display.display(); //顯示出來
delay(1000);
display.clearDisplay(); //清屏
display.setTextSize(1); //字體大小
display.setTextColor(SSD1306_WHITE); //字體顏色
display.setCursor(0, 0); //字體位置
display.println(" "); //輸出字符并換行
display.display(); //顯示出來
delay(1000);
}
void loop() {
use_delay();
uart_chuli();
}
void uart_chuli() //串口處理
{
if (flag == 1) {
Serial.println(shuju);
uart_dispose();
shuju = "";
flag = 0;
}
}
void use_delay() //自定義延時函式
{
if (xs_biaozhi == 1) //如果顯示標志為1
{
delay_data--; //延時資料自減
if (delay_data == 0) //如果延時資料減到0,則清空螢屏不顯示
{
xs_biaozhi = 0;
display.clearDisplay(); //清屏
display.setTextSize(1); //字體大小
display.setTextColor(SSD1306_WHITE); //字體顏色
display.setCursor(0, 0); //字體位置
display.println(" "); //輸出字符并換行
display.display(); //顯示出來
}
}
}
void serialEvent() {
while (Serial.available() > 0)
{
shuju = shuju + char(Serial.read());
delay(2);
flag = 1;
}
}
void uart_dispose() {
if (shuju == "adan")
{
display.setTextSize(2); //字體大小
display.setCursor(64, 32); //字體位置
display.println(shuju); //輸出字符并換行
display.display(); //顯示出來
delay(100);
xs_biaozhi = 1; //顯示標志至1
delay_data=50000; //延時資料為50000,不是時間,時間要靠晶振時鐘頻率去算,我賴得算,,,
}
}
3.顯示溫度、速度等
加入DHT11模塊然后在oled進行溫度顯示
然后加入霍爾編碼器或者光電編碼器就可以測小車速度了
這些都太簡單了,懶得做,可以自己自行添加,
實驗效果
openmv人臉識別開啟螢屏
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/310669.html
標籤:其他
