不想写论文不想写摘要不想写绪论不想写研究背景不想写现状。。。
嗯,好久不写博客,因为我在忙(bu)着(xiang)写(chao)论文。为我的心理健康着想,我决定搞点东西玩玩。于是我去某宝买了这个:
实际上这个是一种型号为DS-3DW300的日产3d摄像头,每个头最大分辨率为640x480,最大帧率为30fps,彩色。
焊好usb连接线并连接到ubuntu,用lsusb命令获取其usb描述符信息,可以发现:
$ lsusb -d 18e3:5031 -v
...
bFunctionClass 14 Video
...
好嘛,uvc啊,直接拿Cheese打开:
你大爷的。。果然不用官方软件(CHUSEI 3D Camera)就只能打开一个头啊,而且那个软件是windows独占的。
没办法,开心的Hack吧
既然是UVC协议,先考虑SELECTOR_UNIT中有多个输入的情况。呃。。。瞄了一眼刚才lsusb获取的信息发现:
bNrInPins 1
好吧,去他大爷的uvc,还是从官方软件下手吧。切换到windows下,用BusHound抓取在软件中切换双摄像头时,usb总线上的数据:
Bus Hound 6.01 capture on Windows Vista Service Pack 1 (x64). Complements of www.perisoft.net
double
Device - Device ID (followed by the endpoint for USB devices)
(26) USB 视频设备
Length - Total transfer length
Phase - Phase Type
CTL USB control transfer
IN Data in transfer
OUT Data out transfer
Data - Hex dump of the data transferred
Descr - Description of the phase
Cmd... - Position in the captured data
Driver - Driver that submitted the command
ntoskrnl : NT Kernel & System 6.1.7601.19135 (win7sp1_gdr.160121-1718)
Device Length Phase Data Description Cmd.Phase.Ofs(rep) Driver
------ -------- ----- ------------------------ ---------------- ------------------ ------------
26.0 CTL a1 85 00 08 00 06 02 00 GET LEN 1.1.0 ntoskrnl
26.0 2 IN 02 00 .. 1.2.0
26.0 CTL 21 01 00 08 00 06 02 00 SET CUR 2.1.0 ntoskrnl
26.0 2 OUT 50 ff P. 2.2.0
26.0 CTL a1 85 00 0f 00 06 02 00 GET LEN 3.1.0 ntoskrnl
26.0 2 IN 02 00 .. 3.2.0
26.0 CTL 21 01 00 0f 00 06 02 00 SET CUR 4.1.0 ntoskrnl
26.0 2 OUT 00 f6 .. 4.2.0
...
26.0 2 OUT 76 c3 v. 32.2.0
26.0 CTL a1 85 00 0a 00 06 02 00 GET LEN 33.1.0 ntoskrnl
26.0 2 IN 02 00 .. 33.2.0
26.0 CTL 21 01 00 0a 00 06 02 00 SET CUR 34.1.0 ntoskrnl
26.0 2 OUT 04 00 .. 34.2.0
嘿,SET CUR。。。翻出UVC协议来看了一眼,果然所有的输出数据都是SET CUR的格式。后面我又抓去了左、右以及红蓝模式切换时的数据,发现这4种情况下总线上的数据都是一样的,只有最后一个SET CUR分别穿出的是1234。
也就是说,只要我们自己构造出相应的SET CUR指令流,就可以实现摄像头工作方式的切换了!于是乎就有了下面这段脚本:
# need pyusb and python binding for opencv
# also need libusb installed
import cv2
import usb.core
cam=cv2.VideoCapture(0)
dev = usb.core.find(idVendor=0x18e3, idProduct=0x5031)
# simulate the SET_CUR sequence
dev.ctrl_transfer(0x21,0x01,0x0800,0x0600,[0x50,0xff])
dev.ctrl_transfer(0x21,0x01,0x0f00,0x0600,[0x00,0xf6])
dev.ctrl_transfer(0x21,0x01,0x0800,0x0600,[0x25,0x00])
dev.ctrl_transfer(0x21,0x01,0x0800,0x0600,[0x5f,0xfe])
dev.ctrl_transfer(0x21,0x01,0x0f00,0x0600,[0x00,0x03])
dev.ctrl_transfer(0x21,0x01,0x0f00,0x0600,[0x00,0x02])
dev.ctrl_transfer(0x21,0x01,0x0f00,0x0600,[0x00,0x12])
dev.ctrl_transfer(0x21,0x01,0x0f00,0x0600,[0x00,0x04])
dev.ctrl_transfer(0x21,0x01,0x0800,0x0600,[0x76,0xc3])
k=0
while (k!=ord('q')):
ret,frame=cam.read()
cv2.imshow("cam_test",frame)
k=cv2.waitKey(18)&0xFF
kv=k-ord('0')
# print(kv)
# if press 1,2,3 or 4, change the 3d camera mode
if kv in [1,2,3,4]:
dev.ctrl_transfer(0x21,0x01,0x0a00,0x0600,[kv,0x00])
运行脚本并按下“4”,结果如下:
可以的,把两张图压缩一半然后当成一张图通过UVC传输,跟我做的那个双摄像头差不多,不过我是利用YUV格式来隐藏两张灰度图(还是我的强一点哈哈哈哈哈哈哈哈哈(。ì _ í。))。
玩完收工,憋论文去~~