树莓派(4):寻迹小车

学习的时候百分之99参考了这篇文章
yzy_1996:【方法】树莓派小车自动循迹(摄像头):
具体内容都在里面了,因为我用的是L298N电机驱动模块,所以是用ENAB来控制PWM的,所以适当更改一下
因为我是在办公室地面,不像他一样有颜色清楚的轨道,所以修改了二值化类型和腐蚀膨胀的顺序系数

import RPi.GPIO as GPIO
import time
import cv2 as cv
import numpy as np

GPIO.setmode(gpio.BOARD)
GPIO.setwarnings(False)
INT1 = 11
INT2 = 12
INT3 = 13
INT4 = 15
ENA = 16
ENB = 18
# 设置GPIO口为输出
GPIO.setup(INT1, GPIO.OUT)
GPIO.setup(INT2, GPIO.OUT)
GPIO.setup(INT3, GPIO.OUT)
GPIO.setup(INT4, GPIO.OUT)
GPIO.setup(ENA,GPIO.OUT)
GPIO.setup(ENB,GPIO.OUT)
# 设置PWM波,频率为500Hz
pwma = GPIO.PWM(ENA, 500)
pwmb = GPIO.PWM(ENB, 500)
def stop():
    GPIO.output(INT1, 0)
    GPIO.output(INT2, 0)
    GPIO.output(INT3, 0)
    GPIO.output(INT4, 0)
    pwma.stop()
    pwmb.stop()
def forward():
    GPIO.output(INT1, 1)
    GPIO.output(INT2, 0)
    GPIO.output(INT3, 1)
    GPIO.output(INT4, 0)
# pwm波控制初始化
pwma.start(0)
pwmb.start(0)
# center定义
center = 320
# 打开摄像头,图像尺寸640*480(长*高),opencv存储值为480*640(行*列)
cap = cv.VideoCapture(0)
while True:
    ret, frame = cap.read()
    cv.imshow('frame',frame)
    # 转化为灰度图
    gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    #直方图均匀化
    dst = cv.equalizeHist(gray)
    # 二值化
    ret, dst = cv.threshold(dst,165,255,cv.THRESH_BINARY)
    # 腐蚀膨胀
    dst = cv.erode(dst, None, iterations=1)
    dst = cv.dilate(dst, None, iterations=4)
    # 单看第400行的像素值
    color = dst[400]
    # 找到白色的像素点个数
    white_count = np.sum(color == 255)
    # 找到白色的像素点索引
    white_index = np.where(color == 255)

    # 防止white_count=0的报错
    if white_count == 0:
        white_count = 1

    # 找到白色像素的中心点位置
    center = (white_index[0][white_count - 1] + white_index[0][0]) / 2

    # 计算出center与标准中心点的偏移量
    direction = center - 320
    print(direction)


    # 停止
    if abs(direction) > 250:
        stop()

    # 右转
    elif direction >= 0:
        # 限制在70以内
        if direction > 70:
            direction = 70
        forward()
        pwma.ChangeDutyCycle(30 + direction)
        pwmb.ChangeDutyCycle(30)

    # 左转
    elif direction < 0:
        if direction < -70:
            direction = -70
        forward()
        pwma.ChangeDutyCycle(30)
        pwmb.ChangeDutyCycle(30 - direction)

    if cv.waitKey(1) & 0xFF == ord('q'):
        break

# 释放清理
stop()
cap.release()
cv.destroyAllWindows()
GPIO.cleanup()

缺点:在拐弯处,因摄像头摆放位置,准确度差

你可能感兴趣的:(树莓派(4):寻迹小车)