1.理论知识

https://zhuanlan.zhihu.com/c_1263787122512822272
相机工作原理介绍

http://t.zoukankan.com/eve612-p-13841736.html
相机SDK介绍

https://zhuanlan.zhihu.com/p/468033445

2.代码解读

(sick的visionary-s双目3D相机的SDK)

1. 链接相机

deviceStreaming = Device.Streaming(args.ipAddress,args.tcpPort)
deviceStreaming.openStream()''' Opens the streaming channel. '''
def openStream(self):logging.warning("HPF Opening streaming socket..."),self.sock_stream = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 2,1self.sock_stream.settimeout(5)try:self.sock_stream.connect((self.ipAddress, self.tcpPort))except socket.error as err:logging.error("Error on connecting to %s:%d: %s" % (self.ipAddress, self.tcpPort, err))sys.exit(2)logging.info("...done.")

2.发送接收数据请求

通过socket发送blob请求

deviceStreaming.sendBlobRequest()
def sendBlobRequest(self):""" Sending a blob request. """MSG_BLREQ_TX = b'BlbReq'logging.debug("Sending BlbReq: %s" % (to_hex(MSG_BLREQ_TX)))self.sock_stream.send(MSG_BLREQ_TX)

3.定义一个data类接受数据

dontStop = TruemyData = Data.Data()

4.接受数据放在devicestreaming.frame

while dontStop:try:deviceStreaming.getFrame() # 下面有实现wholeFrame = deviceStreaming.framemyData.read(wholeFrame)if myData.hasDepthMap:print('\nData contains depth map data:')print('Frame number: ', myData.depthmap.frameNumber)distanceData = myData.depthmap.distance

前面向相机发送了字符“BlbReq”,然后执行了getframe,

def getFrame(self):""" Receives the raw data frame from the device via the streaming channel."""logging.warning('HPF !!_> Reading image from stream...')keepRunning = TrueBLOB_HEAD_LEN = 11header = self.sock_stream.recv(BLOB_HEAD_LEN)  # minimum headerframeAcqStart = time.perf_counter()logging.debug("len(header) = %d dump: %s" % (len(header),to_hex(header)))if len(header) < BLOB_HEAD_LEN:raise RuntimeError("Uh, not enough bytes for BLOB_HEAD_LEN, only %s" % (len(header)))# check if the header content is as expected(magicword, pkgLength, protocolVersion, packetType) = \struct.unpack('>IIHB', header)  #  Python中按一定的格式取出某字符串中的子字符串 if magicword != 0x02020202:logging.error("Unknown magic word: %0x" % (magicword))keepRunning = Falseif protocolVersion != 0x0001:logging.error("Unknown protocol version: %0x" % (protocolVersion))keepRunning = Falseif packetType != 0x62:logging.error("Unknown packet type: %0x" % (packetType))keepRunning = Falseif not keepRunning:raise RuntimeError('something is wrong with the buffer')# -3 for protocolVersion and packetType already received# +1 for checksumtoread = pkgLength - 3 + 1logging.debug("pkgLength: %d" % (pkgLength))logging.debug("toread: %d" % (toread))data = bytearray(len(header) + toread)view = memoryview(data)view[:len(header)] = headerview = view[len(header):]while toread:nBytes = self.sock_stream.recv_into(view, toread)if nBytes==0:# premature end of connectionraise RuntimeError("received {} but requested {} bytes".format(len(data)-len(view), pkgLength))view = view[nBytes:]toread -= nBytesself.frame = str(data)frameAcqStop = time.perf_counter()logging.info("Receiving took %0.1f ms"%((frameAcqStop-frameAcqStart)*1000))# full frame should be received nowlogging.debug("...done.")


首先定义一个长度是head+plglength的data数组。然后把数组的内存地址给到view,操作view就相当于操作了data,所有后面获取sock的数据都是存在data里,然后赋值给self.frame

5. 获取frame赋值给刚开始定义的data类

