《Java图像处理:基于OpenCV与JVM》 ——1.13 处理视频流
1.13 处理视频流
问题定义
你希望使用OpenCV来对视频流进行实时的图像处理。
解决方法
Java版本的OpenCV提供了一个videoio包,以及一个特定的VideoCapture对象,它提供了多种方法来直接从连接的视频设备中读取矩阵对象。
首先,你会看到如何从视频设备中获取一个特定大小的矩阵对象,然后将矩阵存入文件中。
通过使用帧(frame),你将看到如何将之前学习到的预处理代码应用在实时获取到的图像中。
工作原理
拍摄静止图片
首先介绍do_still_captures函数。它的输入参数是一组需要抓取的帧、每帧间隔的时间以及从哪个camera_id读入图像。
camera_id是连接到你机器的捕获设备索引。通常你会使用0,但是如果你还有其他外接设备的话,就要选择对应的camera_id。
首先创建一个 VideoCapture对象,camera_id作为参数。
然后创建一个空的矩阵对象,把它传入camera.read()函数来读取数据。
这里的矩阵对象是你熟悉的标准OpenCV矩阵Mat,于是你也可以应用那些之前学过的变换。
到目前为止,我们先把每一帧存储好,用时间戳作为文件名。
完成后,你可以通过VideoCapture对象中的release函数来把相机设置回待机模式。
看看以下代码是怎么实现的。
调用新建的函数只需填入所需参数,接下来从ID为0的设备中读取10张图片,每间隔1秒拍摄1次。
如图1-32所示,这10张图片被创建在该项目的video文件夹中。确实,时间过得飞快,现在已经是深夜了。
图1-32 静止卧室的掠影
实时处理
好吧,坏消息是OpenCV的Java封装不包含将矩阵转为BufferedImage的明确方法,BufferedImage是Java的graphic包中处理图像的对象。
这里不介绍太多细节,假设你需要一个MatToBufferedImage函数来实时处理Java帧,通过把矩阵对象转换为BufferedImage,即可将它渲染为标准的Java GUI对象。
让我们快速地写一个函数,将矩阵转换为标准的Java BufferedImage。
当你有了这段代码之后,事情就变得简单了起来。但你仍然需要另外一段代码:一个自定义的panel,它继承了Java的Panel类JPanel。
这个自定义的panel,称为MatPanel,包含一个需要绘制的矩阵对象。MatPanel继承Java的JPanel类的方法是,在paint() 函数中直接调用你刚刚见过的函数:MatToBufferedImage。
好了,标准OpenCV包中缺少的代码已经被实现了,你可以直接创建JFrame来接收矩阵对象。
本攻略的最后一步是使用一段与do_still_captures函数类似的代码,但并不在几帧之后停下,你将会写一个无限循环来处理视频流。
图1-33展示了一个日本房间在凌晨1点钟的实时景象,通过JFrame实时渲染。
显然,目标是实时处理矩阵对象,对于你来说一个很好的练习是试着生成图1-34所示的屏幕截图效果。
图1-33 使用JFrame展示的实时视频流 图1-34 实时进行Canny处理的图像
答案如下所示,你也应该猜到了,这段代码只是将Canny函数应用在视频读取的矩阵对象中。
- 点赞
- 收藏
- 关注作者
评论(0)