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

作者:gloomyfish 时间:2023-11-23 06:14:02 

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摄像头读取每帧

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

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

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

代码实现

视频文件读取


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();
 }

}

来源:https://blog.csdn.net/jia20003/article/details/69934353

标签:java,OpenCV3.2,视频
0
投稿

猜你喜欢

  • C#之CLR内存深入分析

    2023-01-24 17:18:07
  • Java 的可变参数方法详述

    2022-06-03 19:12:34
  • Android开发之android_gps定位服务简单实现

    2023-07-31 20:02:25
  • Android网格视图GridView的使用

    2023-06-12 20:27:33
  • c#简单工厂、工厂方法与抽象工厂的区别分析

    2021-11-30 04:39:47
  • c#的dllimport使用方法详解

    2023-04-20 04:01:49
  • SpringBoot Knife4j在线API文档框架基本使用

    2022-03-10 21:27:48
  • 详解Java中数组判断元素存在几种方式比较

    2021-09-25 13:49:21
  • 解读@RequestBody与post请求的关系

    2022-10-07 02:02:51
  • Springboot实现图片上传功能的示例代码

    2022-08-05 22:46:44
  • Android仿京东分类模块左侧分类条目效果

    2022-09-09 04:35:34
  • C# 列表List的常用属性和方法介绍

    2022-09-04 07:52:05
  • java后台批量下载文件并压缩成zip下载的方法

    2021-07-24 21:13:11
  • Java装饰者模式的示例详解

    2022-03-30 07:26:22
  • Java8新特性之默认方法和静态方法

    2021-08-29 13:34:26
  • springboot配置https访问的方法

    2022-12-11 16:17:37
  • Java线程通信中关于生产者与消费者案例分析

    2022-01-18 10:49:25
  • Spring Boot集成ElasticSearch实现搜索引擎的示例

    2021-06-02 05:06:16
  • spring boot中使用@Async实现异步调用任务

    2023-04-25 13:35:18
  • Android中handler使用浅析

    2022-08-22 23:45:16
  • asp之家 软件编程 m.aspxhome.com