wholeFrame = deviceStreaming.framemyData.read(wholeFrame)
def read(self, dataBuffer):
""" Extracts necessary data segments and triggers parsing of segments. """# first 11 bytes contain some internal definitions
tempBuffer = dataBuffer[0:11]
(magicword, pkglength, protocolVersion, packetType) = \unpack('>IIHB', tempBuffer)
assert (magicword == 0x02020202)
logging.debug("Package length: %s", pkglength)
logging.debug("Protocol version: %s", protocolVersion)  # expected to be == 1
logging.debug("Packet type: %s", packetType)  # expected to be  == 98# next four bytes an id (should equal 1) and
# the number of segments (should be 3)
tempBuffer = dataBuffer[11:15]
(segid, numSegments) = unpack('>HH', tempBuffer)
logging.debug("Blob ID: %s", segid)  # expected to be == 1
logging.debug("Number of segments: %s", numSegments)  # expected to be  == 3# offset and changedCounter, 4 bytes each per segment
offset = [None] * numSegments
changedCounter = [None] * numSegments
tempBuffer = dataBuffer[15:15 + numSegments * 2 * 4]
for i in range(numSegments):index = i * 8(offset[i], changedCounter[i]) = \unpack('>II', tempBuffer[index:index + 8])offset[i] += 11
logging.debug("Offsets: %s", offset)  # offset in bytes for each segment
logging.debug("Changed counter: %s", changedCounter)  # counter for changes in the data# first segment describes the data format in XML
xmlSegment = dataBuffer[offset[0]:offset[1]]
logging.debug("The whole XML segment:")
logging.debug(xmlSegment)
# second segment contains the binary data
binarySegment = dataBuffer[offset[1]:offset[2]]if (numSegments == 3):overlaySegment = dataBuffer[offset[2]:pkglength+4+4] # numBytes(magicword) = 4, numBytes(pkglength) = 4logging.debug("The whole overlay XML segment:")logging.debug(overlaySegment)checksum = dataBuffer[pkglength+8]
if checksum != self.checksum:logging.error("Checksum is wrong: %s (expected %s)" % (checksum, self.checksum)) # checksum of whole dataself.corrupted = True
else:logging.debug("Checksum: %s", checksum) # checksum of whole dataself.corrupted = False# parsing the XML in order to extract necessary image information
# only parse if something has changed
if (self.changedCounter < changedCounter[0]):logging.debug("XML did change, parsing started.")myXMLParser = XMLParser()myXMLParser.parse(xmlSegment)self.xmlParser = myXMLParserself.changedCounter = changedCounter[0]
else:logging.debug("XML did not change, not parsing again.")myXMLParser = self.xmlParsermyBinaryParser = BinaryParser()self.hasDepthMap = False
self.hasPolar2D = False
self.hasCartesian = Falseif myXMLParser.hasDepthMap:logging.debug("Data contains depth map, reading camera params")self.hasDepthMap = Trueself.cameraParams = \CameraParameters(width=myXMLParser.imageWidth,height=myXMLParser.imageHeight,cam2worldMatrix=myXMLParser.cam2worldMatrix,fx=myXMLParser.fx, fy=myXMLParser.fy,cx=myXMLParser.cx, cy=myXMLParser.cy,k1=myXMLParser.k1, k2=myXMLParser.k2,f2rc=myXMLParser.f2rc)# extracting data from the binary segment (distance, intensity# and confidence).if myXMLParser.stereo:numBytesDistance = myXMLParser.imageHeight * \myXMLParser.imageWidth * \myXMLParser.numBytesPerZValueelse:numBytesDistance = myXMLParser.imageHeight * \myXMLParser.imageWidth * \myXMLParser.numBytesPerDistanceValuenumBytesIntensity = myXMLParser.imageHeight * \myXMLParser.imageWidth * \myXMLParser.numBytesPerIntensityValuenumBytesConfidence = myXMLParser.imageHeight * \myXMLParser.imageWidth * \myXMLParser.numBytesPerConfidenceValuetry:numBytesFrameNumber = myXMLParser.numBytesFrameNumbernumBytesQuality = myXMLParser.numBytesQualitynumBytesStatus = myXMLParser.numBytesStatusexcept AttributeError:numBytesFrameNumber = 0numBytesQuality = 0numBytesStatus = 0logging.info("Reading binary segment...")myBinaryParser.getDepthMap(binarySegment,numBytesFrameNumber,numBytesQuality,numBytesStatus,numBytesDistance,numBytesIntensity,myXMLParser.numBytesPerIntensityValue,numBytesConfidence)logging.info("...done.")if myXMLParser.stereo:distance = list(myBinaryParser.depthmap.distance)for i in range(0, len(distance)):distance[i] = distance[i] / 10.0 #account for sub-millimeter valuesmyBinaryParser.depthmap.distance = tuple(distance)self.depthmap = myBinaryParser.depthmapif myXMLParser.hasPolar2DData:self.hasPolar2D = Trueif (myXMLParser.hasDepthMap):myBinaryParser.getPolar2D(myBinaryParser.remainingBuffer, myXMLParser.numPolarValues)else:myBinaryParser.getPolar2D(binarySegment, myXMLParser.numPolarValues)if hasattr(myBinaryParser, 'polardata'):self.polarData2D = myBinaryParser.polardataelse:self.hasPolar2D = False
elif myXMLParser.hasCartesianData:self.hasCartesian = Trueif (myXMLParser.hasDepthMap):myBinaryParser.getCartesian(myBinaryParser.remainingBuffer)else:myBinaryParser.getCartesian(binarySegment)if hasattr(myBinaryParser, 'cartesianData'):self.cartesianData = myBinaryParser.cartesianDataelse:self.hasCartesian = False
  1. 先取出11个长度的头文件
    2.取出4个长度
    3.给offest和changecounter赋值 offest表示数据片段大小

    4.第一个片段,是xml数据,第二个是binary数据,第三个是覆盖xml数据(???)


然后把切割出来的数据分发到相应的实例中

这里myxmlparser.parse 是读取xml文件内容 ,然后把self.xmlparser=myXMLParser


根据xml的参数 获取binarysegment中的数据,然后把深度数据放入myBinaryParser的self.depthmap

然后在赋值给self.depthmap

