修改Adafruit_PCA9685目录下的PCA9685.py文件:

  sudo find / -name Adafruit_PCA9685     得到 /usr/local/lib/python3.6/dist-packages/Adafruit_PCA9685

  cd /usr/local/lib/python3.6/dist-packages/Adafruit_PCA9685

  ls

  vim PCA9685.py

  把 self._device = i2c.get_i2c_device(address, **kwargs)  改为  self._device = i2c.Device(address, "0", None, **kwargs)

然后根据jetbot源码改编得到以下代码

此时就可以使用下面代码控制云台pwm舵机了

import time
import Adafruit_PCA9685

pwm = Adafruit_PCA9685.PCA9685()
pwm.set_pwm_freq(50)

def servo_move(basechannel,basevalue,tiltchannel,tiltvalue):
    basevalue=4096*((basevalue*11)+500)/20000
    pwm.set_pwm(basechannel,0,int(basevalue))
    tiltvalue=4096*((tiltvalue*11)+500)/20000
    pwm.set_pwm(tiltchannel,0,int(tiltvalue))

pan = 90
tilt = 90

servo_move(0, pan, 1, tilt)


if __name__ == '__main__':

    for angle in range(30, 120, 5):
        servo_move(0, angle, 1, angle)
        time.sleep(0.5)

    servo_move(0, pan, 1, tilt)
servo_control.py(云台舵机控制代码)

应用:

import cv2   #导入库
import numpy as np
import time
import os
from servo_control import *

#关于色域范围可以百度 HSV
#百科:https://baike.baidu.com/item/HSV/547122?fr=aladdin
#参考:https://blog.csdn.net/leo_888/article/details/88284251

# 启动脚本杀死影响程序的进程
os.system('./killmjpg.sh')
time.sleep(0.1)

# 要识别的颜色字典
color_dist = {
             'red':   {'Lower': np.array([156, 60, 60]), 'Upper': np.array([180, 255, 255])},
             'green': {'Lower': np.array([35, 43, 35]), 'Upper': np.array([90, 255, 255])},
             'blue':  {'Lower': np.array([110, 80, 80]), 'Upper': np.array([128, 255, 255])},
#             'gray':  {'Lower': np.array([0,0,30]),'Upper':np.array([255,40,80]) }
             };

flag = -1
flag_bak = -1

img_w = 320
img_h = 240

cap = cv2.VideoCapture(0)  #打开摄像头 最大范围 640×480
cap.set(3,img_w)  #设置画面宽度
cap.set(4,img_h)  #设置画面高度


lastTime = time.time()

time.sleep(1)

while 1: #进入无线循环
    global pan,tilt
    #将摄像头拍摄到的画面作为frame的值
    ret,frame = cap.read()
    for i in color_dist:
        #1-高斯滤波GaussianBlur() 让图片模糊
        frame = cv2.GaussianBlur(frame,(5,5),0)
    
        #2-转换HSV的样式 以便检测
        hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV) 
        
        #3-查找字典
        mask = cv2.inRange(hsv, color_dist[i]['Lower'], color_dist[i]['Upper'])
        
        #4-腐蚀图像
        mask = cv2.erode(mask,None,iterations=2)
        
        #高斯模糊
        mask = cv2.GaussianBlur(mask,(3,3),0)
        
        #图像合并
        res = cv2.bitwise_and(frame,frame,mask=mask)       
        #6-边缘检测
        cnts = cv2.findContours(mask.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2] 
         
        if len(cnts) >0 : #通过边缘检测来确定所识别物体的位置信息得到相对坐标

            cnt = max(cnts,key=cv2.contourArea)
            rect = cv2.minAreaRect(cnt)
            # 获取最小外接矩形的4个顶点
            box = cv2.boxPoints(rect)
                        
            #获取坐标 长宽 角度
            c_x, c_y = rect[0]
            c_h, c_w = rect[1]
            c_angle = rect[2]
            #print(c_x,c_y,c_h,c_w)
            #判断是否是方块大小且在方框中
            if 25 < c_h < 85 and 25 < c_w < 85: #  and 50 < c_x < 270 and 60 < c_y < 180:
                #print('---',c_x,c_y,c_h,c_w)
                #绘制轮廓
                cv2.drawContours(frame, [np.int0(box)], -1, (0, 255, 255), 2)
                
                #print(time.time(), 'x=', int(c_x), 'y=', int(c_y), 'c_h=', int(c_h), 'c_w=', int(c_w), 'angle=', int(c_angle))
                
                errorPan = c_x - img_w/2 
                errorTilt = c_y - img_h/2
                #print('errorpan',errorPan)
                if abs(errorPan)>15:
                    pan=pan-errorPan/75
                if abs(errorTilt)>15:
                    tilt=tilt-errorTilt/50
                #print('pan',pan)
                if pan > 180:
                    pan = 180
                    print("Pan out of Range")
                if pan < 0:
                    pan = 0
                    print("pan Out of Range")
                if tilt > 180:
                    tilt = 180
                    print("Pan out of Range")
                if tilt < 0:
                    tilt = 0
                    print("pan Out of Range")

                #servo_move(0,180-pan,1,tilt)
                servo_move(0,pan,1,180-tilt)
                
            else:
                pass
    
    
    cv2.imshow('frame',frame) #将具体的测试效果显示出来
    #cv2.imshow('mask',mask)
    #cv2.imshow('res',res)
    if cv2.waitKey(5) & 0xFF == 27: #如果按了ESC就退出 当然也可以自己设置
        break

