我的一个树莓派小车项目

如何使用该程序进行开发

1.寻找串口

查看识别串口号

ls -l /dev/tty*

找到相应的串口并在程序里修改

ser = serial.Serial("/dev/ttyUSB0",9600)

2.摄像头

括号里是0还是1取决于摄像头是内部还是外部

不确定的话就挨着尝试,反正就是二选一嘛

#视频捕获口:1为本机笔记本,0为外接摄像头
#视频捕获:只有本机一个摄像头,默认为0
cap = cv2.VideoCapture(0)

3.设置某一程序开机自启

意思就是:树莓派一开机,相应的程序就会自动运行起来。

4.程序环境

上位机:树莓派4b

下位机:stm32大疆a板

5.主程序使用逻辑

主程序一直在死循环里。

每次循环都会读串口寄存器传来的数值,这里不能使用阻塞型串口,要使用延时三秒的串口进行工作,模仿硬件的串口寄存器原理

根据相应的数值进行if语句的判断,进而执行相应的命令

板子初始发送1

树莓派执行二维码操作,返回结果a123321z

随后板子收到这个结果发送5,树莓派停止工作

随后板子发送2或者3或者4

树莓派进行颜色识别,返回识别结果ggggz或rrrrz或者bbbbz

随后板子收到这个结果发送5,树莓派停止工作

周而复始,循环往复

接下来是主程序

''' 
这是肖巨龙物流车的上位机程序
此程序运行环境是 树莓派4b
下位机是大疆A板,经过USB转ttl模块,识别出串口号为"/dev/ttyUSB0"
查找串口号需要使用 ls -l /dev/ttyUSB*   命令 
'''
import cv2
import numpy as np
import math
import time
import imutils
from imutils.video import VideoStream
import numpy
import pyzbar.pyzbar as pyzbar
import argparse
import datetime
from PIL import Image,ImageEnhance
import serial
import binascii


def port_open():
    # # ser.port = 12345      #设置端口号
    # ser.baudrate = 9600     #设置波特率
    # ser.bytesize = 8        #设置数据位
    # ser.stopbits = 1        #设置停止位
    # ser.parity = "N"        #设置校验位
    if (ser.isOpen()==False):
        ser.open()
    
    if(ser.isOpen()):
        print("打开成功")
    else:
        print("打开失败")
 
def port_close():
    
    if (ser.isOpen()):
        ser.close()

    if (ser.isOpen()==False):
        print("关闭成功")
    else:
        print("关闭失败")
        
 
def send(send_data):
    if (ser.isOpen()==False):
        port_open()
    if (ser.isOpen()):
        ser.write(send_data.encode('utf-8'))  #utf-8 编码发送
        #ser.write(binascii.a2b_hex(send_data))  #Hex发送
        print("发送成功",send_data)
    else:
        print("发送失败")
    port_close()


def barcode_recog():
    print("开始二维码识别")
    vs = VideoStream(0).start() 
    time.sleep(2.0)
    flag=False#后面的break用到这一条件
    while True:# 循环来自视频流的帧
        frame = vs.read()
        frame = imutils.resize(frame, width=1000)
        #找到视频中的条形码,并解析所有条形码
        barcodes = pyzbar.decode(frame)

        # 循环所有检测到的条形码
        for barcode in barcodes:
            # 提取条形码的边界框位置
            # 绘出围绕图像上条形码的边界框
            (x, y, w, h) = barcode.rect
            cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)

            # 条形码数据为字节对象
            # 需要先把它转换成字符串
            barcodeData = barcode.data.decode("utf-8")#barcodeData二维码信息
            barcodeType = barcode.type#barcodeType二维码信息的类别
            #print(barcodeData)#输出二维码信息
            barcodeData = list(barcodeData)
            barcodeData.pop(3)
            barcodeData = ''.join(barcodeData)
            barcodeData = 'a' + barcodeData + 'z'
            print(barcodeData)
            send(barcodeData)
            if barcodeData != "":
                flag=True
        cv2.imshow("barcode", frame)#图形化窗口展示结果
        cv2.waitKey(5)
        if flag :#跳出while循环
            print("二维码函数结束")
            time.sleep(2)#用两秒时间来展示图形化窗口结果
        break
    vs.stop()
    cv2.destroyAllWindows()
    

def barcode_recog_new():
    print("[INFO] starting video stream...")
    vs = VideoStream(0).start()
    time.sleep(2.0)
    flag=False#后面的break用到这一条件
# 循环来自视频流的帧
  # 抓取来自单线程视频流的帧, 
  # 将大小重新调整为最大宽度400像素
    frame = vs.read()
    frame = imutils.resize(frame, width=1000)
  #  找到视频中的条形码,并解析所有条形码
    barcodes = pyzbar.decode(frame)
  # 循环所有检测到的条形码
    for barcode in barcodes:
    # 提取条形码的边界框位置
    # 绘出围绕图像上条形码的边界框
        (x, y, w, h) = barcode.rect
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)
    # 条形码数据为字节对象
    # 需要先把它转换成字符串
        barcodeData = barcode.data.decode("utf-8")#barcodeData二维码信息
        barcodeType = barcode.type#barcodeType二维码信息的类别
        barcodeData = list(barcodeData)
        barcodeData.pop(3)
        barcodeData = ''.join(barcodeData)
        barcodeData = 'a' + barcodeData + 'z'
        print(barcodeData)#输出二维码信息
        send(barcodeData)
        if barcodeData != "":
            flag=True
    cv2.imshow("Barcode Scanner", frame)#图形化窗口展示结果
    cv2.waitKey(5)
    if flag :#跳出while循环
        print("识别成功,解析成功")
    #time.sleep(2)#用两秒时间来展示图形化窗口结果
    cv2.destroyAllWindows()
    vs.stop()



 
