基于树莓派与YOLOv3模型的人体目标检测小车(四)

前面几篇文章完成了训练端和部署端的环境搭建以及模型的训练,并经过两次模型转化最终将YOLOv3 TINY模型部署在了树莓派上。其实最核心的内容已经完成了,接下来就是一些应用层面的东西了。

树莓派控制马达:
1. 材料硬件:

1.树莓派3B+

2.四个直流电机

3.一个小车底盘+四个车轮(某宝上有卖)

image

4.L298N驱动模块(介于树莓派与马达之间的桥梁)

image

5.充电宝一个(用于给树莓派供电)

6.18650锂电池两节(给小车马达供电,普通干电池真的不能用,不然你会拥有好多废电池)

7.杜邦线公对公、母对母、公对母各40条

8.面包板(可选)

9.蜂鸣器

image
2.线路连接:
image

图片是用fritzing这个软件画的,也是今天第一次用,画的有点丑,凑合看吧。我没有找到L298N这个模块,就用图中红色的这个代替一下吧。

我的马达控制逻辑比较简单,小车左右两侧的马达为一组同时控制,小车左边两个马达正负极分别连在out1、out2接口上,右边两个马达正负极分别连在out3、out4上,通过给out1和out2,out3和out4输出相反的电平实现马达的转动,采用BOARD编码格式,使用35、33、31、29四个GPIO接口分别连接到L298N驱动模块上的in1、in2、in3、in4接口,同时将32、36、38、40分别连接到四个使能端接口,通过python编程设置gpio接口输出高电平和低电平实现相应的控制,蜂鸣器连接到gpio的11号端口上。

3.小车控制与视频直播流web程序:

web程序采用的是基于python的flask框架,便于实现流媒体直播。同时前台的按钮可以将前进后退转弯信号传回后台,并在后台解析后调用相关的控制程序实现小车的前进后退。

# -*- coding:utf-8 -*-
from flask import Flask, render_template, Response,request
import cv2
import os,time
import RPi.GPIO as GPIO
from flask import jsonify
import sys

class Car(object):
    def __init__(self):
        self.enab_pin = [38, 40, 32, 36]
        self.inx_pin = [35, 33, 31, 29]  # 1leftahead  2left down 3 right ahead 4 right down
        self.RightAhead_pin = self.inx_pin[2]
        self.RightBack_pin = self.inx_pin[3]
        self.LeftAhead_pin = self.inx_pin[0]
        self.LeftBack_pin = self.inx_pin[1]
        self.setup()
        
    def setup(self):
        GPIO.setmode(GPIO.BOARD)
        GPIO.setwarnings(False)
        for pin in self.enab_pin:
            GPIO.setup(pin, GPIO.OUT)
            GPIO.output(pin, GPIO.HIGH)
            
        pin = None
        
        for pin in self.inx_pin:
            GPIO.setup(pin, GPIO.OUT)
            GPIO.output(pin, GPIO.LOW)
            
    def front(self):
        self.setup()
        GPIO.output(self.RightAhead_pin, GPIO.HIGH)
        GPIO.output(self.LeftAhead_pin, GPIO.HIGH)
           
    def rear(self):
        self.setup()
        GPIO.output(self.RightBack_pin, GPIO.HIGH)
        GPIO.output(self.LeftBack_pin, GPIO.HIGH)
        
    def right(self):
        self.setup()
        GPIO.output(self.RightAhead_pin, GPIO.HIGH)
    def left(self):
        self.setup()
        GPIO.output(self.LeftAhead_pin, GPIO.HIGH)
        
    def stop(self):
        for pin in self.inx_pin:
            GPIO.output(pin, GPIO.LOW)
    def clear(self):
        GPIO.cleanup()


def main(status):
    car = Car()
    if status == 'front':
        car.front()
    if status == 'rear':
        car.rear()
    if status == 'right':
        car.right()
    if status == 'left':
        car.left()
    
    if status == 'stop':
        car.stop()



class VideoCamera(object):
    def __init__(self):
            self.video = cv2.VideoCapture(0)
    def get_frame(self):
        success, image = self.video.read()
        ret, jpeg = cv2.imencode('.jpg', image)
        return jpeg.tobytes()
    def __del__(self):
        self.video.release()
        print('cam is closed...')
    
