基于OpenCv和swing实现图片/视频的展示

图片的展示

swing展示图片,多为操作BufferedImage,这里要关注的核心是将Mat转为BufferedImage。

代码如下:

  1. public Image toBufferedImage(Mat matrix) {
  2. int type = BufferedImage.TYPE_BYTE_GRAY;
  3. if (matrix.channels() > 1) {
  4. type = BufferedImage.TYPE_3BYTE_BGR;
  5. }
  6. int bufferSize = matrix.channels() * matrix.cols() * matrix.rows();
  7. byte[] buffer = new byte[bufferSize];
  8. matrix.get(0,0,buffer); // get all the pixels
  9. BufferedImage image = new BufferedImage(matrix.cols(),matrix.rows(),type);
  10. final byte[] targetPixels = ((DataBufferByte)image.getRaster().getDataBuffer()).getData();
  11. System.arraycopy(buffer,0,targetPixels,0,buffer.length);
  12. return image;
  13. }

comment 1:OpenCV Mat --> BufferedImage AWT , 创建一个byte array用以保存mat 矩阵的像素信息。数组大小为通道数和图片宽/高之积。其中,Mat.get()将所有的元素导入byte数组。最终,图片的光栅信息通过 getDataBuffer()和getDate()组成接收数组,并通过System.arraycopy方法完成填充。实现最终的类型与数据的转移。

comment 2:图片/视频,最终展示的都为BufferedImage,并在JFrame中展示,这里可将toBufferedImage与swing组件配置以展示的部分抽取为类ImageReader。如下:

  1. import org.opencv.core.Mat;
  2.  
  3. import javax.swing.*;
  4. import java.awt.*;
  5. import java.awt.image.BufferedImage;
  6. import java.awt.image.DataBufferByte;
  7.  
  8. /**
  9. * @Author: nya
  10. * @Description: 图片展示类
  11. * @Date: Created in 10:55 2018/9/21
  12. * @Modify by:
  13. */
  14. public class ImageViewer {
  15. private JLabel imageView;
  16.  
  17. public void show(Mat image,String windowName) {
  18. setSystemLookAndFeel();
  19. JFrame frame = createJFrame(windowName);
  20. Image loadedImage = toBufferedImage(image);
  21. imageView.setIcon(new ImageIcon(loadedImage));
  22.  
  23. frame.pack();
  24. frame.setLocationRelativeTo(null);
  25. frame.setVisible(true);
  26. }
  27.  
  28. private JFrame createJFrame(String windowName) {
  29. JFrame frame = new JFrame(windowName);
  30. imageView = new JLabel();
  31. final JScrollPane imageScrollPane = new JScrollPane(imageView);
  32. imageScrollPane.setPreferredSize(new Dimension(640,480));
  33. frame.add(imageScrollPane,BorderLayout.CENTER);
  34. frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
  35. return frame;
  36. }
  37.  
  38. private void setSystemLookAndFeel() {
  39. try {
  40. UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
  41. } catch (ClassNotFoundException e) {
  42. e.printStackTrace();
  43. } catch (InstantiationException e) {
  44. e.printStackTrace();
  45. } catch (IllegalAccessException e) {
  46. e.printStackTrace();
  47. } catch (UnsupportedLookAndFeelException e) {
  48. e.printStackTrace();
  49. }
  50. }
  51.  
  52. public Image toBufferedImage(Mat matrix) {
  53. int type = BufferedImage.TYPE_BYTE_GRAY;
  54. if (matrix.channels() > 1) {
  55. type = BufferedImage.TYPE_3BYTE_BGR;
  56. }
  57. int bufferSize = matrix.channels() * matrix.cols() * matrix.rows();
  58. byte[] buffer = new byte[bufferSize];
  59. matrix.get(0,0,buffer); // get all the pixels
  60. BufferedImage image = new BufferedImage(matrix.cols(),matrix.rows(),type);
  61. final byte[] targetPixels = ((DataBufferByte)image.getRaster().getDataBuffer()).getData();
  62. System.arraycopy(buffer,0,targetPixels,0,buffer.length);
  63. return image;
  64. }
  65. }

