一.相机展示
二.实现代码
简单实现OAK相机的驱动和图像采集的测试代码,做双目标定准备。
使用方法:安装相关包,按个人需求更改相应路径或代码,接上相机,启动执行,等待出图后按’a‘即可保存图像。
'''
func:驱动DepthAi套件的相机,并根据自身需要采集图像
by:2024.7.17
'''
import threading
import depthai as dai
import cv2
import time
import os
class CamerDrive():
# cam_list = ['rgb', 'left', 'right', 'camd']
# 这里我只需要其中两个相机的图像,根据自己需求更改 构造函数里相应部分也需要更改
cam_list = ['rgb', 'camd']
cam_socket_opts = {}
pipeline = dai.Pipeline()
# 初始化两个字典,用于存储摄像头节点和XLinkOut节点
cam = {}
xout = {}
#
frameQueue = {}
device = None
#保存图像的容器
image_np = []
# myFrameQueue = {}
# 构造函数
def __init__(self):
self.cam_socket_opts = {
'rgb': dai.CameraBoardSocket.RGB, # Or CAM_A 板载接口名称可复用
# 'left': dai.CameraBoardSocket.LEFT, # Or CAM_B
# 'right': dai.CameraBoardSocket.RIGHT, # Or CAM_C
'camd': dai.CameraBoardSocket.CAM_D,
}
# 配置相机节点
def cameraNodeConfig(self):
for c in self.cam_list:
# 创建MonoCamera节点(注意:这里可能对于RGB摄像头需要改为ColorCamera)
self.cam[c] = self.pipeline.create(dai.node.MonoCamera)
# 设置摄像头分辨率为800P
self.cam[c].setResolution(dai.MonoCameraProperties.SensorResolution.THE_800_P)
# 根据摄像头类型设置帧同步模式
if c == 'rgb':
self.cam[c].initialControl.setFrameSyncMode(dai.CameraControl.FrameSyncMode.OUTPUT) # 输出同步模式
else:
self.cam[c].initialControl.setFrameSyncMode(dai.CameraControl.FrameSyncMode.INPUT) # 输入同步模式
# 设置摄像头连接到板载的哪个接口
self.cam[c].setBoardSocket(self.cam_socket_opts[c])
# 创建XLinkOut节点,用于将摄像头数据输出到主机
self.xout[c] = self.pipeline.create(dai.node.XLinkOut)
# 设置输出流的名称
self.xout[c].setStreamName(c)
# 将摄像头的输出链接到XLinkOut的输入
self.cam[c].out.link(self.xout[c].input)
def depthAIConfig(self):
config = dai.Device.Config()
# 将GPIO引脚6配置为输出模式,并设置初始电平为高
config.board.gpio[6] = dai.BoardConfig.GPIO(dai.BoardConfig.GPIO.OUTPUT,
dai.BoardConfig.GPIO.Level.HIGH)
# 使用Device类创建一个设备实例,并传入之前配置的配置对象。同时,使用with语句确保设备在使用完毕后正确关闭。
# with dai.Device(config) as device:
self.device = dai.Device(config)
# 启动pipeline对象
self.device.startPipeline(self.pipeline)
# 遍历相机列表,为每个相机设置输出队列、OpenCV窗口,并初始化FPS计算对象。
for c in self.cam_list:
self.frameQueue[c] = self.device.getOutputQueue(name=c, maxSize=1, blocking=False) # 获取相机输出队列,非阻塞模式
cv2.namedWindow(c, cv2.WINDOW_NORMAL) # 为每个相机创建一个OpenCV窗口
cv2.resizeWindow(c, (640, 480)) # 调整窗口大小
def get_frame(self):
start_time = time.time()
while True:
# 延时3秒 等待oak相机出图
elapsed_time = time.time() - start_time
if elapsed_time >= 2:
for c in self.cam_list:
try:
pkt = self.frameQueue[c].tryGet()
except:
print('报错了,没有图片')
pass
if pkt is not None:
frame = pkt.getCvFrame()
self.image_np.append(frame)
else:
pass
# 有一组图了 结束
return
def save_img(self,a):
self.get_frame()
if a != len(self.image_np):
print('保存的图片数量与输入要求不符合,')
print(len(self.image_np))
return
# 获取当前时间戳
current_time = time.time()
# 创建图片保存路径
path1 = r'D:\Project\Python\test01\MultiCap\sources\image\rgb'
path2 = r'D:\Project\Python\test01\MultiCap\sources\image\camd'
filename_01 = str(current_time) +"rgb" + ".jpg"
filename_02 = str(current_time) + "camd" + ".jpg"
save_path1 = os.path.join(path1,filename_01)
save_path2 = os.path.join(path2,filename_02)
cv2.imwrite(save_path1,self.image_np[0])
cv2.imwrite(save_path2, self.image_np[1])
#
self.image_np.clear()
print('采集完成')
def get_Frame(self):
while True:
for c in self.cam_list:
# 尝试从输出队列中获取一帧数据。
try:
pkt = self.frameQueue[c].tryGet()
if pkt is not None:
# 将数据包转换为OpenCV的Mat对象并显示。
frame = pkt.getCvFrame()
cv2.imshow(c, frame)
else:
pass
key = cv2.waitKey(1)
if key == ord('q'):
break
if key == ord('a'):
tets_thread = threading.Thread(target=self.save_img(2))
tets_thread.start()
except:
pass
if __name__ == '__main__':
a = CamerDrive()
a.cameraNodeConfig()
a.depthAIConfig()
a.get_Frame()