每一个摄像头单独开一个线程,摄像头配置是否要放进线程内?

每一个摄像头线程内单独处理错误信息

每一个摄像头要存储最新彩色帧和深度帧(用于识别和获取深度信息)

接收打击信号要一个线程,对打击信号进行排序、分析、存储。

识别线程去获取存储的打击信号知道要识别哪个,去调用指定摄像头存储的帧识别,存储识别结果。

发送坐标信息需要一个线程,用于获取识别线程的存储结果进行发送

(因为我们单帧识别时间较长,所以不能使用一直识别的方式,需要采用接收信号然后识别的方式【当然也不排除可以使用预测方式,像商品推荐那样,我预测你哪个机械臂会发来打击信号,然后提前识别然后直接给你发过去】)

20200330 更新

初步完成代码

# -*- coding: utf-8 -*-
"""
@File    : 20200324_多摄像头多线程调度.py
@Time    : 2020/3/24 15:58
@Author  : Dontla
@Email   : sxana@qq.com
@Software: PyCharm
"""import sys
import threading
import time
import traceback
import cv2
import numpy as np
import pyrealsense2 as rs
import dontla_package.tensorflow_yolov3_algorithm as tya
import core.utils as utils# Parameters
# cam_serials = ['836612070298', '838212073806', '827312071616']
cam_serials = ['826212070395', '838212072365']
# cam_serials = ['826212070395']# Needn't modify
cam_num = len(cam_serials)
ctx = rs.context()# 【类】单个摄像头帧传输线程
class CamThread(threading.Thread):def __init__(self, cam_serial):threading.Thread.__init__(self)self.cam_serial = cam_serial# 【类函数】def run(self):while True:try:print('摄像头{}线程启动:'.format(self.cam_serial))# 配置摄像头并启动流# self.cam_cfg(self.cam_serial) # 放函数里就不行了不知为什么?(因为那是局部变量啊傻子,只能在函数内使用)locals()['pipeline' + self.cam_serial] = rs.pipeline(ctx)locals()['config' + self.cam_serial] = rs.config()locals()['config' + self.cam_serial].enable_device(self.cam_serial)locals()['config' + self.cam_serial].enable_stream(rs.stream.depth, 1280, 720, rs.format.z16, 30)locals()['config' + self.cam_serial].enable_stream(rs.stream.color, 1280, 720, rs.format.bgr8, 30)locals()['pipeline' + self.cam_serial].start(locals()['config' + self.cam_serial])locals()['align' + self.cam_serial] = rs.align(rs.stream.color)# 从内存循环读取摄像头传输帧while True:locals()['frames' + self.cam_serial] = locals()['pipeline' + self.cam_serial].wait_for_frames()locals()['aligned_frames' + self.cam_serial] = locals()['align' + self.cam_serial].process(locals()['frames' + self.cam_serial])globals()['aligned_depth_frame' + self.cam_serial] = locals()['aligned_frames' + self.cam_serial].get_depth_frame()locals()['color_frame' + self.cam_serial] = locals()['aligned_frames' + self.cam_serial].get_color_frame()locals()['color_profile' + self.cam_serial] = locals()['color_frame' + self.cam_serial].get_profile()locals()['cvsprofile' + self.cam_serial] = rs.video_stream_profile(locals()['color_profile' + self.cam_serial])locals()['color_intrin' + self.cam_serial] = locals()['cvsprofile' + self.cam_serial].get_intrinsics()globals()['color_intrin_part' + self.cam_serial] = [locals()['color_intrin' + self.cam_serial].ppx,locals()['color_intrin' + self.cam_serial].ppy,locals()['color_intrin' + self.cam_serial].fx,locals()['color_intrin' + self.cam_serial].fy]globals()['color_image' + self.cam_serial] = np.asanyarray(locals()['color_frame' + self.cam_serial].get_data())except Exception:# Dontla 20200326 下面这句主要担心摄像头掉线后,重新配置直到pipeline.start()时,摄像头还未连上,然后又重新执行下面这句就会报管道无法在启动之前关闭的错误,所以加个trytry:locals()['pipeline' + self.cam_serial].stop()except Exception:passprint('摄像头{}线程{}掉线重连:'.format(self.cam_serial, self.name))# 【类】帧处理与显示
class ImgProcess(threading.Thread):def __init__(self, cam_serial):threading.Thread.__init__(self)self.cam_serial = cam_serial# 【类函数】def run(self):while True:try:# 搞了半天我说怎么卡住运行不下去,原来是加锁没try,即使出错也不会释放锁。。。那如果对了不就?是不是不释放锁即使是拥有锁的线程也没法再次获得锁的?# TODO(Dontla)如果某个摄像头掉线,它还一直占用锁怎么办?必须要用到队列?现在的情况是所有都会卡住# 必须要检测globals()['color_image' + self.cam_serial]是否为空if 'color_image{}'.format(self.cam_serial) not in globals():continuethreadLock.acquire()try:locals()['boxes_pr' + self.cam_serial] = YoloTest.predict(globals()['color_image' + self.cam_serial])except Exception:threadLock.release()continue# locals()['boxes_image' + self.cam_serial] = YoloTest.draw_bbox(#     globals()['color_image' + self.cam_serial], locals()['boxes_pr' + self.cam_serial],#     globals()['aligned_depth_frame' + self.cam_serial],#     globals()['color_intrin_part' + self.cam_serial])locals()['boxes_image' + self.cam_serial] = YoloTest.draw_bbox(globals()['color_image' + self.cam_serial], locals()['boxes_pr' + self.cam_serial])cv2.imshow('{}'.format(self.cam_serial), locals()['boxes_image' + self.cam_serial])cv2.waitKey(1)except Exception:traceback.print_exc()pass# 【函数】摄像头连续验证、连续验证机制
def cam_conti_veri(cam_num, ctx):# D·C 1911202:创建最大验证次数max_veri_times;创建连续稳定值continuous_stable_value,用于判断设备重置后是否处于稳定状态max_veri_times = 100continuous_stable_value = 5print('\n', end='')print('开始连续验证,连续验证稳定值:{},最大验证次数:{}:'.format(continuous_stable_value, max_veri_times))continuous_value = 0veri_times = 0while True:devices = ctx.query_devices()# for dev in devices:#     print(dev.get_info(rs.camera_info.serial_number), dev.get_info(rs.camera_info.usb_type_descriptor))connected_cam_num = len(devices)print('摄像头个数:{}'.format(connected_cam_num))if connected_cam_num == cam_num:continuous_value += 1if continuous_value == continuous_stable_value:breakelse:continuous_value = 0veri_times += 1if veri_times == max_veri_times:print("检测超时,请检查摄像头连接!")sys.exit()# 【函数】循环reset摄像头
def cam_hardware_reset(ctx, cam_serials):# hardware_reset()后是不是应该延迟一段时间?不延迟就会报错print('\n', end='')print('开始初始化摄像头:')for dev in ctx.query_devices():# 先将设备的序列号放进一个变量里,免得在下面for循环里访问设备的信息过多(虽然不知道它会不会每次都重新访问)dev_serial = dev.get_info(rs.camera_info.serial_number)# 匹配序列号,重置我们需重置的特定摄像头(注意两个for循环顺序,哪个在外哪个在内很重要,不然会导致刚重置的摄像头又被访问导致报错)for serial in cam_serials:if serial == dev_serial:dev.hardware_reset()# 像下面这条语句居然不会报错,不是刚刚才重置了dev吗?莫非区别在于没有通过for循环ctx.query_devices()去访问?# 是不是刚重置后可以通过ctx.query_devices()去查看有这个设备,但是却没有存储设备地址?如果是这样,# 也就能够解释为啥能够通过len(ctx.query_devices())函数获取设备数量,但访问序列号等信息就会报错的原因了print('摄像头{}初始化成功'.format(dev.get_info(rs.camera_info.serial_number)))# 如果只有一个摄像头,要让它睡够5秒(避免出错,保险起见)time.sleep(5 / len(cam_serials))if __name__ == '__main__':# 连续验证cam_conti_veri(cam_num, ctx)# 摄像头重置cam_hardware_reset(ctx, cam_serials)# 连续验证cam_conti_veri(cam_num, ctx)# 创建YoloTest对象YoloTest = tya.YoloTest()# 创建线程锁threadLock = threading.Lock()globals()['flag'] = True# 创建新线程for serial in cam_serials:locals()['CamThread_{}'.format(serial)] = CamThread(serial)locals()['ImgProcess_{}'.format(serial)] = ImgProcess(serial)# 开启新线程for serial in cam_serials:locals()['CamThread_{}'.format(serial)].start()locals()['ImgProcess_{}'.format(serial)].start()# 阻塞主程序for serial in cam_serials:locals()['CamThread_{}'.format(serial)].join()print("退出主线程")
# -*- coding: utf-8 -*-
"""
@File    : tensorflow_yolov3_algorithm.py
@Time    : 2020/3/27 10:30
@Author  : Dontla
@Email   : sxana@qq.com
@Software: PyCharm
"""
import colorsys
import randomimport cv2
import numpy as np
import tensorflow as tf
import core.utils as utils
from core.config import cfg
from core.yolov3 import YOLOV3# Dontla 191106注释:创建能够返回读取class.names文件信息为字典参数的函数
def read_class_names(class_file_name):"""loads class name from a file"""names = {}with open(class_file_name, 'r') as data:for ID, name in enumerate(data):names[ID] = name.strip('\n')return namesmy_classes = read_class_names(cfg.YOLO.CLASSES)class YoloTest(object):def __init__(self):# D·C 191111:__C.TEST.INPUT_SIZE = 544self.input_size = cfg.TEST.INPUT_SIZEself.anchor_per_scale = cfg.YOLO.ANCHOR_PER_SCALE# Dontla 191106注释:初始化class.names文件的字典信息属性self.classes = utils.read_class_names(cfg.YOLO.CLASSES)# D·C 191115:类数量属性self.num_classes = len(self.classes)self.anchors = np.array(utils.get_anchors(cfg.YOLO.ANCHORS))# D·C 191111:__C.TEST.SCORE_THRESHOLD = 0.3self.score_threshold = cfg.TEST.SCORE_THRESHOLD# D·C 191120:__C.TEST.IOU_THRESHOLD = 0.45self.iou_threshold = cfg.TEST.IOU_THRESHOLDself.moving_ave_decay = cfg.YOLO.MOVING_AVE_DECAY# D·C 191120:__C.TEST.ANNOT_PATH = "./data/dataset/Dontla/20191023_Artificial_Flower/test.txt"self.annotation_path = cfg.TEST.ANNOT_PATH# D·C 191120:__C.TEST.WEIGHT_FILE = "./checkpoint/f_g_c_weights_files/yolov3_test_loss=15.8845.ckpt-47"self.weight_file = cfg.TEST.WEIGHT_FILE# D·C 191115:可写标记(bool类型值)self.write_image = cfg.TEST.WRITE_IMAGE# D·C 191115:__C.TEST.WRITE_IMAGE_PATH = "./data/detection/"(识别图片画框并标注文本后写入的图片路径)self.write_image_path = cfg.TEST.WRITE_IMAGE_PATH# D·C 191116:TEST.SHOW_LABEL设置为Trueself.show_label = cfg.TEST.SHOW_LABEL# D·C 191120:创建命名空间“input”with tf.name_scope('input'):# D·C 191120:建立变量(创建占位符开辟内存空间)self.input_data = tf.placeholder(dtype=tf.float32, name='input_data')self.trainable = tf.placeholder(dtype=tf.bool, name='trainable')model = YOLOV3(self.input_data, self.trainable)self.pred_sbbox, self.pred_mbbox, self.pred_lbbox = model.pred_sbbox, model.pred_mbbox, model.pred_lbbox# D·C 191120:创建命名空间“指数滑动平均”with tf.name_scope('ema'):ema_obj = tf.train.ExponentialMovingAverage(self.moving_ave_decay)# D·C 191120:在允许软设备放置的会话中启动图形并记录放置决策。(不懂啥意思。。。)allow_soft_placement=True表示允许tf自动选择可用的GPU和CPUself.sess = tf.Session(config=tf.ConfigProto(allow_soft_placement=True))# D·C 191120:variables_to_restore()用于加载模型计算滑动平均值时将影子变量直接映射到变量本身self.saver = tf.train.Saver(ema_obj.variables_to_restore())# D·C 191120:用于下次训练时恢复模型self.saver.restore(self.sess, self.weight_file)# 摄像头序列号# self.cam_serials = ['838212073249', '827312070790']# self.cam_serials = ['838212073249', '827312070790', '838212071055', '838212074152', '838212073806',#                     '827312071616']self.cam_serials = ['838212074152', '838212072365', '827312070790', '838212073806', '826212070395']self.cam_num = len(self.cam_serials)# self.cam_num = 2def predict(self, image):# D·C 191107:复制一份图片的镜像,避免对图片直接操作改变图片的内在属性org_image = np.copy(image)# D·C 191107:获取图片尺寸org_h, org_w, _ = org_image.shape# D·C 191108:该函数将源图结合input_size,将其转换成预投喂的方形图像(作者默认544×544,中间为缩小尺寸的源图,上下空区域为灰图):image_data = utils.image_preprocess(image, [self.input_size, self.input_size])# D·C 191108:打印维度看看:# print(image_data.shape)# (544, 544, 3)# D·C 191108:创建新轴,不懂要创建新轴干嘛?image_data = image_data[np.newaxis, ...]# D·C 191108:打印维度看看:# print(image_data.shape)# (1, 544, 544, 3)# D·C 191110:三个box可能存放了预测框图(可能是N多的框,有用的没用的重叠的都在里面)的信息(但是打印出来的值完全看不懂啊喂?)pred_sbbox, pred_mbbox, pred_lbbox = self.sess.run([self.pred_sbbox, self.pred_mbbox, self.pred_lbbox],feed_dict={self.input_data: image_data,self.trainable: False})# D·C 191110:打印三个box的类型、形状和值看看:# print(type(pred_sbbox))# print(type(pred_mbbox))# print(type(pred_lbbox))# 都是<class 'numpy.ndarray'># print(pred_sbbox.shape)# print(pred_mbbox.shape)# print(pred_lbbox.shape)# (1, 68, 68, 3, 6)# (1, 34, 34, 3, 6)# (1, 17, 17, 3, 6)# print(pred_sbbox)# print(pred_mbbox)# print(pred_lbbox)# D·C 191110:(-1,6)表示不知道有多少行,反正你给我整成6列,然后concatenate又把它们仨给叠起来,最终得到无数个6列数组(后面self.num_classes)个数存放的貌似是这个框属于类的概率)pred_bbox = np.concatenate([np.reshape(pred_sbbox, (-1, 5 + self.num_classes)),np.reshape(pred_mbbox, (-1, 5 + self.num_classes)),np.reshape(pred_lbbox, (-1, 5 + self.num_classes))], axis=0)# D·C 191111:打印pred_bbox和它的维度看看:# print(pred_bbox)# print(pred_bbox.shape)# (18207, 6)# D·C 191111:猜测是第一道过滤,过滤掉score_threshold以下的图片,过滤完之后少了好多:# D·C 191115:bboxes维度为[n,6],前四列是坐标,第五列是得分,第六列是对应类下标bboxes = utils.postprocess_boxes(pred_bbox, (org_h, org_w), self.input_size, self.score_threshold)# D·C 191111:猜测是第二道过滤,过滤掉iou_threshold以下的图片:bboxes = utils.nms(bboxes, self.iou_threshold)return bboxesdef draw_bbox(self, image, bboxes, aligned_depth_frame=None, color_intrin_part=None, show_label=True):"""bboxes: [x_min, y_min, x_max, y_max, probability, cls_id] format coordinates."""# D·C 191117:创建存放class.names文件中类数目的变量num_classes = len(my_classes)# Dontla 20191014# print(num_classes)# 80# D·A 191117# print(num_classes)# 1# D·A 191117:获取图片分辨率image_h, image_w, _ = image.shape# Dontla 20191014# print('(image_h,image_w):', image_h, '', image_w)# (image_h,image_w): 240  424# D·C 191118:hsv颜色模式第一个数表示色阶,用于将不同类别的框分配给不同颜色,#             用RGB模式不好做颜色分配,用这种方法分配后再转换成rgb模式,方便很多!hsv_tuples = [(1.0 * x / num_classes, 1., 1.) for x in range(num_classes)]# D·A 191118 打印hsv_tuples看看# print(hsv_tuples)# [(0.0, 1.0, 1.0)]# D·C 191118:将hsv颜色模式转换成rgb颜色模式colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))# D·A 191118 打印colors看看# print(colors)# [(1.0, 0.0, 0.0)]# D·C 191118:将转换后的值分配给0-255colors = list(map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)), colors))# Dontla 20191014# print(type(colors))# <class 'list'># print(colors)# [(255, 0, 0)]# D·C 191119:生成固定随机数种子random.seed(0)# D·C 191119:将colors里的颜色打乱(由于设定了随机数种子,每次打乱后的颜色顺序都是一样的)random.shuffle(colors)# D·C 191119:取消固定随机数种子random.seed(None)# Dontla 20191017# print('*' * 50)# print(bboxes)# [array([1.57846606e+00, 3.41371887e+02, 8.33116150e+01, 4.69713715e+02, 3.56435806e-01, 7.30000000e+01]),#  array([3.03579620e+02, 3.27595886e+02, 6.24216125e+02, 4.67514557e+02, 4.15683120e-01, 6.30000000e+01]),#  array([356.42529297, 143.32351685, 424.81719971, 191.51617432,0.55459815,  62.        ]),#  array([468.05984497, 186.09997559, 638.58270264, 295.89181519,0.68913358,  57.        ])]# 解释:每个元素前四位数值为框左上角和右下角坐标,第五位为真实概率,第六位为类号。如book为73,laptop为63。# 识别出目标:book 中心点像素坐标:(42, 405) 深度:0.640m# 识别出目标:laptop 中心点像素坐标:(464, 397) 深度:0.479m# 识别出目标:tvmonitor 中心点像素坐标:(390, 167) 深度:4.274m# 识别出目标:sofa 中心点像素坐标:(553, 240) 深度:1.608m# Dontla 20191017# 提取ppx,ppy,fx,fy# Dontla 20191104 Dontla reformed at 20200301# 如果color_intrin_part不为空(因为参数在传入之前color_frame和aligned_depth_frame都已经判断过了,这里没必要再做判断)if color_intrin_part:ppx = color_intrin_part[0]ppy = color_intrin_part[1]fx = color_intrin_part[2]fy = color_intrin_part[3]# D·C 191119:获取行列索引作为下标for i, bbox in enumerate(bboxes):# 取前四位数字作为画框坐标coor = np.array(bbox[:4], dtype=np.int32)# 创建标注字符字体大小的变量?(将fontScale增加后,发现画框左上角的文字变大了)fontScale = 0.5# 取第五位数字作为得分值score = bbox[4]# 取第六位数字作为类号class_ind = int(bbox[5])# print(class_ind)# 如:59# 以类序号分配颜色bbox_color = colors[class_ind]# print(bbox_color)# 如:(255, 0, 133) 不知道是咋跟序号对应上的?(见前面,框颜色的创建) 【识别出目标:bed 中心点像素坐标:(322, 374) 深度:4.527m】# D·C 191119:设置框的边宽?不过为啥不直接设置成:bbox_thick = int((image_h + image_w) / 1000)bbox_thick = int(0.6 * (image_h + image_w) / 600)# Dontla 20191014# print(type(bbox_thick))# <class 'int'># print(bbox_thick)# 640×480像素下固定为1,因为之前用的是424×248像素所以值为0# print(0.6 * (640 + 480) / 600)# 1.12# 创建存储框左上角和右下角坐标的变量c1, c2 = (coor[0], coor[1]), (coor[2], coor[3])# Dontla 20191014# print(c1, '', c2)# 貌似打印出的就是识别框的左上角和右下角坐标(以图像左上角为原点,x轴水平向右,y轴垂直向下)# 如 (126, 77)  (229, 206)#    (363, 112)  (423, 239)# D·C 191119:绘制矩形框cv2.rectangle(image, c1, c2, bbox_color, bbox_thick)# D·C 191119:如果允许显示标签if show_label:# D·C 191119:创建需显示在框左上角的字符信息(类名+得分)bbox_mess = '%s: %.2f' % (my_classes[class_ind], score)# Dontla 20191017# print(type(bbox_mess))# <class 'str'># print(bbox_mess)# 如:# keyboard: 0.66# laptop: 0.48# D·A 191119:获取目标的中心点坐标,round后默认带一位小数,可用int去掉它target_xy_pixel = [int(round((coor[0] + coor[2]) / 2)), int(round((coor[1] + coor[3]) / 2))]# Dontla 20191104 Dontla reformed at 20200301# 如果aligned_depth_frame不为空(因为参数在传入之前color_frame和aligned_depth_frame都已经判断过来,这里没必要再做判断)if aligned_depth_frame:target_depth = aligned_depth_frame.get_distance(target_xy_pixel[0], target_xy_pixel[1])target_xy_true = [(target_xy_pixel[0] - ppx) * target_depth / fx,(target_xy_pixel[1] - ppy) * target_depth / fy]# Dontla commented out at 20200301(测试掉线不需要打印这个,先注释掉)# print('识别出目标:{} 中心点像素坐标:({}, {}) 实际坐标(mm):({:.0f},{:.0f}) 深度(mm):{:.0f}'.format(classes[class_ind],#                                                                                 target_xy_pixel[0],#                                                                                 target_xy_pixel[1],#                                                                                 target_xy_true[#                                                                                     0] * 1000,#                                                                                 -target_xy_true[#                                                                                     1] * 1000,#                                                                                 target_depth * 1000))# print('识别出目标:{} 中心点像素坐标:({}, {}) 深度:{:.3f}m'.format(classes[class_ind], target_xy_pixel[0],#                                                     target_xy_pixel[1],#                                                     target_depth))# 识别出目标:cup 中心点像素坐标:(317, 148)# 识别出目标:keyboard 中心点像素坐标:(398, 162)# 识别出目标:bottle 中心点像素坐标:(321, 124)# D·C 191119:计算bbox_mess字符所占像素的大小t_size = cv2.getTextSize(bbox_mess, 0, fontScale, thickness=bbox_thick // 2)[0]# D·A 191119:打印t_size看看:# print(t_size)# (97, 12)# D·A 191119:打印cv2.getTextSize(bbox_mess, 0, fontScale, thickness=bbox_thick // 2)看看:# print(cv2.getTextSize(bbox_mess, 0, fontScale, thickness=bbox_thick // 2))# ((97, 12), 5)     # 5是基线与中线的距离,我们这里用不到,所以就舍去了# D·C 191119:绘制装载文字的矩形实心框# D·R 191119:当框在顶端,标签显示不出来,我想把它弄到框内# 原始为:cv2.rectangle(image, c1, (c1[0] + t_size[0], c1[1] - t_size[1] - 3), bbox_color, thickness=-1)  # filledcv2.rectangle(image, c1, (c1[0] + t_size[0], c1[1] + t_size[1] + 3), bbox_color, thickness=-1)  # filled# D·C 191119:绘制文字# D·R 191119:当框在顶端,标签显示不出来,我想把它弄到框内(bbox_thick是线宽。-2是底线到中线距离?)# 原始为:cv2.putText(image, bbox_mess, (c1[0], c1[1] - 2), cv2.FONT_HERSHEY_SIMPLEX,#                         fontScale, (0, 0, 0), bbox_thick // 2, lineType=cv2.LINE_AA)cv2.putText(image, bbox_mess, (c1[0], c1[1] + t_size[1] + bbox_thick - 2), cv2.FONT_HERSHEY_SIMPLEX,fontScale, (0, 0, 0), bbox_thick // 2, lineType=cv2.LINE_AA)return image