image Mat operate code:

  1. String path = "src/main/java/com/opencv/simpleopencvsample/sample/1.jpg";
  2. Mat openFile = null;
  3. try {
           // openFile just is path to mat
  4. openFile = openFile(path);
  5. Mat clone = openFile.clone();
  6. System.out.println(openFile);
  7. Imgproc.resize(openFile,clone,new Size(640,480));
  8. System.out.println(clone);
  9. ImageViewer imageViewer = new ImageViewer();
  10. imageViewer.show(clone,"Loaded image");
  11.  
  12. } catch (Exception e) {
  13. e.printStackTrace();
  14. } finally {
  15. // comment : never forget to release the matrix
  16. if (openFile != null ) {
  17. openFile.release();
  18. }
  19. }
  20. System.out.println(openFile);

视频的展示

有了图片展示为蓝本,视频的操作关键在于VideoCapture类的使用,展示部分不过是捕获视频的每一帧转为Mat,基于swing循环顺序展示即可。获取mat推荐采用read(),此方法为grab()/retrieve()的结合体。

为适应视频处理的JFrame宽高,此处自定义设置,主要采用toBufferedImage方法。

VideoCapture -> Mat -> display code:

  1. import org.opencv.core.Core;
  2. import org.opencv.core.Mat;
  3. import org.opencv.videoio.VideoCapture;
  4. import org.opencv.videoio.Videoio;
  5.  
  6. import javax.swing.*;
  7. import java.awt.*;
  8.  
  9. /**
  10. * @Author: nya
  11. * @Description: 视频捕获相关操作类VideoCapture使用
  12. * @Date: Created in 13:50 2018/9/21
  13. * @Modify by:
  14. */
  15. public class VideoCaptureSample {
  16. static {
  17. System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
  18. }
  19. private JFrame frame;
  20. private JLabel imageLabel;
  21.  
  22. public static void main(String[] args) {
  23. VideoCaptureSample sample = new VideoCaptureSample();
  24. sample.initGUI();
  25. sample.runMainLoop(args);
  26. }
  27.  
  28. private void initGUI(){
  29. frame = new JFrame("Camera Input Example");
  30. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  31. frame.setSize(555,970);
  32. imageLabel = new JLabel();
  33. frame.add(imageLabel);
  34. frame.setVisible(true);
  35. }
  36.  
  37. private void runMainLoop(String[] args) {
  38. ImageViewer viewer = new ImageViewer();
  39. Mat webcamMatImage = new Mat();
  40. Image tempImage;
  41. VideoCapture capture = new VideoCapture("src/main/java/com/opencv/simpleopencvsample/sample/1.mp4");
  42. capture.set(Videoio.CAP_PROP_FRAME_WIDTH,550);
  43. capture.set(Videoio.CAP_PROP_FRAME_HEIGHT,960);
  44. if (capture.isOpened()) {
  45. while (true) {
  46. capture.read(webcamMatImage);
  47. if (!webcamMatImage.empty()) {
  48. tempImage = viewer.toBufferedImage(webcamMatImage);
  49. ImageIcon imageIcon = new ImageIcon(tempImage,"Captured video");
  50. imageLabel.setIcon(imageIcon);
  51. frame.pack();
  52. } else {
  53. System.out.println(" --- Frame not captured -- Break !");
  54. break;
  55. }
  56. }
  57. } else {
  58. System.out.println("Couldn't open capture.");
  59. }
  60. }
  61. }

常见异常 VideoCapture-isOpened返回false

  实际测试中,存在视频路径正常,isOpened()一直返回false的问题。

  这是因为视频处理类VideoCapture位于opencv_videoio模块,使用该类时需在运行时加载预先构建的opencv_ffmpeg * .dll / so。该模块如果加载成功,ffmpeg可用于解码/编码视频;否则,使用其它API。在排除路径问题后,仍然无法读取视频则多为此情况。

  解决方法很简单,将动态库dll/so导入 管理员/root 权限下配置的java.library.path路径下即可。