相机工作原理和理解SDK流程相关推荐

  1. uart怎么判断帧错误_UART通讯总线工作原理的理解

    奥的斯电梯OCSS/LCBII /TCBC/GECB板与电梯轿厢和电梯井道之间的串行通讯采用了UART通讯,将井道和轿厢的输入.输出和开关部件的信号转换成串行通讯信号传输给电梯操作控制系统,大大节省了 ...

  2. uart怎么判断帧错误_UART通讯总线工作原理的理解--龚玉山

    奥的斯电梯OCSS/LCBII /TCBC/GECB板与电梯轿厢和电梯井道之间的串行通讯采用了UART通讯,将井道和轿厢的输入.输出和开关部件的信号转换成串行通讯信号传输给电梯操作控制系统,大大节省了 ...

  3. Spring aop 原始的工作原理的理解

    理解完aop的名词解释,继续学习spring aop的工作原理. 首先明确aop到底是什么东西?又如何不违单一原则并实现交叉处理呢? 如果对它的认识只停留在面向切面编程,那就脏了.从oop(Objec ...

  4. 深度相机工作原理 (AMCW)

    工作原理 ToF成像,深度相机实现调幅连续波 (AMCW) 时差测距 (ToF) 原理. 该相机将近红外 (NIR) 频谱中的调制光投射到场景中. 然后,它会记录光线从相机传播到场景,然后从场景返回到 ...

  5. 彩色CCD相机工作原理

    原理 黑白(单色)相机        CCD原理并不复杂.我们可以把它想象成一个顶部被打开的记忆芯片.因此光束可以射到记忆单元中.根据"光电效应",这些光束在记忆单元中产生负电荷( ...

  6. SpringCloud Feign工作原理基本理解

    Feign介绍 Feign是Netflix公司开源的轻量级rest客户端,使用Feign可以非常方便的实现Http 客户端.Spring Cloud引入Feign并且集成了Ribbon实现客户端负载均 ...

  7. 计算机漫游用户的工作原理,深入理解计算机系统——计算机系统漫游

    前言 入坑计算机原理嘛,漫游慢慢游 思维导图 1.1 信息就是位+上下文 什么是位? 一个程序的生命周期是从一个源程序开始的,源程序实际上就是一个有值 0 和 1 组成的 位(比特 序列,8个位 为一 ...

  8. Tuner及工作原理介绍

    Tuner的介绍 Tuner是什么? 为了提高电视信号的传输效率,减少于扰,电视信号通常都采用射频(RF)信号传输方式,即把要传输的视频或音频信号调制(作幅度调制AM或频率调制FM)到频率较高的射频载 ...

  9. 图解搜索引擎工作原理

    做SEO的,如果不懂搜索引擎的工作原理是很难恰当开展工作的.前几天给学生讲SEO课程中的搜索引擎工作原理时,很多同学表示不太懂.后来我画了搜索引擎主要工作流程的示意图给大家,很多同学表示"懂 ...

  10. MMU相关概念及工作原理介绍

    MMU相关概念及工作原理介绍 笔者这篇文章主要从使用者的角度介绍MMU的相关概念和工作原理. 一. MMU是什么,为什么要用它 在了解MMU之前需要了解下面几个概念: 物理地址(Physical Ad ...

最新文章

  1. 类和对象—继承—同名成员处理
  2. 《剑指offer》二维数组中的查找
  3. 机器学习(一) 基于sklearn库的数据集划分(交叉验证)
  4. 简单在于的acdsee 2012
  5. bucket sort sample sort 并行_Java 中 Arrays.sort 和 Arrays.parallelSort 哪个更快?
  6. 基于物理的渲染详尽指南 卷1光与介质:基于物理的渲染和着色理论
  7. c++语言中如何检测鼠标消息,c++ 如何检测全局鼠标按钮事件
  8. distpicker实现省市级联动
  9. 阿里云服务器安装Nginx
  10. 路由器 android 打印机,用路由器将普通打印机变成网络打印机
  11. 银行家算法实现(操作系统实验)
  12. unity编辑器扩展篇-中文字段显示
  13. Brocade 6510 交换机清空配置,重新initiator交换机
  14. 【黑盒测试】 正交排列法设计测试用例
  15. linux的gpio设备,Linux 4.x之Gpio分析(一)Gpiolib库1
  16. C10K 问题引发的技术变革
  17. 基于PHP后台的购物商城微信小程序的设计与实现 毕业设计毕设参考
  18. canvas孙悟空脚踩白云今年是猴年
  19. oracle建用户之前是否必须建表空间,Oracle数据库-建库、建表空间,建用户
  20. 1049:晶晶赴约会

热门文章

  1. [通过scikit-learn掌握机器学习] 01基础
  2. 2.4 是否同一棵二叉搜索树(树,c)
  3. Game AI Pro Principles of Multiagent Systems and Reinf
  4. ssm社区团购平台cu9o99
  5. 工业摄像头临时简易支架
  6. 视频压缩与编解码的基本原理
  7. 携手支付宝,首旅如家送出“天使特权”致敬医护
  8. 关于通达信REFDATE函数的未来属性
  9. Android微信登录、分享、支付
  10. 微信发送自定义卡片消息