def recognizeByColor(ball_color):
        #视频捕获口:1为本机笔记本,0为外接摄像头
    #视频捕获:只有本机一个摄像头,默认为0
    #cap = cv2.VideoCapture(0)
    ret, frame = cap.read()
    frame = imutils.resize(frame, width=300)
    frame = frame[60:120, 120:200]
    gs_frame = cv2.GaussianBlur(frame, (5, 5), 0)                     # 高斯模糊
    hsv = cv2.cvtColor(gs_frame, cv2.COLOR_BGR2HSV)                 # 转化成HSV图像
    erode_hsv = cv2.erode(hsv, None, iterations=2)                   # 腐蚀 粗的变细
    inRange_hsv = cv2.inRange(erode_hsv, color_dist[ball_color]['Lower'], color_dist[ball_color]['Upper'])
    cnts = cv2.findContours(inRange_hsv.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
    cv2.imshow("color", frame)#图形化窗口展示结果
    cv2.waitKey(5)
    if(len(cnts)==0):
        time.sleep(0.5) #节省系统开销
        print("无该颜色")
        return False
    else:
        
        #definite the "color" acording to the color recognized
        if ball_color == 'blue':
            color="bbbbz"
            print(color)
            #port_open()
            send(color)
            #port_close()
        if ball_color=='red':
            color="rrrrz"
            print(color)
            #port_open()
            send(color)
            #port_close()
        if ball_color=='green':
            color="ggggz"
            print(color)
            #port_open()
            send(color)
            #port_close()
        #下面四句话展示矩形框选效果,正式比赛时可以去掉,节省资源
        c = max(cnts, key=cv2.contourArea)
        rect = cv2.minAreaRect(c)
        box = cv2.boxPoints(rect)
        cv2.drawContours(frame, [np.int0(box)], -1, (0, 255, 255), 2)
        cv2.imshow('color', frame)
        cv2.waitKey(1)
        return True
    vs.stop()
    cv2.destroyAllWindows()






#主程序运行前的初始化
ser = serial.Serial("/dev/ttyUSB0",9600,timeout=3)#这一语句默认会打开串口
recogTime = 5 #识别时间
gapTime = 3 #机械臂旋转调整时间
a=1
color_dist = {'red': {'Lower': np.array([156, 43, 60]), 'Upper': np.array([180, 255, 255])},
              'blue': {'Lower': np.array([100, 43, 46]), 'Upper': np.array([124, 255, 255])},
              'green': {'Lower': np.array([35, 43, 35]), 'Upper': np.array([77, 255, 255])},
           }





while True:
    port_open()
    time.sleep(2)
    print("等待曾巨发送...")
    us=ser.read(10)
    long_of_us=len(us)
    print("信号length:",long_of_us)
    if (long_of_us):
        us=us[0]#因为是字节的方式,所以取第一个字节
    else:
        us=1
    print("这是第 ",a," 次while循环")
    a=a+1
    print("曾巨发送过来的是:",us)


    if us==2 or us==3 or us==4:
        cap = cv2.VideoCapture(0)
        #cv2.namedWindow('color', cv2.WINDOW_AUTOSIZE)
        #cv2.namedWindow('color', cv2.WINDOW_FREERATIO)
        for i in "pa":

            ball_color = 'green'
            #print("aaaa")
            time0 = time.time()
            print("识别绿色")
            while time.time()-time0 < recogTime:#表示这个while循环运行五秒
                ret, frame = cap.read()
                if ret:#该条件表示读取到摄像头
                    if frame is not None:#该条件表示可以读取摄像头的画面
                        if(recognizeByColor(ball_color)):#如果颜色识别函数返回ture
                            print("成功识别绿色")
                            break
                    else:
                        print("无画面")
                else:
                    print("无法读取摄像头!")


            ball_color = 'red'
            #print("bbbb")
            time1 = time.time()
            time.sleep(gapTime)
            print("识别红色")
            while time.time()-time1 < recogTime:
                ret, frame = cap.read()
                if ret:
                    if frame is not None:
                        if(recognizeByColor(ball_color)):
                            print("成功识别红色")
                            break
                    else:
                        print("无画面")
                else:
                    print("无法读取摄像头!")

                
            ball_color = 'blue'
            #print("cccc")
            time2 = time.time()
            time.sleep(gapTime)
            print("识别蓝色")
            while time.time()- time2 < recogTime:
                ret, frame = cap.read()
                if ret:
                    if frame is not None:
                        if(recognizeByColor(ball_color)):
                            print("成功识别蓝色")
                            break
                    else:
                        print("无画面")
                else:
                    print("无法读取摄像头!")
        cap.release()



    if us==0x01:
        barcode_recog_new()





    if us==0x05:
        cv2.destroyAllWindows()
        time.sleep(5)




    if (us!=0x01) and (us!=0x02) and (us!=0x03) and (us!=0x04) and (us!=0x05):
        send('a123321z')
        send('a123321z')
        print('串口通信有误,受到干扰')
        us=0x04



    



你可能感兴趣的:(opencv,opencv,python)