如何使用该程序进行开发
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 binasciidef 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.rectcv2.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=Truecv2.imshow("barcode", frame)#图形化窗口展示结果cv2.waitKey(5)if flag :#跳出while循环print("二维码函数结束")time.sleep(2)#用两秒时间来展示图形化窗口结果breakvs.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.rectcv2.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=Truecv2.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 Falseelse:#definite the "color" acording to the color recognizedif 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 Truevs.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=1print("这是第 ",a," 次while循环")a=a+1print("曾巨发送过来的是:",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)):#如果颜色识别函数返回tureprint("成功识别绿色")breakelse: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("成功识别红色")breakelse: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("成功识别蓝色")breakelse: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