实时追踪物体,并将追踪到的物体的坐标的中心发送出去。注意要先连接指定的串口,不然运行会报错。框选坐标方法:
首先导入包
import cv2
import serial
定义串口和波特率
serial = serial.Serial('COM4', 115200) # 选择串口和波特率
一些初始化
cap = cv2.VideoCapture(0)
cv2.namedWindow("Frame")
if (cap.isOpened()):
print('摄像头已打开')
else:
print('摄像头未打开')
OPENCV_OBJECT_TRACKERS = {
"csrt": cv2.legacy.TrackerCSRT_create, "kcf": cv2.legacy.TrackerKCF_create,
"boosting": cv2.legacy.TrackerBoosting_create, "mil": cv2.legacy.TrackerMIL_create,
"tld": cv2.legacy.TrackerTLD_create,
"medianflow": cv2.legacy.TrackerMedianFlow_create, "mosse": cv2.legacy.TrackerMOSSE_create
}
trackers = cv2.legacy.MultiTracker_create()
读取摄像头画面并发送数据
while True:
frame = cap.read()
frame = frame[1]
if frame is None:
break
# 设置宽高比为1:2后的
height = 800 # 高度为800像素
width = int(height / 2) # 宽度为高度的一半
dim = (width, height)
frame = cv2.resize(frame, dim, interpolation=cv2.INTER_CUBIC)
# 对做摄像头做目标识别初始化
(success, boxes) = trackers.update(frame)
# 画图的循环
for box in boxes:
(x, y, w, h) = [int(v) for v in box]
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 调整坐标 这一步其实没有必要,当时是因为和动作区域成比例方便处理数据才对坐标进行了这样的处理,可以结合自己的需求发送数据
x_ = ((x + x + w) / 64)
x__ = ((x + x + w) / 2) % 32
y_ = ((y + y + h) / 64)
y__ = ((y + y + h) / 2) % 32
# 发送数据
uart_data = bytearray([0x00, int(x_), int(x__), int(y_), int(y__)])
serial.write(uart_data)
cv2.imshow('Frame', frame)
# 按键判断是否设置了新的目标
key = cv2.waitKey(10) & 0xFF
if key == ord('s'):
box = cv2.selectROI('Frame', frame, fromCenter=False, showCrosshair=True)
tracker = cv2.legacy.TrackerCSRT_create()
print(type(box), type(box[0]), box[1], box)
trackers.add(tracker, frame, box)
elif key == 27:
break
摄像头的大小设置以及对于发送的xy坐标大家可以任意设置,我这里是根据设置的摄像头的宽高计算的,为了好和当时做的其他任务配合。
结束
cap.release()
cv2.destroyAllWindows()
按下S键,画面停止,开始框选目标,再按下空格键,画面恢复,开始识别目标。可以多次框选。