基于OpenCv和swing的图片/视频展示Java实现的更多相关文章

  1. 使用图片视频展示插件blueimp Gallery改造网站的视频图片展示

    在很多情况下,我们网站可能会展示我们的产品图片.以及教程视频等内容,结合一个比较好的图片.视频展示插件,能够使得我们的站点更加方便使用,也更加酷炫,在Github上有很多相关的处理插件可以找来使用,有 ...

  2. 基于opencv在摄像头ubuntu根据视频获取

     基于opencv在摄像头ubuntu根据视频获取 1  工具 原料 平台 :UBUNTU12.04 安装库  Opencv-2.3 2  安装编译执行步骤 安装编译opencv-2.3  參考h ...

  3. 【图像处理】基于OpenCV底层实现的图片旋转

    image processing 系列 [图像处理]直方图匹配 [图像处理]高斯滤波.中值滤波.均值滤波 图片旋转,本质上是对旋转后的图片中每一个像素点计算在原图的位置.然后照搬过来就好. (多说一句 ...

  4. Java基于OpenCV实现走迷宫(图片+路线展示)

    Java基于OpenCV实现走迷宫(图片+路线展示) 由于疫情,待在家中,太过无聊.同学发了我张迷宫图片,让我走迷宫来缓解暴躁,于是乎就码了一个程序出来.特此记录. 原图: 这张图,由于不是非常清晰, ...

  5. 基于OpenCV实现对图片及视频中感兴趣区域颜色识别

    基于OpenCV实现图片及视频中选定区域颜色识别 近期,需要实现检测摄像头中指定坐标区域内的主体颜色,通过查阅大量相关的内容,最终实现代码及效果如下,具体的实现步骤在代码中都详细注释,代码还可以进一步 ...

  6. OpenCV2学习笔记(十四):基于OpenCV卡通图片处理

    得知OpenCV有一段时间.除了研究的各种算法的内容.除了从备用,据导游书籍和资料,尝试结合链接的图像处理算法和日常生活,第一桌面上(随着摄像头)完成了一系列的视频流处理功能.开发平台Qt5.3.2+ ...

  7. 基于opencv将视频转化为字符串Java版

    基于opencv将视频转化为字符串Java版 opencv java  先上一个效果图吧 首先,弄清一下原理 我们要将视频转化为字符画,那么就需要获取画面的每一帧,也就是每一张图片,然后将图片进行转化 ...

  8. 基于opencv网络摄像头在ubuntu下的视频获取

     基于opencv网络摄像头在ubuntu下的视频获取 1  工具 原料 平台 :UBUNTU12.04 安装库  Opencv-2.3 2  安装编译运行步骤 安装编译opencv-2.3  参 ...

  9. 基于opencv图片切割

    基于opencv图片切割为n个3*3区块 工作原因,切割图片,任务急,暂留调通的源码,留以后用. package com.rosetta.image.test; import org.opencv.c ...

随机推荐

  1. prometeus, grafana部署以及监控mysql

    什么是普罗米修斯? Prometheus是一个最初在SoundCloud上构建的开源系统监视和警报工具包 .自2012年成立以来,许多公司和组织都采用了Prometheus,该项目拥有一个非常活跃的开 ...

  2. ORM 多表操作查询及增删改查

    ------------------------------------------只有对前途乐观的人,才能不怕黑暗,才能有力量去创造光明.乐观不是目的,而是人生旅途中的一种态度. 多表操作 创建模型 ...

  3. Python_每日习题_0004_一年中的第几天

    # 题目 输入某年某月某日,判断这一天是这一年的第几天? # 程序分析 特殊情况,闰年时需考虑二月多加一天: def isLeapYear(y): return (y%400==0 or (y%4== ...

  4. K进制数

    题目描述 考虑包含N位数字的K-进制数. 定义一个数有效, 如果其K-进制表示不包含两连续的0. 考虑包含N位数字的K-进制数. 定义一个数有效, 如果其K-进制表示不包含两连续的0. 例: 1010 ...

  5. D1. Great Vova Wall (Version 1)

    链接 [https://codeforces.com/contest/1092/problem/D1] 题意 给你n个位置墙的高度,现在你有2×1 砖块,你可以竖直或者水平放置 问你是否可以使得所有位 ...

  6. Karen and Game CodeForces - 816C (暴力+构造)

    On the way to school, Karen became fixated on the puzzle game on her phone! The game is played as fo ...

  7. JS_左边栏菜单

    需求: 要求实现左边栏菜单点击一下就弹开,其他的隐藏.再点击一下就隐藏. 最多只能有一个菜单的详细内容会显示出来. 三个菜单实现联动效果. 代码如下: 1 <!DOCTYPE html> ...

  8. 从Mongo导出数据库到Excel

    在MongoDB的安装目录的bin文件夹下打开命令行: ./mongoexport -d kugou_db -c songs -f rank,singer,song,time --type=csv - ...

  9. IdentityServer4【Introduction】之支持的规范

    支持的规范 identityserver实现了下面的规范 OpenID Connect OpenID Connect Core 1.0 (spec) OpenID Connect Discovery ...

  10. 转《vue引入第三方js库》

    一.绝对路径直接引入,全局可用 二.绝对路径直接引入,配置后,import 引入后再使用 三.webpack中配置 alias,import 引入后再使用 四.webpack 中配置 plugins, ...