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

图片的展示

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

代码如下:

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

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

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

import org.opencv.core.Mat;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte; /**
* @Author: nya
* @Description: 图片展示类
* @Date: Created in 10:55 2018/9/21
* @Modify by:
*/
public class ImageViewer {
private JLabel imageView; public void show(Mat image,String windowName) {
setSystemLookAndFeel();
JFrame frame = createJFrame(windowName);
Image loadedImage = toBufferedImage(image);
imageView.setIcon(new ImageIcon(loadedImage)); frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} private JFrame createJFrame(String windowName) {
JFrame frame = new JFrame(windowName);
imageView = new JLabel();
final JScrollPane imageScrollPane = new JScrollPane(imageView);
imageScrollPane.setPreferredSize(new Dimension(640,480));
frame.add(imageScrollPane,BorderLayout.CENTER);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
return frame;
} private void setSystemLookAndFeel() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
} public Image toBufferedImage(Mat matrix) {
int type = BufferedImage.TYPE_BYTE_GRAY;
if (matrix.channels() > 1) {
type = BufferedImage.TYPE_3BYTE_BGR;
}
int bufferSize = matrix.channels() * matrix.cols() * matrix.rows();
byte[] buffer = new byte[bufferSize];
matrix.get(0,0,buffer); // get all the pixels
BufferedImage image = new BufferedImage(matrix.cols(),matrix.rows(),type);
final byte[] targetPixels = ((DataBufferByte)image.getRaster().getDataBuffer()).getData();
System.arraycopy(buffer,0,targetPixels,0,buffer.length);
return image;
}
}

image Mat operate code:

        String path = "src/main/java/com/opencv/simpleopencvsample/sample/1.jpg";
Mat openFile = null;
try {
       // openFile just is path to mat
openFile = openFile(path);
Mat clone = openFile.clone();
System.out.println(openFile);
Imgproc.resize(openFile,clone,new Size(640,480));
System.out.println(clone);
ImageViewer imageViewer = new ImageViewer();
imageViewer.show(clone,"Loaded image"); } catch (Exception e) {
e.printStackTrace();
} finally {
// comment : never forget to release the matrix
if (openFile != null ) {
openFile.release();
}
}
System.out.println(openFile);

视频的展示

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

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

VideoCapture -> Mat -> display code:

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.videoio.VideoCapture;
import org.opencv.videoio.Videoio; import javax.swing.*;
import java.awt.*; /**
* @Author: nya
* @Description: 视频捕获相关操作类VideoCapture使用
* @Date: Created in 13:50 2018/9/21
* @Modify by:
*/
public class VideoCaptureSample {
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
private JFrame frame;
private JLabel imageLabel; public static void main(String[] args) {
VideoCaptureSample sample = new VideoCaptureSample();
sample.initGUI();
sample.runMainLoop(args);
} private void initGUI(){
frame = new JFrame("Camera Input Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(555,970);
imageLabel = new JLabel();
frame.add(imageLabel);
frame.setVisible(true);
} private void runMainLoop(String[] args) {
ImageViewer viewer = new ImageViewer();
Mat webcamMatImage = new Mat();
Image tempImage;
VideoCapture capture = new VideoCapture("src/main/java/com/opencv/simpleopencvsample/sample/1.mp4");
capture.set(Videoio.CAP_PROP_FRAME_WIDTH,550);
capture.set(Videoio.CAP_PROP_FRAME_HEIGHT,960);
if (capture.isOpened()) {
while (true) {
capture.read(webcamMatImage);
if (!webcamMatImage.empty()) {
tempImage = viewer.toBufferedImage(webcamMatImage);
ImageIcon imageIcon = new ImageIcon(tempImage,"Captured video");
imageLabel.setIcon(imageIcon);
frame.pack();
} else {
System.out.println(" --- Frame not captured -- Break !");
break;
}
}
} else {
System.out.println("Couldn't open capture.");
}
}
}

常见异常 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. APM实践目录

    长路漫漫,如果不能作出一款可用开源的东西出来,那是对时光的浪费.   这是我的学习分布式调用链的实践之路! 思考大纲: .Net架构篇:思考如何设计一款实用的分布式监控系统? 理论篇: http:// ...

  2. c++继承实例

    #include <iostream> #include <vector> #include <string> using namespace std; class ...

  3. Linux—vim常用命令

    vim常用命令: 1. 键入i进入编辑模式2. esc进入命令模式3. a,进入编辑模式3. b,光标移动到单词前,end,光标移动到行尾4. home光标移动到行首5. cc,删除当前行,并进入编辑 ...

  4. codeforces#766 D. Mahmoud and a Dictionary (并查集)

    题意:给出n个单词,m条关系,q个询问,每个对应关系有,a和b是同义词,a和b是反义词,如果对应关系无法成立就输出no,并且忽视这个关系,如果可以成立则加入这个约束,并且输出yes.每次询问两个单词的 ...

  5. CNZZ友盟访问明细的采集办法

    www.cnzz.com是中文网站统计分析平台,很多站长需要获取网站提供的访问明细,以做分析. 直接采集这个网站的数据相当麻烦,通过浏览器或者fiddlercore就简单多了. 2.0新版,通过浏览器 ...

  6. Spring Boot 中使用 @Transactional 注解配置事务管理

    事务管理是应用系统开发中必不可少的一部分.Spring 为事务管理提供了丰富的功能支持.Spring 事务管理分为编程式和声明式的两种方式.编程式事务指的是通过编码方式实现事务:声明式事务基于 AOP ...

  7. 初次使用git上传代码到github远程仓库

    https://blog.csdn.net/loner_fang/article/details/80488385 2018年05月28日 21:02:31 蒲公英上的尘埃 阅读数:697 因为最近在 ...

  8. iOS开发之线程组解决请求多个接口数据,完成后,再刷新界面

    1.多任务请求接口,完成后,在刷新数据,常用方法 2018年07月18日 16:34:38 hbblzjy 阅读数:1382 版权声明:本文为博主原创文章,未经博主允许不得转载. https://bl ...

  9. ansible jenkins war

    Ansible is Simple IT Automationhttps://www.ansible.com/ Ansible中文权威指南- 国内最专业的Ansible中文官方学习手册http://a ...

  10. 关于JS动画和CSS3动画的性能差异

    本文章为综合其它资料所得. 根据Google Developer,Chromium项目里,渲染线程分为main thread和compositor thread. 如果CSS动画只是改变transfo ...