赞
踩
大二的时候做的一个东西,也算是花了不少的心血,所以希望记录下来,也能给其他的小伙伴有一点点参考。由于是自己摸索,所以可能说的不是很清楚或者显得很业余。后来还把小车和智能家居联合起来了,小车可以控制智能家居,智能家居也可以控制小车。主要还是做的功能整合,把之前控制传感器的代码和语音识别、人脸识别的功能结合起来,然后做了web端对沙盘的一些控制,例如灯、舵机这些操作。
后面也有了新的设备,可是也没什么时间更新,很多的功能和代码都来得及写,以后会补上的。如果是想做毕业设计的小伙伴可以和我联系,可以远程协助,包括环境的安装,代码的调试。
1.前期是几千个小积木一点点拼起来的,后来自己用木板做了一个小沙盘,最后拿了奖金,买了个沙盘。
2.设备是树莓派4B,我的是8G内存的,性能剩余太多了,有点浪费
3.烟雾传感器、火焰传感器、雨滴传感器、土壤湿度传感器、震动传感器、超声波传感器、温湿度传感器、红外发射与接收模块
3.夜视摄像头、体感摄像头、自己焊接的一个小音响,我的体感摄像头是有麦克风的,所以不用单独搞一个麦克风,设置一下体感摄像头为默认麦克风输入。
4.MG90舵机
5.目前还有一个stm32f1的板子和51单片机开发板,还在纠结应该做些什么比较好,放着也是吃灰
语音识别是上面很多功能的基础,首先通过snowboy的关键词唤醒,可以自己官网制作属于自己的唤醒模型(因为我懒,测试的时候把灵敏度拉满,于是大喊一声也成),程序使用录音软件进行录音,并且保存在本地文件,调用百度语音识别进行识别,此时将返回的结果保存为文本,来一个正则表达式。
接下来就是朴实无华的语音合成,语音播报其实就是我将录制好的音频文件,在某个if()满足条件的时候就播放出来,例如人脸识别的时候,如果识别通过,就播放欢迎回来,xx。没识别到人脸也给出提示:未识别到人脸,如果不在人脸库的时候,就播放:我不认识你哦。其实我觉得百度语音技术挺好用的,而且还有那么多次的免费调用,用在自己个人学习绰绰有余,几万次的调用,正常人用不完。
放一部分代码
import snowboydecoder import signal import wave import sys import json import requests import time import os import base64 from pyaudio import PyAudio, paInt16 import webbrowser from fetchToken import fetch_token interrupted = False endSnow = False framerate = 16000 num_samples = 2000 channels = 1 sampwidth = 2 FILEPATH = './audio/audio.wav' TTS_URL = 'http://tsn.baidu.com/text2audio' music_exit = './audio/exit.wav' music_open = './audio/open.wav' os.close(sys.stderr.fileno()) def signal_handler(signal, frame): global interrupted interrupted = True def interrupt_callback(): global interrupted return interrupted def detected(): play('./audio/open.wav') global interrupted interrupted = True detector.terminate() def play(filename): wf = wave.open(filename, 'rb') p = PyAudio() stream = p.open(format=p.get_format_from_width(wf.getsampwidth()), channels=wf.getnchannels(), rate=wf.getframerate(), output=True) data = wf.readframes(1024) while data != b'': data = wf.readframes(1024) stream.write(data) stream.stop_stream() stream.close() p.terminate() def save_wave_file(filepath, data): wf = wave.open(filepath, 'wb') wf.setnchannels(channels) wf.setsampwidth(sampwidth) wf.setframerate(framerate) wf.writeframes(b''.join(data)) wf.close() def my_record(): pa = PyAudio() stream = pa.open(format=paInt16, channels=channels, rate=framerate, input=True, frames_per_buffer=num_samples) my_buf = [] # count = 0 t = time.time() while time.time() < t + 5: string_audio_data = stream.read(num_samples) my_buf.append(string_audio_data) save_wave_file(FILEPATH, my_buf) stream.close() def speech2text(speech_data, token, dev_pid=1537): FORMAT = 'wav' RATE = '16000' CHANNEL = 1 CUID = 'baidu_workshop' SPEECH = base64.b64encode(speech_data).decode('utf-8') data = { "format": "wav", "rate": 16000, 'dev_pid': 1537, 'channel': 1, 'token': "*", 'cuid': "baidu_workshop", 'len': len(speech_data), 'speech': "base64.b64encode(speech_data).decode('utf-8')" } url = 'http://vop.baidu.cpm/server_api' headers = {'Content-Type': 'application/json'} r = requests.post(url, json=data, headers=headers) Result = r.json() if 'result' in Result: return Result['result'][0] else: return Result def get_audio(file): with open(file, 'rb') as f: data = f.read() return data if __name__ == "__main__": while endSnow == False: interrupted = False detector = snowboydecoder.HotwordDetector('zpf.pmdl', sensitivity=1) detector.start(detected_callback=detected, interrupt_check=interrupt_callback, sleep_time=0.03) my_record() TOKEN = fetch_token() speech = get_audio(FILEPATH) result = speech2text(speech, TOKEN, int(80001)) if type(result) == str: identifyComplete(result.strip(', '))
嗯,调用的还是百度的人脸识别,也是免费的。这个我这几天忙完会把代码传上来。主要思路就是在识别到人脸的时候,if(相似度超过80),这个时候就把门打开,否则提示不在人脸库。
from aip import AipFace from picamera import PiCamera import urllib.request import RPi.GPIO as GPIO import base64 import time from snow import * from hc import * from snow import * APP_ID ='*' API_KEY ='*' SECRET_KEY ='*' client = AipFace(APP_ID, API_KEY, SECRET_KEY) IMAGE_TYPE='BASE64' camera = PiCamera() GROUP ='zpf' def getimage(): camera.resolution =(1024,768) camera.start_preview() camera.capture('faceimage.jpg') def transimage(): f = open('faceimage.jpg','rb') img = base64.b64encode(f.read()) return img def go_api(image): result = client.search(str(image,'utf-8'), IMAGE_TYPE, GROUP); if result['error_msg'] == 'SUCCESS': name = result['result']['user_list'][0]['user_id'] score = result['result']['user_list'][0]['score'] if score > 80: if name == 'zpf': door() play(result_au) else: print("对不起,我不认识你!") name = 'Unknow' return 0 return 1 if result['error_msg'] == 'pic not has face': print('检测不到人脸') return 0 else: print(result['error_code']) return 0 if __name__ == '__main__': while True: print('准备') if True: getimage() img = transimage() res = go_api(img) time.sleep(1)
至于开门的话,我用的是MG90舵机,老样子写好函数,如果满足开门条件,就让舵机把门拉开,至于多少角度的话就需要计算了哈哈哈。舵机我是接在树莓派的11物理引脚上面的,通过调节PWM的占空比控制舵机的转向角度。代码发出来了,大家稍微改一下角度和引脚就可以使用了。
#!/usr/bin/env python3 import RPi.GPIO as GPIO import time def setServoAngle(angle): GPIO.setmode(GPIO.BOARD) GPIO.setwarnings(False) GPIO.setup(11, GPIO.OUT) tilt = GPIO.PWM(11, 50) tilt.start(0) DutyCycle = angle/18 + 2 tilt.ChangeDutyCycle(DutyCycle) time.sleep(1) tilt.stop() c = 'c' while c == 'c': angle = 30 setServoAngle(angle) c = 'e' GPIO.cleanup() exit()
这里依赖一个雨滴传感器,检测雨滴就会把衣服那条杠拉进来。没办法,成本不够,gpio口也有限,只能两个舵机来回使用了。
这里依赖火焰传感器和烟雾传感器,我纠结到底是两者都符合触发报警呢还是单独一个就可以触发报警。如果是单独一个的话,我怕别人点根烟就报警了,到时候会不会很尴尬(我不抽烟哈哈哈哈)传感器原理知识就不多说了,主要还是上代码,改一下pin就好
#!/usr/bin/python # encoding:utf-8 import RPi.GPIO as GPIO import time from snow import * pin_fire=16 GPIO.setmode(GPIO.BCM) GPIO.setup(pin_fire, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) try: while True: status = GPIO.input(pin_fire) if status == True: print('没有检测到火') else: print('检测到火灾') play('./audio/fire.wav') time.sleep(0.5) except KeyboradInterrupt: GPIO.cleanup()
来一张靓仔亲测照片,局域网内都可以查看。现在的思路是树莓派官方的摄像头当人脸识别摄像头,而体感摄像头用来当网络监控,不知道会不会冲突,到时候试一下。目前两个都是用夜视摄像头测试的,补光灯也还没有安装 (因为螺丝不见了,靓仔无语 )
这个时候大家首先要把树莓派的摄像头权限打开
sudo raspi-config
选择第五项Interfacing Options,选择第一项camera,选择是,然后重新启动一下
sudo reboot
安装motion
sudo apt install motion
sudo vim /etc/default/motion
//设置“start_motion_daemon=no”,将no改为yes,让其后台运行
sudo vim /etc/motion/motion.conf
设置motion.conf如下:
daemon on
width 640
height 480
stream_localhost off
stream_maxrate 100
这个在比较靠后,我当时翻了挺久的,所以耐心翻一下吧哈哈哈
最后运行
sudo motion
接下来浏览器输入树莓派的ip:8081
就可以看见靓仔了
前面的图上面应该有写,搭建服务器端,根据不同的控制请求发布不同的指令,实现对应的控制。
这里主要利用到了一个光敏传感器,根据光线的强弱,到达一定的值就会调用舵机拉开窗帘。
这个淘宝买的继电器加土壤湿度检测,简单粗暴,稍微焊接一下就好,就是焊接的不太好看。哦对了,没花。
最后分享一个在线工具网站,https://www.sora-site.top/
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。