前言
材料:树莓派 摄像头 SG90舵机两个 PCA9685拓展板 led小灯 蜂鸣器模块
一、树莓派引脚介绍
树莓派引脚对照表
可以看到一共有三种定义方式 分别是Wiring Pi编码,BCM编码和BOARD物理引脚编码。
1.1引脚设置
在最开始终端输入
sudo raspi-config
进入设置 后找到
Interfacing Options
进入 找到
Remote GPIO
开启GPIO
二、代码书写
2.1引入库
在最开始导入库
import RPi.GPIO as GPIO #1导入引脚库
GPIO.setmode(GPIO.BOARD) # 2定义引脚方式 此处为BOARD编码
GPIO.setup(channel, GPIO.OUT) # 3建立通道 该函数需要两个参数 第一个为引脚编号 第二个为模式定义
#此处为输出
GPIO.output(7, True)#4 驱动通道
GPIO.cleanup()#5清除 释放资源
2.2示例代码点亮led 响蜂鸣器
#导入gpio模块 调用引脚
import RPi.GPIO as GPIO
#初始化引脚模式为BOARD 屏蔽警告
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
#引脚定义 蜂鸣器接的35引脚 led接的37引脚
beep=35
led=37
GPIO.setup(beep,GPIO.OUT)#设置gpio模式为输出
GPIO.setup(led,GPIO.OUT)
GPIO.output(led,GPIO.HIGH)#开灯
GPIO.output(led,GPIO.LOW)#关灯
GPIO.output(beep,GPIO.HIGH)#蜂鸣器响
GPIO.output(beep,GPIO.LOW)#蜂鸣器关
三完整代码 图片
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
* @par Copyright (C): 2010-2020, hunan CLB Tech
* @file 50_Hand_gestures.py
* @version V2.0
* @details
* @par History
@author: zhulin
"""
import cv2
import numpy as np
import math
import time
import sys
import Adafruit_PCA9685#导入PCA9685模块
#设置编码为utf-8
import importlib
importlib.reload(sys)
#sys.setdefaultencoding('utf8')
#导入gpio模块 调用引脚
import RPi.GPIO as GPIO
#初始化引脚模式为BOARD 屏蔽警告
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
#引脚定义 蜂鸣器接的35引脚 led接的37引脚
beep=35
led=37
GPIO.setup(beep,GPIO.OUT)#设置gpio模式为输出
GPIO.setup(led,GPIO.OUT)
#初始化PCA9685和舵机
servo_pwm = Adafruit_PCA9685.PCA9685() # 实例话舵机云台
# 设置舵机初始值,可以根据自己的要求调试
servo_pwm.set_pwm_freq(60) # 设置频率为60HZ
servo_pwm.set_pwm(5,0,325) # 底座舵机
servo_pwm.set_pwm(4,0,325) # 倾斜舵机
time.sleep(1)
#初始化摄像头并设置阙值
cap = cv2.VideoCapture(0)
cap.set(3,120)
cap.set(4,160)
while(1):
try: #an error comes if it does not find anything in window as it cannot find contour of max area
#therefore this try error statement
ret, frame = cap.read()
frame=cv2.flip(frame,1)
kernel = np.ones((3,3),np.uint8)
#define region of interest
roi=frame[0:300, 0:300]
cv2.rectangle(frame,(0,0),(300,300),(0,255,0),0)
hsv = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
# define range of skin color in HSV
lower_skin = np.array([0,20,70], dtype=np.uint8)
upper_skin = np.array([20,255,255], dtype=np.uint8)
#extract skin colur imagw
mask = cv2.inRange(hsv, lower_skin, upper_skin)
#extrapolate the hand to fill dark spots within
mask = cv2.dilate(mask,kernel,iterations = 4)
#blur the image
mask = cv2.GaussianBlur(mask,(5,5),100)
#find contours
_,contours,hierarchy= cv2.findContours(mask,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#find contour of max area(hand)
cnt = max(contours, key = lambda x: cv2.contourArea(x))
#approx the contour a little
epsilon = 0.0005*cv2.arcLength(cnt,True)
approx= cv2.approxPolyDP(cnt,epsilon,True)
#make convex hull around hand
hull = cv2.convexHull(cnt)
#define area of hull and area of hand
areahull = cv2.contourArea(hull)
areacnt = cv2.contourArea(cnt)
#find the percentage of area not covered by hand in convex hull
arearatio=((areahull-areacnt)/areacnt)*100
#find the defects in convex hull with respect to hand
hull = cv2.convexHull(approx, returnPoints=False)
defects = cv2.convexityDefects(approx, hull)
# l = no. of defects
l=0
#code for finding no. of defects due to fingers
for i in range(defects.shape[0]):
s,e,f,d = defects[i,0]
start = tuple(approx[s][0])
end = tuple(approx[e][0])
far = tuple(approx[f][0])
pt= (100,180)
# find length of all sides of triangle
a = math.sqrt((end[0] - start[0])**2 + (end[1] - start[1])**2)
b = math.sqrt((far[0] - start[0])**2 + (far[1] - start[1])**2)
c = math.sqrt((end[0] - far[0])**2 + (end[1] - far[1])**2)
s = (a+b+c)/2
ar = math.sqrt(s*(s-a)*(s-b)*(s-c))
#distance between point and convex hull
d=(2*ar)/a
# apply cosine rule here
angle = math.acos((b**2 + c**2 - a**2)/(2*b*c)) * 57
# ignore angles > 90 and ignore points very close to convex hull(they generally come due to noise)
if angle <= 90 and d>30:
l += 1
cv2.circle(roi, far, 3, [255,0,0], -1)
#draw lines around hand
cv2.line(roi,start, end, [0,255,0], 2)
l+=1
#print corresponding gestures which are in their ranges
font = cv2.FONT_HERSHEY_SIMPLEX
if l==1:
if areacnt<2000:
cv2.putText(frame,'Put hand in the box',(0,50), font, 2, (0,0,255), 3, cv2.LINE_AA)
else:
if arearatio<12:
cv2.putText(frame,'0',(0,50), font, 2, (0,0,255), 3, cv2.LINE_AA)
elif arearatio<17.5:
cv2.putText(frame,'Best of luck',(0,50), font, 2, (0,0,255), 3, cv2.LINE_AA)
else:
cv2.putText(frame,'1',(0,50), font, 2, (0,0,255), 3, cv2.LINE_AA)
GPIO.output(led,GPIO.HIGH)#开灯
elif l==2:
cv2.putText(frame,'2',(0,50), font, 2, (0,0,255), 3, cv2.LINE_AA)
GPIO.output(led,GPIO.LOW)#关灯
elif l==3:
if arearatio<27:
cv2.putText(frame,'3',(0,50), font, 2, (0,0,255), 3, cv2.LINE_AA)
GPIO.output(beep,GPIO.HIGH)#蜂鸣器响
else:
pass#屏蔽ok手势
#cv2.putText(frame,'ok',(0,50), font, 2, (0,0,255), 3, cv2.LINE_AA)
elif l==4:
cv2.putText(frame,'4',(0,50), font, 2, (0,0,255), 3, cv2.LINE_AA)
GPIO.output(beep,GPIO.LOW)#蜂鸣器关
elif l==5:
cv2.putText(frame,'5',(0,50), font, 2, (0,0,255), 3, cv2.LINE_AA)
GPIO.output(led,GPIO.HIGH)#开灯
time.sleep(0.5)
GPIO.output(beep,GPIO.HIGH)#蜂鸣器响
time.sleep(0.5)
GPIO.output(beep,GPIO.LOW)#蜂鸣器关
time.sleep(0.5)
GPIO.output(led,GPIO.LOW)#关灯
time.sleep(0.5)
elif l==6:
cv2.putText(frame,'reposition',(0,50), font, 2, (0,0,255), 3, cv2.LINE_AA)
else :
cv2.putText(frame,'reposition',(10,50), font, 2, (0,0,255), 3, cv2.LINE_AA)
#show the windows
cv2.imshow('mask',mask)
cv2.imshow('frame',frame)
except:
pass
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()
cap.release()
实现功能 :
识别手势1 伸一个指头 点亮LED 灯
识别手势2 伸两个指头 关闭LED 灯
识别手势3 伸三个指头 响蜂鸣器
识别手势4 伸四个指头 蜂鸣器关
识别手势5 伸5个指头 声光警报
成品展示:
评论(0)
您还未登录,请登录后发表或查看评论