当前位置: 首页 > news >正文

OAK相机:自动或手动设置相机参数

OAK相机:自动或手动设置相机参数

硬件

使用硬件如下:

  • 4✖️ov9782相机
  • OAK-FFC-4P驱动板

硬件接线参考博主的一篇博客:OAK相机:多相机硬件同步拍摄

软件

博主使用的是Ubuntu18.04系统,首先配置所需的python环境:
1、下载SDK软件包:

git clone https://gitee.com/oakchina/depthai.git

2、安装依赖:

python3 -m pip install -r depthai/requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

3、注意:在Linux平台并且第一次使用OAK需要配置udev规则

echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="03e7", MODE="0666"' | sudo tee /etc/udev/rules.d/80-movidius.rules
sudo udevadm control --reload-rules && sudo udevadm trigger

相关python API可参考官方文档:https://docs.luxonis.com/projects/api/en/latest/references/python/#
在此博主提供一个示例:四个相机通过硬件触发同步,使用ROS发布图像消息,并可以自动或手动设置相机参数,更多设置可参考官方文档的API加以修改,完整程序如下:

# -*- coding: utf-8 -*-
#!/usr/bin/env python3
import depthai as dai
import yaml
import cv2
assert cv2.__version__[0] == '4', 'The fisheye module requires opencv version >= 3.0.0'
import numpy as np
import globNAME_LIST = ['cama', 'camb', 'camc', 'camd']FPS = 20
AUTOSET = Truedef clamp(num, v0, v1):return max(v0, min(num, v1))class CameraArray:def __init__(self,fps=20):self.FPS = fpsself.RESOLUTION = dai.ColorCameraProperties.SensorResolution.THE_800_Pself.cam_list = ['cam_a', 'cam_b', 'cam_c', 'cam_d']self.cam_socket_opts = {'cam_a': dai.CameraBoardSocket.CAM_A,'cam_b': dai.CameraBoardSocket.CAM_B,'cam_c': dai.CameraBoardSocket.CAM_C,'cam_d': dai.CameraBoardSocket.CAM_D,}self.pipeline = dai.Pipeline()self.cam = {}self.xout = {}# colorself.controlIn = self.pipeline.create(dai.node.XLinkIn)self.controlIn.setStreamName('control')for camera_name in self.cam_list:self.cam[camera_name] = self.pipeline.createColorCamera()self.cam[camera_name].setResolution(self.RESOLUTION)if camera_name == 'cam_a':  # ref triggerself.cam[camera_name].initialControl.setFrameSyncMode(dai.CameraControl.FrameSyncMode.OUTPUT)else:  # other triggerself.cam[camera_name].initialControl.setFrameSyncMode(dai.CameraControl.FrameSyncMode.INPUT)self.cam[camera_name].setBoardSocket(self.cam_socket_opts[camera_name])self.xout[camera_name] = self.pipeline.createXLinkOut()self.xout[camera_name].setStreamName(camera_name)self.cam[camera_name].isp.link(self.xout[camera_name].input)self.cam[camera_name].setFps(self.FPS)self.config = dai.Device.Config()self.config.board.gpio[6] = dai.BoardConfig.GPIO(dai.BoardConfig.GPIO.OUTPUT, dai.BoardConfig.GPIO.Level.HIGH)self.device = dai.Device(self.config)def start(self):self.device.startPipeline(self.pipeline)self.output_queue_dict = {}for camera_name in self.cam_list:self.output_queue_dict[camera_name] = self.device.getOutputQueue(name=camera_name, maxSize=1, blocking=False)def read_data(self):output_img = {}output_ts = {}for camera_name in self.cam_list:output_data = self.output_queue_dict[camera_name].tryGet()if output_data is not None:timestamp = output_data.getTimestampDevice()img = output_data.getCvFrame()# img = cv2.rotate(img, cv2.ROTATE_180)output_img[camera_name] = imgoutput_ts[camera_name] = timestamp.total_seconds()# print(camera_name, timestamp, timestamp.microseconds, img.shape)else:# print(camera_name, 'No ouput')output_img[camera_name] = Noneoutput_ts[camera_name] = Nonereturn output_img, output_tsif __name__ == '__main__':import rospyfrom sensor_msgs.msg import Imagefrom std_msgs.msg import Headerclass CvBridge():def __init__(self):self.numpy_type_to_cvtype = {'uint8': '8U', 'int8': '8S', 'uint16': '16U','int16': '16S', 'int32': '32S', 'float32': '32F','float64': '64F'}self.numpy_type_to_cvtype.update(dict((v, k) for (k, v) in self.numpy_type_to_cvtype.items()))def dtype_with_channels_to_cvtype2(self, dtype, n_channels):return '%sC%d' % (self.numpy_type_to_cvtype[dtype.name], n_channels)def cv2_to_imgmsg(self, cvim, encoding = "passthrough"):img_msg = Image()img_msg.height = cvim.shape[0]img_msg.width = cvim.shape[1]if len(cvim.shape) < 3:cv_type = self.dtype_with_channels_to_cvtype2(cvim.dtype, 1)else:cv_type = self.dtype_with_channels_to_cvtype2(cvim.dtype, cvim.shape[2])if encoding == "passthrough":img_msg.encoding = cv_typeelse:img_msg.encoding = encodingif cvim.dtype.byteorder == '>':img_msg.is_bigendian = Trueimg_msg.data = cvim.tobytes()img_msg.step = len(img_msg.data) // img_msg.heightreturn img_msgbridge = CvBridge()img_pub_dict = {}rospy.init_node('camera_array', anonymous=True)rate = rospy.Rate(20)for camera_name in ['cam_a', 'cam_b', 'cam_c', 'cam_d']:img_pub_dict[camera_name] = rospy.Publisher('/img/'+str(camera_name), Image, queue_size=0)img_cnt_dict = {'cam_a':0, 'cam_b':0, 'cam_c':0, 'cam_d':0}camera_array = CameraArray(FPS)camera_array.start()controlQueue = camera_array.device.getInputQueue(camera_array.controlIn.getStreamName())if AUTOSET:ctrl = dai.CameraControl()ctrl.setAutoExposureEnable()ctrl.setAutoWhiteBalanceMode(dai.CameraControl.AutoWhiteBalanceMode.AUTO)controlQueue.send(ctrl)else:# Defaults and limits for manual focus/exposure controlsexpTime = 10000expMin = 1expMax = 33000sensIso = 100sensMin = 100sensMax = 1600wbManual = 3500expTime = clamp(expTime, expMin, expMax)sensIso = clamp(sensIso, sensMin, sensMax)print("Setting manual exposure, time:", expTime, "iso:", sensIso)ctrl = dai.CameraControl()ctrl.setManualExposure(expTime, sensIso)ctrl.setManualWhiteBalance(wbManual)controlQueue.send(ctrl)first_time_cam = Nonefirst_time_local = Nonewhile not rospy.is_shutdown():output_img, output_ts = camera_array.read_data()if first_time_cam is None and output_ts['cam_a'] is not None:first_time_cam = output_ts['cam_a']first_time_local = rospy.Time.now().to_sec()for key in output_img.keys():if output_img[key] is None:continueframe = output_img[key]# convertimg = bridge.cv2_to_imgmsg(undistorted_img, encoding="bgr8")img.header = Header()if first_time_cam is not None:ts = output_ts[key] - first_time_cam + first_time_localimg.header.stamp = rospy.Time.from_sec(ts)else:img.header.stamp = rospy.Time.now()img_pub_dict[key].publish(img)rate.sleep()