cap.release()
cv2.destroyAllWindows() #后面两句是常规操作,每次使用摄像头都需要这样设置一波
颜色跟随(本地版)
import cv2   #导入库
import numpy as np
import time
import os
from servo_control import *

#创建显示控件
from jetcam.utils import bgr8_to_jpeg
import traitlets
import ipywidgets.widgets as widgets
from IPython.display import display

disp = widgets.Image(format='jpeg', width=320, height=240)
display(disp)

#关于色域范围可以百度 HSV
#百科:https://baike.baidu.com/item/HSV/547122?fr=aladdin
#参考:https://blog.csdn.net/leo_888/article/details/88284251

# 启动脚本杀死影响程序的进程
os.system('./killmjpg.sh')
time.sleep(0.1)

# 要识别的颜色字典
color_dist = {
             'red':   {'Lower': np.array([156, 60, 60]), 'Upper': np.array([180, 255, 255])},
             'green': {'Lower': np.array([35, 43, 35]), 'Upper': np.array([90, 255, 255])},
             'blue':  {'Lower': np.array([110, 80, 80]), 'Upper': np.array([128, 255, 255])},
#             'gray':  {'Lower': np.array([0,0,30]),'Upper':np.array([255,40,80]) }
             };

flag = -1
flag_bak = -1

img_w = 320
img_h = 240

cap = cv2.VideoCapture(0)  #打开摄像头 最大范围 640×480
cap.set(3,img_w)  #设置画面宽度
cap.set(4,img_h)  #设置画面高度


lastTime = time.time()

time.sleep(1)

try:
    while 1: #进入无线循环
        global pan,tilt
        #将摄像头拍摄到的画面作为frame的值
        ret,frame = cap.read()
        for i in color_dist:
            #1-高斯滤波GaussianBlur() 让图片模糊
            frame = cv2.GaussianBlur(frame,(5,5),0)

            #2-转换HSV的样式 以便检测
            hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV) 

            #3-查找字典
            mask = cv2.inRange(hsv, color_dist[i]['Lower'], color_dist[i]['Upper'])

            #4-腐蚀图像
            mask = cv2.erode(mask,None,iterations=2)

            #高斯模糊
            mask = cv2.GaussianBlur(mask,(3,3),0)

            #图像合并
            res = cv2.bitwise_and(frame,frame,mask=mask)       
            #6-边缘检测
            cnts = cv2.findContours(mask.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2] 

            if len(cnts) >0 : #通过边缘检测来确定所识别物体的位置信息得到相对坐标

                cnt = max(cnts,key=cv2.contourArea)
                rect = cv2.minAreaRect(cnt)
                # 获取最小外接矩形的4个顶点
                box = cv2.boxPoints(rect)

                #获取坐标 长宽 角度
                c_x, c_y = rect[0]
                c_h, c_w = rect[1]
                c_angle = rect[2]
                #print(c_x,c_y,c_h,c_w)
                #判断是否是方块大小且在方框中
                if 25 < c_h < 85 and 25 < c_w < 85: #  and 50 < c_x < 270 and 60 < c_y < 180:
                    #print('---',c_x,c_y,c_h,c_w)
                    #绘制轮廓
                    cv2.drawContours(frame, [np.int0(box)], -1, (0, 255, 255), 2)

                    #print(time.time(), 'x=', int(c_x), 'y=', int(c_y), 'c_h=', int(c_h), 'c_w=', int(c_w), 'angle=', int(c_angle))

                    errorPan = c_x - img_w/2 
                    errorTilt = c_y - img_h/2
                    #print('errorpan',errorPan)
                    if abs(errorPan)>15:
                        pan=pan-errorPan/75
                    if abs(errorTilt)>15:
                        tilt=tilt-errorTilt/50
                    #print('pan',pan)
                    if pan > 180:
                        pan = 180
                        print("Pan out of Range")
                    if pan < 0:
                        pan = 0
                        print("pan Out of Range")
                    if tilt > 180:
                        tilt = 180
                        print("Pan out of Range")
                    if tilt < 0:
                        tilt = 0
                        print("pan Out of Range")

                    #servo_move(0,180-pan,1,tilt)
                    servo_move(0,pan,1,180-tilt)

                else:
                    pass

        disp.value = bgr8_to_jpeg(frame)
        #cv2.imshow('frame',frame) #将具体的测试效果显示出来
        #cv2.imshow('mask',mask)
        #cv2.imshow('res',res)
        #if cv2.waitKey(5) & 0xFF == 27: #如果按了ESC就退出 当然也可以自己设置
            #break