app = Flask(__name__)
''
@app.route('/')  # 主页
def index():
    # jinja2模板,具体格式保存在index.html文件中
    return render_template('index.html')
@app.route('/operation')  
def operation():
   
    return render_template('operation.html')


def gen(camera):
    while True:
        
        frame = camera.get_frame()
        if(frame !=None):
                yield (b'--frame\r\n'b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
@app.route('/video_feed')  # 这个地址返回视频流响应

def video_feed():
   # os.system('python3 test_tiny_yolo.py')
   
    return Response(gen(VideoCamera()),
                    mimetype='multipart/x-mixed-replace; boundary=frame')   
@app.route('/cmd',endpoint='cmd',methods=['GET', 'POST'])
def getjson():
    a = request.args.get('mydata')
    print('收到请求:'+a)
    main(a)
    return jsonify('success')


if __name__ == '__main__':
    
    app.run(host='0.0.0.0', port =5000,debug=True, threaded=True)
    print("ok")
   

实现效果:

{此处插入视频}

微信报警程序:
1.安装wxpy:

查看官方网站:https://wxpy.readthedocs.io/zh/latest/

2.监控端程序:

我们需要的功能很简单:

​ 在离开家门之前在树莓派上登陆一个微信--》当有不明入侵人员进入小车的视线范围时被检测到--》给另一个微信好友发送检测到的人体图片以及检测到的人数和检测时间--》收到信息后由微信好友回复"Y/N"来决定是否触发蜂鸣器来发出警报。

只需要在实时检测的代码中插入图片保存和记录时间人数的代码段即可:

    WEBIMG = cv2.resize(color_image, (width, height))
        cv2.imshow(window_name, WEBIMG)
        cv2.imwrite('image1.jpeg', WEBIMG)
        if(flag == True):
            now = int(time.time())
            if(iffirst or (now - lastsendtime) >= 20): #为了演示方便,这里设置触发时间间隔为20s
                iffirst = False
                filename = 'flag.txt'
                with open(filename,'w') as f: # 如果filename不存在会自动创建, 'w'表示写数据,写之前会清空文件中的原有数据!
                    f.write(str(now))
                    f.write('\n')
                    f.write(str(count))
                    f.write('\n')

                lastsendtime = now
                cv2.imwrite('person.jpeg', WEBIMG)

在监控工作时只有当检测到人体时才执行图片保存任务和flag文件的写入工作,并且只有和上次保存时间相隔超过20s时才会进行更新,这很大程序避免了在一段时间内频繁发送图片的情况。

image
3.微信发送端程序:

监控端在不断的写图片更新flag,同时微信端也不断的读取flag来判断是否有新的检测情况,如果有则发送检测到的图片和时间人数信息给指定的微信好友。

# 导入模块
from wxpy import*

import datetime
import RPi.GPIO as GPIO
import sys
import time

def alarm():
    fengming = 11
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(fengming, GPIO.OUT)
    GPIO.output(fengming, GPIO.HIGH)
    time.sleep(5)
    GPIO.cleanup()



# 初始化机器人,扫码登陆
bot = Bot()

my_friend = bot.friends().search('可以的')[0]
flag = 0
lastsendtime = None

@bot.register()
def print_others(msg):
    m = msg.text
    print(m)
    if(("y" in m) or ("Y" in m)):
        print(m)
        alarm()

while True:
    with open('flag.txt') as f: # 默认模式为‘r’,只读模式
        lastsend = f.readline()
        if(lastsend==''):
            continue
        count = f.readline().strip()
        if((lastsendtime == None )or (lastsend !=lastsendtime)):
            lastsendtime = lastsend
            lastsend_trans=time.localtime(int(lastsend))
            lastsend_time=time.strftime('%Y-%m-%d %H:%M:%S',lastsend_trans)
            # 发送图片
            time.sleep(3)
            my_friend.send_image('/home/pi/OpenVINO-YoloV3-master/person.jpeg')
            my_friend.send("时间:  "+lastsend_time+"\n检测到"+count +"个人进入房间。。。")
            my_f
            riend.send("是否开启警报?(回复y/n)")
embed()          

实现的效果:

image

后来想了个问题就是是否可以给熟人加个白名单呢,这个仅靠目标检测是实现不了,需要进行人脸比对,利用一些云端的API倒是可以实现,但可能实时性就没有那么高了。


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容