将程序拷贝到本地,运行程序python camera.py;输入rostopic list,查看话题名;打开Rviz查看图像输出。

相关文章:

OAK相机:自动或手动设置相机参数

OAK相机&#xff1a;自动或手动设置相机参数 硬件软件 硬件 使用硬件如下&#xff1a; 4✖️ov9782相机OAK-FFC-4P驱动板 硬件接线参考博主的一篇博客&#xff1a;OAK相机&#xff1a;多相机硬件同步拍摄 软件 博主使用的是Ubuntu18.04系统&#xff0c;首先配置所需的pytho…...

百家宴焕新上市,持续深耕100-300元价位段

执笔 | 尼 奥 编辑 | 古利特 4月8日&#xff0c;长江酒道曾在《百家宴谋划“晋级”之路&#xff0c;多措并举切分宴席市场“蛋糕”》一文中提到&#xff1a;“百家宴主力新品即将登场&#xff0c;市场政策灵活焕新。” 如今&#xff0c;百家宴新品及市场新政&#xff0c;正…...

Linux Debian12使用git将本地项目上传到码云(gitee)远程仓库

一、注册码云gitee账号 这个可以参考其他教程&#xff0c;本文不做介绍。 gitee官网&#xff1a;https://gitee.com/ 二、Linux Debian12安装git 如果Linux系统没有安装git&#xff0c;可以使用下面命令安装git sudo apt install git 三、gitee新建仓库 我这只做测试&…...

