赞
踩
人脸识别模块选用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只当一个视觉识别模块处理。
屏幕我选用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,不是时间,时间要靠晶振时钟频率去算,我赖得算。。。 } }
加入DHT11模块然后在oled进行温度显示
然后加入霍尔编码器或者光电编码器就可以测小车速度了
这些都太简单了,懒得做,可以自己自行添加。
openmv人脸识别开启屏幕
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。