Java使用OpenCV3.2实现视频读取与播放

Java使用OpenCV3.2实现视频读取与播放,供大家参考,具体内容如下

OpenCV从3.x版本开始其JAVA语言的SDK支持视频文件读写,这样就极大的方便了广大Java语言开发者学习与使用OpenCV,通过摄像头或者视频文件读取帧的内容与播放,完成视频内容分析与对象跟踪等各种应用开发任务。可以说OpenCV C++ SDK可以做到绝大多数事情,在OpenCV3.x版本上用Java都可以完成,这样就为很多Java开发者学习OpenCV打开了方便之门。

实现思路

首先用OpenCV相关API读取视频流或者视频文件的每一帧,然后通过Swing JComponent组件实现视频每一帧的更新显示,我模仿了C++的HIGHGUI里面创建窗口与显示图像接口,基于Swing实现了一个视频播放窗口类,把读取到的每一帧都传给它就可以实现连续显示即播放。每帧之间相隔100毫秒,我是通过Java线程Sleep方法实现。

运行效果 - USB摄像头读取每帧

运行效果 - 视频文件读取每帧

代码实现

视频文件读取

package com.gloomyfish.video.demo;

import java.awt.Dimension;
import java.awt.image.BufferedImage;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.videoio.VideoCapture;

public class VideoDemo {

  public static void main(String[] args) {
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    // 打开摄像头或者视频文件
    VideoCapture capture = new VideoCapture();
    //capture.open(0);
    capture.open("D:/vcprojects/images/768x576.avi");
    if(!capture.isOpened()) {
      System.out.println("could not load video data...");
      return;
    }
    int frame_width = (int)capture.get(3);
    int frame_height = (int)capture.get(4);
    ImageGUI gui = new ImageGUI();
    gui.createWin("OpenCV + Java视频读与播放演示", new Dimension(frame_width, frame_height));
    Mat frame = new Mat();
    while(true) {
      boolean have = capture.read(frame);
      Core.flip(frame, frame, 1);// Win上摄像头
      if(!have) break;
      if(!frame.empty()) {
        gui.imshow(conver2Image(frame));
        gui.repaint();
      }
      try {
        Thread.sleep(100);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }

  }

  public static BufferedImage conver2Image(Mat mat) {
    int width = mat.cols();
    int height = mat.rows();
    int dims = mat.channels();
    int[] pixels = new int[width*height];
    byte[] rgbdata = new byte[width*height*dims];
    mat.get(0, 0, rgbdata);
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    int index = 0;
    int r=0, g=0, b=0;
    for(int row=0; row<height; row++) {
      for(int col=0; col<width; col++) {
        if(dims == 3) {
          index = row*width*dims + col*dims;
          b = rgbdata[index]&0xff;
          g = rgbdata[index+1]&0xff;
          r = rgbdata[index+2]&0xff;
          pixels[row*width+col] = ((255&0xff)<<24) | ((r&0xff)<<16) | ((g&0xff)<<8) | b&0xff;
        }
        if(dims == 1) {
          index = row*width + col;
          b = rgbdata[index]&0xff;
          pixels[row*width+col] = ((255&0xff)<<24) | ((b&0xff)<<16) | ((b&0xff)<<8) | b&0xff;
        }
      }
    }
    setRGB( image, 0, 0, width, height, pixels);
    return image;
  }

  /**
   * A convenience method for setting ARGB pixels in an image. This tries to avoid the performance
   * penalty of BufferedImage.setRGB unmanaging the image.
   */
  public static void setRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {
    int type = image.getType();
    if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )
      image.getRaster().setDataElements( x, y, width, height, pixels );
    else
      image.setRGB( x, y, width, height, pixels, 0, width );
  }

}

视频与图像显示窗口类

package com.gloomyfish.video.demo;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

import javax.swing.JComponent;
import javax.swing.JDialog;

public class ImageGUI extends JComponent {
  /**
   *
   */
  private static final long serialVersionUID = 1L;
  private BufferedImage image;

  public ImageGUI() {

  }