电子烟行业常用的英文表达

1. 电子烟的各种表达 a) 电子烟 i. Electronic-cigarette, ii. Electronic smoke, iii. electronic cigarettes iv. Electric cigarette, v. E-Cigarettes vi. e-cigarette, vii. e-Cig viii. E cigar,e-cigar 电子烟雪茄 2. 电子烟特指词汇及衍生 a) VAPE i. Vapo…...

【SpringMvc 丨跨域】

Spring MVC 支持跨域处理&#xff08;CORS&#xff09;。 CORS 简介处理CORS 过滤器CrossOrigin注解java配置xml配置 主页传送门&#xff1a;&#x1f4c0; 传送 简介 跨域是指在浏览器的同源策略下&#xff0c;不能执行其他网站的脚本。它是由浏览器的安全限制造成的&#xf…...

【C语言】【strlen函数的使用与模拟实现】

1.strlen函数的使用和模拟实现 1.1使用&#xff1a; size_t strlen(const char* str)返回类型为无符号整型&#xff0c;参数是字符指针 计算的是字符串中到“\0"之前的字符个数 1.2模拟实现&#xff1a; 方法一&#xff1a;计数器式遍历 #include<stdio.h> #in…...

类和对象【基础概念】

全文目录 类的定义定义方式 类的访问限定符封装&#xff08;面向对象的三大特性之一&#xff09; 类对象模型类对象的存储方式类对象的大小计算 this指针this指针的特性**this指针可以为空吗&#xff1f;** 类的定义 在C中&#xff0c;C语言中的结构体struct中除了定义变量外还…...

如何测试生成式人工智能(AIGC)

简介&#xff1a;在人工智能日趋普及的今天&#xff0c;生成式人工智能&#xff08;AIGC&#xff09;已经成为不可忽视的一个分支。从自动化生成新闻、编写代码到图像和音频生成&#xff0c;AIGC几乎无处不在。但如何确保这些生成的内容达到预期标准、安全可靠&#xff0c;同时…...

机器学习算法详解3:逻辑回归

机器学习算法详解3&#xff1a;逻辑回归 前言 ​ 本系列主要对机器学习上算法的原理进行解读&#xff0c;给大家分享一下我的观点和总结。 本篇前言 ​ 本篇对逻辑回归的算法原理进行解读。 目录结构 文章目录 机器学习算法详解3&#xff1a;逻辑回归1. 引子2. sigmoid函数3. 原…...

linux命令集合

cd:切换文件路径 pwd:显示当前所处的路径 mkdir&#xff1a;创建目录比如mkdir test touch:创建一个空文件touch test.txt in:用于指定文件夹在另一个位置建立同步的链接in -s /lib/test1 /user/lj 在user目录下建立指向/lib/test1 目录的lj文件 cat:cat file(查看文件内…...

实现卓越供应链:RFID技术的革命性应用

