python basler 相机调用方法 USB通信 网口通讯 多台相机同时启用

from pypylon import pylon
import cv2
import numpy as np


class BaslerCameras:
    def __init__(self, interface_type, width, height, exposure, gain):
        """
        初始化 BaslerCamera 类
        :param interface_type: 接口类型 ('GigE' 或 'USB')
        :param width: 图像宽度
        :param height: 图像高度
        :param exposure: 曝光时间(微秒)
        :param gain: 增益
        """
        self.interface_type = interface_type
        self.camera = None
        self.width = width
        self.height = height
        self.exposure = exposure
        self.gain = gain

        # 初始化 Pylon 系统
        # pylon.initialize()

        # 获取所有可用的相机
        self.camera_list = pylon.TlFactory.GetInstance().EnumerateDevices()

        if not self.camera_list:
            raise RuntimeError("No camera detected")

        # 根据接口类型选择相机
        self.select_camera()

        # 配置相机参数
        self.camera.Width = self.width
        self.camera.Height = self.height
        self.camera.ExposureTime = self.exposure
        self.camera.Gain = self.gain

        # 开始采集图像
        self.camera.StartGrabbing(pylon.GrabStrategy_LatestImageOnly)

    def select_camera(self):
        """
        选择适当的相机根据接口类型
        """
        for device in self.camera_list:
            if (self.interface_type == 'GigE' and device.GetDeviceClass() == 'BaslerGigE') or \
                    (self.interface_type == 'USB' and device.GetDeviceClass() == 'BaslerUsb'):
                self.camera = pylon.InstantCamera(pylon.TlFactory.GetInstance().CreateDevice(device))
                break

        if self.camera is None:
            raise RuntimeError(f"No {self.interface_type} camera detected")

        # 打开相机
        self.camera.Open()

    def grab_image(self):
        """
        抓取一帧图像
        :return: 图像(如果成功),否则返回 None
        """
        if self.camera.IsGrabbing():
            #这行代码从相机中检索抓取结果。5000 表示等待结果的最大时间
            grab_result = self.camera.RetrieveResult(5000, pylon.TimeoutHandling_ThrowException)
            if grab_result.GrabSucceeded():
                # 获取图像数据
                image = grab_result.Array
                # 将图像数据转换为 OpenCV 格式
                image = np.array(image, dtype=np.uint8)
                image = cv2.cvtColor(image, cv2.COLOR_BAYER_BG2BGR)
                grab_result.Release()
                return image
        return None

    def start_recording(self, output_file, duration):
        """
        开始录像
        :param output_file: 输出文件路径
        :param duration: 录像时长(秒)
        """
        #创建一个视频编解码器对象,使用的是XVID编码格式。用于指定视频编解码器。
        fourcc = cv2.VideoWriter_fourcc(*'XVID')
        #建一个视频写入器对象,用于将视频帧写入文件。output_file:输出视频文件的路径。视频的帧率(每秒20帧)。
        out = cv2.VideoWriter(output_file, fourcc, 20.0, (self.width, self.height))

        #计算出录像结束时的时钟周期计数。获取当前的时钟周期计数。将指定的录像时长(秒)转换为时钟周期数。
        end_time = cv2.getTickCount() + duration * cv2.getTickFrequency()
        #在当前时钟周期计数小于结束时间之前,持续循环。
        while cv2.getTickCount() < end_time:
            image = self.grab_image()
            if image is not None:
                out.write(image)
            else:
                break
        #释放视频写入器
        out.release()

    def close(self):
        """
        停止采集并关闭相机
        """
        if self.camera:
            self.camera.StopGrabbing()
            self.camera.Close()
        # 释放 Pylon 系统
        pylon.terminate()

def camera_worker(camera, operation, *args):
    """
    工作线程函数
    :param camera: BaslerCamera 实例
    :param operation: 操作类型 ('capture' 或 'record')
    :param args: 操作参数
    """
    if operation == 'capture':
        image = camera.grab_image()
        if image is not None:
            cv2.imshow(f'Camera {camera}', image)
            cv2.waitKey(0)
    elif operation == 'record':
        output_file, duration = args
        camera.start_recording(output_file, duration)

# 使用示例
def main():
    # 创建多个相机实例
    cameras = [
        BaslerCameras(interface_type='GigE', width=1920, height=1080, exposure=5000, gain=10),
        BaslerCameras(interface_type='USB', width=1920, height=1080, exposure=5000, gain=10)
    ]

    threads = []

    # 启动线程来同时操作多个相机
    for i, cam in enumerate(cameras):
        if i % 2 == 0:
            # 每隔一个相机捕捉图像
            t = threading.Thread(target=camera_worker, args=(cam, 'capture'))
        else:
            # 其他相机录制视频
            t = threading.Thread(target=camera_worker, args=(cam, 'record', f'output_{i}.avi', 10))

        t.start()
        threads.append(t)

    # 等待所有线程完成
    for t in threads:
        t.join()

    # 释放资源
    for cam in cameras:
        cam.close()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    main()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值