  @Override
  protected void paintComponent(Graphics g) {
    Graphics2D g2d = (Graphics2D)g;
    if(image == null) {
      g2d.setPaint(Color.BLACK);
      g2d.fillRect(0, 0, this.getWidth(), this.getHeight());
    } else {
      g2d.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), null);
      System.out.println("show frame...");
    }
  }

  public void createWin(String title) {
    JDialog ui = new JDialog();
    ui.setTitle(title);
    ui.getContentPane().setLayout(new BorderLayout());
    ui.getContentPane().add(this, BorderLayout.CENTER);
    ui.setSize(new Dimension(330, 240));
    ui.setVisible(true);
  }

  public void createWin(String title, Dimension size) {
    JDialog ui = new JDialog();
    ui.setTitle(title);
    ui.getContentPane().setLayout(new BorderLayout());
    ui.getContentPane().add(this, BorderLayout.CENTER);
    ui.setSize(size);
    ui.setVisible(true);
  }

  public void imshow(BufferedImage image) {
    this.image = image;
    this.repaint();
  }

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java使用OpenCV从视频文件中获取帧

    本文实例为大家分享了java使用OpenCV从视频文件中获取帧的具体代码,供大家参考,具体内容如下 实现功能:使用Java获取mp4.mov.avi等视频文件中的图像帧,每秒获取一帧图像,并保存 环境要求:需要安装Opencv,安装FFmpeg,下载javacv包 操作系统:本次实验使用的Ubuntu系统 实验代码 import com.googlecode.javacv.cpp.opencv_highgui; import org.opencv.core.Core; import org.op

  • Java使用OpenCV3.2实现视频读取与播放

    Java使用OpenCV3.2实现视频读取与播放,供大家参考,具体内容如下 OpenCV从3.x版本开始其JAVA语言的SDK支持视频文件读写,这样就极大的方便了广大Java语言开发者学习与使用OpenCV,通过摄像头或者视频文件读取帧的内容与播放,完成视频内容分析与对象跟踪等各种应用开发任务.可以说OpenCV C++ SDK可以做到绝大多数事情,在OpenCV3.x版本上用Java都可以完成,这样就为很多Java开发者学习OpenCV打开了方便之门. 实现思路 首先用OpenCV相关API读

  • opencv3/C++实现视频读取、视频写入

    视频读取 视频读取,主要利用VideoCapture类下的方法打开视频并获取视频中的帧,具体示例如下: #include<iostream> #include<opencv2/opencv.hpp> using namespace cv; int main() { VideoCapture capture; Mat frame; frame= capture.open("E:/image/a1.avi"); if(!capture.isOpened()) { p

  • SpringBoot + thymeleaf 实现读取视频列表并播放视频功能

    目录 效果 实现过程 后端程序示例 前端程序示例 通过读取数据库video表获取当前视频的视频名.视频地址,展示至前端页面videorecord.html,通过点击播放按钮获取数据id进而得到所选视频地址,跳转播放视频显示页videoshow.html,播放所选视频.当然本案例只是为了展示主要的一些功能,其他比如跳转.页面布局美化等可以自行进行更改. 效果 Springboot播放视频 实现过程 后端程序示例 1. Controller层示例 返回数据库数据时,使用了pagehelp当中的Pag

  • Java详解IO流创建读取与写入操作

    目录 概念 io流对应的方法 一.File方法(创建文件) 二.FileInputStream(获取字节方法)输入流 三.FileOutputStream(写入字节方法)输出流 总结 概念 IO流可以初步的理解为数据间的传输,我们将一组数据入:1234567,将他们从hello文件中转入haha文件中,使用程序的方法进行转入的话则需要一个一个的传入,即为一个字节一个字节的传输,我们每次只能传入或读取一个字节,这就是io流的大致流程,io流对任何类型的文件都可以进行读取.如:文本文件,图片,歌曲m

  • Java实现获取图片和视频文件的Exif信息

    目录 前言 一.相关知识简介 1.Metadata 元数据 2.Exif 可交换图像文件信息 3.metadata-extractor 库 二.使用步骤 1.创建Maven项目 2.Metadata信息获取 3.根据不同的Directory精确Tag提取 4.经纬度提取 5.视频元数据提取 三.对Exif的中文解释 四.总结 前言 随着现在实景地图的如火如荼建设,无人机等航拍测绘手段的不断升级,我们在获取全景照片或者正射影像,全景视频等数据上更加快速.便捷.由于无人机本身不进行相关数据的处理,比

  • Java获取XML节点总结之读取XML文档节点的方法

    dom4j是Java的XML API,用来读写XML文件的.目前有很多场景中使用dom4j来读写xml的. 要使用dom4j开发,需要下载导入dom4j相应的jar文件. 官网下载:http://www.dom4j.org/dom4j-1.6.1/ github下载:http://dom4j.github.io/ 下载解压之后如图所示: 我们只需要把dom4j-1.6.1.jar文件构建到我们开发项目中就可以了. 下面就以Eclipse创建java项目的构建方法为例说明: 声明:本Java项目的

  • Java 自定义注解及利用反射读取注解的实例

    一.自定义注解 元注解: @interface注解: 定义注解接口 @Target注解: 用于约束被描述的注解的使用范围,当被描述的注解超出使用范围则编译失败.如:ElementType.METHOD,ElementType.TYPE: @Retention 注解:用于约束被定义注解的作用范围,作用范围有三个: 1.RetentionPolicy.SOURCE:作用范围是源码,作用于Java文件中,当执行javac时去除该注解. 2.RetentionPolicy.CLASS:作用范围是二进制码

  • Java实现从jar包中读取指定文件的方法

    本文实例讲述了Java实现从jar包中读取指定文件的方法.分享给大家供大家参考,具体如下: 以下的Java代码实现了从一个jar包中读取指定文件的功能: /** * This class implements the funcationality of reading and writing files in jar files. */ package com.leo.util; import java.io.InputStream; import java.io.FileOutputStrea

  • Java RandomAccessFile 指定位置实现文件读取与写入

    Java RandomAccessFile 指定位置实现文件读取与写入 RandomAccessFile是属于随机读取类,是可以对文件本身的内容直接随机进行操作的,可以在文件的指定位置的读取和写入内容,这在很多时候都是很方便的. RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek( )方法来访问记录,并进行读写了.这些记录的大小不必相同:但是其大小和位置必须是可知的.但是该类仅限于操作文件. RandomAccessFile不属于InputStream和Out

  • Java编程实现向文本文件中读取数据之Scanner用法示例

    本文实例讲述了Java编程实现向文本文件中读取数据之Scanner用法.分享给大家供大家参考,具体如下: 使用Scanner类来读取文件 我们使用Scanner类来从键盘上读取数据,也可以使用Scanner类来从文本文件中读取数据,我们先来看一个实例代码 package com.li; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.*; public class Mai

随机推荐