except KeyboardInterrupt:
    cap.release()
    #cv2.destroyAllWindows() #后面两句是常规操作,每次使用摄像头都需要这样设置一波
颜色跟随(jupyter版)
# OpenCV 摄像头云台人脸追踪
import os
import cv2
import numpy as np
#import Adafruit_PCA9685
import time
from servo_control import *

# 启动脚本杀死影响程序的进程
os.system('./killmjpg.sh')
time.sleep(0.1)

servo_move(0,90,1,90)
cam = cv2.VideoCapture(0)
dis_w = 320
dis_h = 240
cam.set(3, dis_w)
cam.set(4, dis_h)

# 载入人脸和眼睛的HAAR 模型
face_cascade = cv2.CascadeClassifier('./trains/haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('./trains/haarcascade_eye.xml')

def Video_display():
    global pan, tilt
    while True: 
        ret,frame = cam.read()
        gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray,1.3,5)

        for(x,y,w,h) in faces:
            cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2)
            Xcent = x + w/2
            Ycent = y + h/2
            errorPan  = Xcent - dis_w/2 
            errorTilt = Ycent - dis_h/2
            if abs(errorPan)>15:
                pan=pan-errorPan/50
            if abs(errorTilt)>15:
                tilt=tilt-errorTilt/50
            if pan > 180:
                pan = 180
                print("Pan out of Range")
            if pan < 0:
                pan = 0
                print("pan Out of Range")
            if tilt > 180:
                tilt = 180
                print("Pan out of Range")
            if tilt < 0:
                tilt = 0
                print("pan Out of Range")

            servo_move(0,pan,1,180-tilt)
            #servo_move(0,pan,1,180-tilt)

            roi_gray = gray[y:y+h, x:x+w]
            roi_color = frame[y:y+h, x:x+w]        
            eyes = eye_cascade.detectMultiScale(roi_gray)
            for (ex,ey,ew,eh) in eyes:
                cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)          
        cv2.imshow('frame', frame)
        if cv2.waitKey(5) & 0xFF == 27:
            break

if __name__ == '__main__':
    try:
        Video_display()
    except KeyboardInterrupt:
        cap.release()
        cv2.destroyAllWindows()
人脸跟随(本地版)
# OpenCV 摄像头云台人脸追踪
import os
import cv2
import numpy as np
#import Adafruit_PCA9685
import time
from servo_control import *

#创建显示控件
from jetcam.utils import bgr8_to_jpeg
import traitlets
import ipywidgets.widgets as widgets
from IPython.display import display

disp = widgets.Image(format='jpeg', width=320, height=240)
display(disp)

# 启动脚本杀死影响程序的进程
os.system('./killmjpg.sh')
time.sleep(0.1)

servo_move(0,90,1,90)
cam = cv2.VideoCapture(0)
dis_w = 320
dis_h = 240
cam.set(3, dis_w)
cam.set(4, dis_h)

# 载入人脸和眼睛的HAAR 模型
face_cascade = cv2.CascadeClassifier('./trains/haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('./trains/haarcascade_eye.xml')

def Video_display():
    global pan, tilt
    while True: 
        ret,frame = cam.read()
        gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray,1.3,5)

        for(x,y,w,h) in faces:
            cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2)
            Xcent = x + w/2
            Ycent = y + h/2
            errorPan  = Xcent - dis_w/2 
            errorTilt = Ycent - dis_h/2
            if abs(errorPan)>15:
                pan=pan-errorPan/50
            if abs(errorTilt)>15:
                tilt=tilt-errorTilt/50
            if pan > 180:
                pan = 180
                print("Pan out of Range")
            if pan < 0:
                pan = 0
                print("pan Out of Range")
            if tilt > 180:
                tilt = 180
                print("Pan out of Range")
            if tilt < 0:
                tilt = 0
                print("pan Out of Range")

            servo_move(0,pan,1,180-tilt)
            #servo_move(0,pan,1,180-tilt)

            roi_gray = gray[y:y+h, x:x+w]
            roi_color = frame[y:y+h, x:x+w]        
            eyes = eye_cascade.detectMultiScale(roi_gray)
            for (ex,ey,ew,eh) in eyes:
                cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)          
        disp.value = bgr8_to_jpeg(frame)
        #cv2.imshow('frame', frame)
        #if cv2.waitKey(5) & 0xFF == 27:
            #break

            
if __name__ == '__main__':
    try:
        Video_display()
    except KeyboardInterrupt:
        cam.release()
人脸跟随(jupyter版)

 

posted on 2021-09-13 21:32  始终不够啊  阅读(637)  评论(0)    收藏  举报