Java使用OpenCV3.2實(shí)現(xiàn)視頻讀取與播放
Java使用OpenCV3.2實(shí)現(xiàn)視頻讀取與播放,供大家參考,具體內(nèi)容如下
OpenCV從3.x版本開(kāi)始其JAVA語(yǔ)言的SDK支持視頻文件讀寫,這樣就極大的方便了廣大Java語(yǔ)言開(kāi)發(fā)者學(xué)習(xí)與使用OpenCV,通過(guò)攝像頭或者視頻文件讀取幀的內(nèi)容與播放,完成視頻內(nèi)容分析與對(duì)象跟蹤等各種應(yīng)用開(kāi)發(fā)任務(wù)??梢哉f(shuō)OpenCV C++ SDK可以做到絕大多數(shù)事情,在OpenCV3.x版本上用Java都可以完成,這樣就為很多Java開(kāi)發(fā)者學(xué)習(xí)OpenCV打開(kāi)了方便之門。
實(shí)現(xiàn)思路
首先用OpenCV相關(guān)API讀取視頻流或者視頻文件的每一幀,然后通過(guò)Swing JComponent組件實(shí)現(xiàn)視頻每一幀的更新顯示,我模仿了C++的HIGHGUI里面創(chuàng)建窗口與顯示圖像接口,基于Swing實(shí)現(xiàn)了一個(gè)視頻播放窗口類,把讀取到的每一幀都傳給它就可以實(shí)現(xiàn)連續(xù)顯示即播放。每幀之間相隔100毫秒,我是通過(guò)Java線程Sleep方法實(shí)現(xiàn)。
運(yùn)行效果 - USB攝像頭讀取每幀

運(yùn)行效果 - 視頻文件讀取每幀

代碼實(shí)現(xiàn)
視頻文件讀取
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);
// 打開(kāi)攝像頭或者視頻文件
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();
}
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Python?OpenCV超詳細(xì)講解讀取圖像視頻和網(wǎng)絡(luò)攝像頭
- pyqt5+opencv?實(shí)現(xiàn)讀取視頻數(shù)據(jù)的方法
- Python OpenCV讀取視頻報(bào)錯(cuò)的問(wèn)題解決
- Python OpenCV讀取顯示視頻的方法示例
- opencv3/C++實(shí)現(xiàn)視頻讀取、視頻寫入
- 使用python-opencv讀取視頻,計(jì)算視頻總幀數(shù)及FPS的實(shí)現(xiàn)
- VS2010+Opencv+MFC讀取圖像和視頻顯示在Picture控件
- 如何使用OpenCV進(jìn)行視頻讀取與處理的完整指南
相關(guān)文章
關(guān)于Java如何正確地實(shí)現(xiàn)方法重載詳解
在一個(gè)類中,可以定義多個(gè)構(gòu)造方法,這叫做方法的重載!但是關(guān)于方法重載,具有有哪些要求和細(xì)節(jié)?在今天的這篇文章中,小編給大家詳細(xì)說(shuō)說(shuō)方法重載相關(guān)的內(nèi)容,需要的朋友可以參考下2023-05-05
java如何使用自己的maven本地倉(cāng)庫(kù)詳解
這篇文章主要給大家介紹了關(guān)于java如何使用自己的maven本地倉(cāng)庫(kù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07
使用feign服務(wù)調(diào)用添加Header參數(shù)
這篇文章主要介紹了使用feign服務(wù)調(diào)用添加Header參數(shù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
druid配置數(shù)據(jù)庫(kù)連接使用密文密碼方式
這篇文章主要介紹了druid配置數(shù)據(jù)庫(kù)連接使用密文密碼方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,2023-12-12
win10下定時(shí)運(yùn)行與開(kāi)機(jī)自啟動(dòng)jar包的方法記錄
這篇文章主要給大家介紹了關(guān)于win10下定時(shí)運(yùn)行與開(kāi)機(jī)自啟動(dòng)jar包的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
搭建一個(gè)基礎(chǔ)的Resty項(xiàng)目框架
這篇文章主要為大家介紹了如何搭建一個(gè)基礎(chǔ)的Resty項(xiàng)目框架示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03
springboot如何使用thymeleaf完成頁(yè)面緩存
這篇文章主要介紹了springboot如何使用thymeleaf完成頁(yè)面緩存,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06

