C/S构架的USB摄像头视频采集
2009-08-14 20:01
337 查看
最近开始做一个机器人操作界面RescueOperator。主要功能有:
显示安装在机器人上的摄像头采集到得视频
显示机器人传感器状态
控制机器人运动
控制机器人手臂
昨天刚刚实现了摄像头视频显示功能。为了调试方便,先做了一个测试用的AgentTest。AgentTest采集USB摄像头视频,并通过网络传输给RescueOperator。
我用JMF[1]
来采集视频。JMF支持添加视频,声音等媒体信息,并且支持捕捉,回放,译码。我只是用它来采集显示视频。相关的类有:
javax.media.CaptureDeviceManager
javax.media.CaptureDeviceInfo
javax.media.Player
javax.media.Manager
CaptureDeviceManager负责管理系统中所哟可用的采集设备。在使用前需要通过JMFRegister注册USB摄像头,也可用通过CaptureDeviceManager来注册采集设备。
CaptureDeviceInfo用于保存采集设备的信息,包括设备输出格式,设备名,MediaLocater。
MediaLocator负责描述媒体内容的位置。它与URL相似。采用一种vfw协议。USB摄像头的MediaLocator.toString()为“vfw://0”。
Player是一个接口,继承MediaHandler和Controller。它负责显示,控制媒体数据。
Manager可以让程序访问系统非独立资源,比如Player,DataSources,Processor等。这里,我用它根据MediaLocator创建Player实例。实例化Player后,需要调用其Start()方法。为了显示视频,我们需要调用Player的getVisualComponent()方法来获得一个gui组建。将该组件添加到窗口中,就可以显示摄像头四品了。
对于AgentTest,最关键的是将视频截为一帧帧图片,再发送给操作站。截取视频也可以使用JMF来实现。首先,获得FrameGrabbingControl实例:
然后直接获得当前帧的buffer
最后将buffer转为byte[],这个过程比较复杂(应该有更简单的方法吧)
发送信息中还要添加图片的字节长度,方便操作站接受。这样就大功告成了,直接发送...
接下来就是完成操作站的接受和显示工作。
接受时先读取图片字节长度,然后读取图片数据。然后用java.awt.Toolkit将图片数据生成图片。
然后就只剩把一帧一帧图片画到Canvas上了。调用drawImage()方法时,需要传一个ImageObserver[2]
。调用drawImage()时,image可能还没有完全加载,甚至还没有开始加载。如果drawImage()方法等待图片加载,可能会降低程序响应速度。所以java会在开启一加载图片的线程来监视图片加载。ImageObserver就是用来监视图片加载状态的。java提供三种监视图片加载方法:
ImageObserver 重写imageUpdate
()方法,手动监视加载图片
MediaTracker 加载多个图片
ImageIcon 加载单个图片
显然,我需要MediaTracker。想MediaTracker中添加图片时需要给一个ID。ID决定加载图片的优先级,ID越小,优先级越高。
最后比较一下ImageObserver和MediaTracker的性能。加载连续图片时,MediaTracker用时<20ms,而ImageObserver需要100ms左右,相差一个数量级。
需要改进:
CPU使用率高
向MediaTracker添加图片时,用了ArrayList和HashMap,虽然不会太大,但可能没有必要
AgentTest中,用Buffer生成图片的方法太繁琐,效率低
进一步工作:
完成视频接收显示测试,主要测试延时;
确定电机控制协议;
实现按键响应->控制信息发送;
设计GUI界面;
接收图片与接收其他传感器信息分别用两个Socket。因为图片数据是基于字节的,而其他传感器信息是基于数字或字符串的;
将图片解析从AgentSenseThread中移出,并添加其他传感器信息的解析模块;
引用:
[1] http://java.sun.com/javase/technologies/desktop/media/jmf/index.jsp
[2] http://www.particle.kth.se/~lindsey/JavaCourse/Book/Part1/Java/Chapter11/loadingImages.html
显示安装在机器人上的摄像头采集到得视频
显示机器人传感器状态
控制机器人运动
控制机器人手臂
昨天刚刚实现了摄像头视频显示功能。为了调试方便,先做了一个测试用的AgentTest。AgentTest采集USB摄像头视频,并通过网络传输给RescueOperator。
我用JMF[1]
来采集视频。JMF支持添加视频,声音等媒体信息,并且支持捕捉,回放,译码。我只是用它来采集显示视频。相关的类有:
javax.media.CaptureDeviceManager
javax.media.CaptureDeviceInfo
javax.media.MediaLocator
javax.media.Player
javax.media.Manager
CaptureDeviceManager负责管理系统中所哟可用的采集设备。在使用前需要通过JMFRegister注册USB摄像头,也可用通过CaptureDeviceManager来注册采集设备。
CaptureDeviceInfo用于保存采集设备的信息,包括设备输出格式,设备名,MediaLocater。
MediaLocator负责描述媒体内容的位置。它与URL相似。采用一种vfw协议。USB摄像头的MediaLocator.toString()为“vfw://0”。
Player是一个接口,继承MediaHandler和Controller。它负责显示,控制媒体数据。
Manager可以让程序访问系统非独立资源,比如Player,DataSources,Processor等。这里,我用它根据MediaLocator创建Player实例。实例化Player后,需要调用其Start()方法。为了显示视频,我们需要调用Player的getVisualComponent()方法来获得一个gui组建。将该组件添加到窗口中,就可以显示摄像头四品了。
对于AgentTest,最关键的是将视频截为一帧帧图片,再发送给操作站。截取视频也可以使用JMF来实现。首先,获得FrameGrabbingControl实例:
FrameGrabbingControl fgc = (FrameGrabbingControl) cameraView.player.getControl("javax.media.control.FrameGrabbingControl");
然后直接获得当前帧的buffer
Buffer buffer = fgc.grabFrame();
最后将buffer转为byte[],这个过程比较复杂(应该有更简单的方法吧)
BufferToImage b2i = new BufferToImage((RGBFormat) buffer.getFormat()); Image capturedImage = b2i.createImage(buffer); // show the image BufferedImage bImage; try { bImage = new BufferedImage(capturedImage.getWidth(cameraView), capturedImage.getHeight(cameraView), BufferedImage.TYPE_INT_RGB); } catch (NullPointerException e) { e.printStackTrace(); return; } Graphics2D bImageG = bImage.createGraphics(); bImageG.drawImage(capturedImage, 0, 0, capturedImage.getWidth(cameraView), capturedImage .getHeight(cameraView), cameraView); bImageG.dispose(); ByteArrayOutputStream byteOS = new ByteArrayOutputStream(); try { ImageIO.write(bImage, "JPEG", byteOS); byte[] imageData = byteOS.toByteArray(); }catch(){ }
发送信息中还要添加图片的字节长度,方便操作站接受。这样就大功告成了,直接发送...
接下来就是完成操作站的接受和显示工作。
接受时先读取图片字节长度,然后读取图片数据。然后用java.awt.Toolkit将图片数据生成图片。
然后就只剩把一帧一帧图片画到Canvas上了。调用drawImage()方法时,需要传一个ImageObserver[2]
。调用drawImage()时,image可能还没有完全加载,甚至还没有开始加载。如果drawImage()方法等待图片加载,可能会降低程序响应速度。所以java会在开启一加载图片的线程来监视图片加载。ImageObserver就是用来监视图片加载状态的。java提供三种监视图片加载方法:
ImageObserver 重写imageUpdate
()方法,手动监视加载图片
MediaTracker 加载多个图片
ImageIcon 加载单个图片
显然,我需要MediaTracker。想MediaTracker中添加图片时需要给一个ID。ID决定加载图片的优先级,ID越小,优先级越高。
最后比较一下ImageObserver和MediaTracker的性能。加载连续图片时,MediaTracker用时<20ms,而ImageObserver需要100ms左右,相差一个数量级。
需要改进:
CPU使用率高
向MediaTracker添加图片时,用了ArrayList和HashMap,虽然不会太大,但可能没有必要
AgentTest中,用Buffer生成图片的方法太繁琐,效率低
进一步工作:
完成视频接收显示测试,主要测试延时;
确定电机控制协议;
实现按键响应->控制信息发送;
设计GUI界面;
接收图片与接收其他传感器信息分别用两个Socket。因为图片数据是基于字节的,而其他传感器信息是基于数字或字符串的;
将图片解析从AgentSenseThread中移出,并添加其他传感器信息的解析模块;
引用:
[1] http://java.sun.com/javase/technologies/desktop/media/jmf/index.jsp
[2] http://www.particle.kth.se/~lindsey/JavaCourse/Book/Part1/Java/Chapter11/loadingImages.html
相关文章推荐
- USB视频采集系统 视频测试软件将正式发布(方便调试测试各自摄像头,RAW,RGB,YUV)
- 用v4l2和framebuffer实现usb摄像头视频采集并显示
- Ehome:智能家居之基于USB摄像头免驱的视频采集服务器
- 一个可以将usb摄像头的视频和麦克风采集的声音以RTMP协议发布到RTMP Server的应用程序
- 用v4l2和framebuffer实现usb摄像头视频采集并显示
- Windows下Qt使用Usb摄像头采集视频实现鼠标事件
- 基于itop4412在Linux最小系统下的USB摄像头采集视频的H264编码
- 基于USB摄像头视频数据采集和利用FFMPEG库函数进行视频数据压缩
- 基于USB摄像头视频数据采集和利用FFMPEG库函数进行视频数据压缩
- 在raspberry上使用USB摄像头做视频采集
- Python+OpenCV采集本地摄像头的视频
- 基于Video4Linux的USB摄像头图像采集实现
- opencv3 采集摄像头的画面canny化,或者读取视频
- C# 如何采集摄像头的视频
- Android摄像头采集的视频数据流如何通过Socket实时发送到目标服务端
- 采集音频和摄像头视频并实时H264编码及AAC编码
- mjpg-streamer 移植到OK6410,从摄像头采集视频直播
- Linux V4L2 摄像头视频采集
- 采集音频和摄像头视频并实时H264编码及AAC编码
- USB摄像头(V4L2接口)的图片采集 (一)