在现代制造业中&#xff0c;供应链和物流的高效运作至关重要&#xff0c;它不仅影响着生产效率&#xff0c;还直接关系到企业的竞争力和客户满意度。为了应对这些挑战&#xff0c;越来越多的企业开始关注智能制造RFID智能设备&#xff0c;将其应用于供应链和物流管理&#xff0…...

从JVM角度看继承

从JVM角度看继承 最近重读了周志明老师的《深入理解JAVA虚拟机》一书&#xff0c;看完大有收获&#xff0c;但仍对继承情况下对象内存布局有所疑惑&#xff0c;所以查阅资料&#xff0c;结合本书进行分析 参考文档&#xff1a; 【深入理解JVM】&#xff1a;Java类继承关系中…...

基于Python和mysql开发的看图猜成语微信小程序(源码+数据库+程序配置说明书+程序使用说明书)

一、项目简介 本项目是一套基于Python和mysql开发的看图猜成语微信小程序&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Python学习者。 包含&#xff1a;项目源码、项目文档、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都…...

Unity入门教程||创建项目(上)

一、介绍 目的&#xff1a;通过尝试制作一款使用玩家角色把小球弹飞的简单小游戏&#xff0c;熟悉使用Unity进行游戏开发的基本流程。 软件环境&#xff1a;Unity 2017.3.0f3&#xff0c;Visual Studio 2013 二、创建新项目 1&#xff0c;启动Unity后将出现一个并列显示Pro…...

Openbmc编译

1.网址的问题解决 原文 Modifying /conf/local.conf was the only solution that worked for me. Simply add one of the two options:#check connectivity using google CONNECTIVITY_CHECK_URIS "https://www.google.com/"#skip connectivity checks CONNECTIVI…...

美国CN2服务器速度怎么样

美国服务器以免备案、大带宽、性价比高的优势&#xff0c;多用于企业、电商、外贸、视频等个中大型网站建设。但是&#xff0c;因中美服 务器接口原因&#xff0c;导致某些服务器的网络并不稳定&#xff0c;这时候就会对美国服务器产品失望&#xff0c;解决这种问题的方法就是选…...

K8S原理架构与实战教程

文章目录 一、背景1.1 物理机时代、虚拟机时代、容器化时代1.2 容器编排的需要 二、K8S架构2.2 Worker节点 三、核心概念3.1 Pod3.2 Deployment3.3 Service3.4 Volume3.5 Namespace 四、K8S安装五、kubectl常用命令六、K8S实战6.1 水平扩容6.2 自动装箱6.2.1 节点污点6.2.2 Pod…...

基于C#的图书管理系统数据库设计报告

第一章 问题描述 1.1 图书管理系统简介 本系统利用.NET处理数据库的功能&#xff0c;实现对图书馆信息的管理。主要功能为管理有关读者、出版社、书籍、借阅和管理者的信息等。 本系统的结构分为读者信息管理模块、出版社信息管理模块、书籍信息管理模块、借阅信息管理模块、…...

【Express.js】pm2进程管理

pm2进程管理 本节我们将介绍如何使用 pm2 运行和监管我们的 express 项目 准备工作 一个 express 项目全局安装 pm2 npm install -g pm2pm2使用介绍 启动应用 你可以用纯命令去运行一个node项目&#xff0c;假设原本运行项目使用 node src/index.js可以跑起来一个项目&am…...

Nginx部署前后端分离项目(Linux)

Nginx代理前端页面、后端接口 一、前端打包二、后端打包三、Linux部署Nginx启动、暂停、重启服务器部署文件地址&#xff1a; 一、前端打包 npm run build二、后端打包 通过Maven 使用package打包 三、Linux部署 安装Nginx 安装环境 yum -y install gcc pcre pcre-devel z…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...

协议转换利器,profinet转ethercat网关的两大派系,各有千秋

随着工业以太网的发展&#xff0c;其高效、便捷、协议开放、易于冗余等诸多优点&#xff0c;被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口&#xff0c;具有实时性、开放性&#xff0c;使用TCP/IP和IT标准&#xff0c;符合基于工业以太网的…...