Intel Realsense D435 多摄像头多线程目标识别架构相关推荐

  1. intel realsense d435深度摄像头使用

    intel realsense d435深度摄像头基本环境配置 基本参考官网给的教程来就ok的 ,这里还是发一下我最初配置d435的记录 官网链接: https://github.com/intel- ...

  2. Intel Realsense D435 测试摄像头在不同曝光值下的帧生成时间(防止曝光时间过长导致fps下降)auto_exposure_priority(没成功)

    文章目录 不用测了 下面测试auto_exposure_priority参数在自动曝光下的作用 下面测试在自动曝光模式下如何实时获取曝光值 测试摄像头在不同曝光值下的帧生成时间 不用测了 参考文章:I ...

  3. Intel Realsense D435 hardware_reset() 摄像头重置记录 context.query_devices()

    摄像头重置后它自己不能马上恢复,如果我们重置后立即访问它们,就会出错,以下是一些问题记录: 之前是使用device=ctx.query_device(),后面重置后检测摄像头的时候直接用len(dev ...

  4. 为什么Intel Realsense D435深度摄像头在基于深度的水平方向障碍物检测(避障)方案中,摄像头不宜安装太高?

    补一句,为啥R与b对比就要比R与a对比更容易区分? 因为a与b的右端和障碍物R属同一深度,但b左端明显比a左端深度大,总体比a拥有差异性更大的深度范围,因此b与a相比,对R拥有差异性更大的深度范围, ...

  5. Tensorflow yolov3 Intel Realsense D435 单摄像头下各模块识别时间测试

    文章目录 1.一次循环总耗时 2.从循环开始到self.predict()之前 3.第一次循环主要耗时函数:wait_for_frames()(其实self.predict()函数在第一次循环更耗时) ...

  6. Intel Realsense D435 当摄像头运行过程中突然USB线断开,对RuntimeError: Frame didn't arrived within 5000的异常捕获及处理

    如图,在摄像头运行过程中,摄像头突然断开,可能设备需要对异常进行捕获并处理(如摄像头重连,发出警报,发送信号给车辆让它停止前进等) 需阅读,python异常捕获及处理 191225 通过捕获所有异常, ...

  7. Intel Realsense D435 获取摄像头option参数值 get_option()

    def get_option(self, option): # real signature unknown; restored from __doc__"""get_o ...

  8. Intel Realsense D435 多摄像头配置 Multi-camera configurations (220)(官方测试的摄像头配置表【不同带宽下分辨率、帧率等】)

    参考文章:Multi-camera configurations 1.异步传输(stream asynchronously)是否会对我们的识别造成影响?如果有影响,影响是否可忽略不计. 2020032 ...

  9. Intel Realsense D435 python multiprocessing 摄像头多进程流传输

    参考文章1:python 测试multiprocessing多进程 参考文章2:Intel Realsense D435 多摄像头目标识别架构

最新文章

  1. 三层交换机的热备实验
  2. 步步为营 .NET 代码重构学习笔记 十一
  3. 拋棄虛擬機,微軟實驗讓我們在線做(二)
  4. oracle 数据库日期定义,Oracle数据库实现日期遍历功能
  5. 当前时间加30分钟_男性早晨坚持慢跑30分钟,一段时间后,或许这些变化不请自来...
  6. 小程序手写板电子签名
  7. Ghrome浏览器安装IE TAB插件的方法
  8. 泛微OA云桥 未授权任意文件读取
  9. 微处理器系统结构与嵌入式系统设计(二)
  10. 山东大学研究生计算机学院导师,山东大学计算机科学与技术学院研究生导师简介-杨义军...
  11. JSON数据交互和RESTful支持
  12. MS Materials Studio 安装
  13. java 将set转成数组,Java程序将Set转换为数组
  14. Leetcode771:宝石与石头
  15. python xlrd模块_新手菜鸟Linux学习之路
  16. 我的世界服务器地皮系统,我的世界服务器怎么创建地皮世界
  17. 刷脸支付无人便利店的使用体验也更好了
  18. 适合普通大众、非科班的路线
  19. vim列删除、列修改
  20. SQL Server(MSSQLSERVER)无法启动问题解决

热门文章

  1. 还有多少时间可以用来读书
  2. 计算机信息处理技术知识点,计算机信息处理技术基础知识.doc
  3. 什么时间回复客户邮件最有效?
  4. 【已修正】SAP中各个环境的简介
  5. 【转】后勤自动过帐(OBYC)详细配置说明
  6. 项目由于装运点不同交货拆分解决方案
  7. SAP 解决长时间不操作掉线问题
  8. SAP-检查多个关联字段输入,以及有条件地调用模块
  9. 下沉市场惊现出行小巨头 松果共享电单车日订单破300w
  10. 长沙望城:当好“贴心人” 扎牢“人民根” 坚守“云阵地”