从java摄像头捕捉图像?
我怎样才能连续捕捉摄像头的图像?
我想实验对象识别(也许使用Java媒体框架)。
我正在考虑创build两个线程
一个线程:
- 节点1:捕捉实时图像
- 节点2:保存图像为“1.jpg”
- 节点3:等待5秒钟
- 节点4:重复…
其他线程:
- 节点1:等待图像被捕获
- 节点2:使用“1.jpg”可以获得每个像素的颜色
- 节点3:将数据保存在数组中
- 节点4:重复…
这个JavaCV实现工作正常。
码:
import org.bytedeco.javacv.*; import static org.bytedeco.javacpp.opencv_core.IplImage; import static org.bytedeco.javacpp.opencv_core.cvFlip; import static org.bytedeco.javacpp.opencv_imgcodecs.cvSaveImage; /** * Created by gtiwari on 1/3/2017. */ public class Test implements Runnable { final int INTERVAL = 100;///you may use interval CanvasFrame canvas = new CanvasFrame("Web Cam"); public Test() { canvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE); } public void run() { FrameGrabber grabber = new VideoInputFrameGrabber(0); // 1 for next camera OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage(); IplImage img; int i = 0; try { grabber.start(); while (true) { Frame frame = grabber.grab(); img = converter.convert(frame); //the grabbed frame will be flipped, re-flip to make it right cvFlip(img, img, 1);// lr = 90_degrees_steps_anti_clockwise //save cvSaveImage((i++) + "-aa.jpg", img); canvas.showImage(converter.convert(img)); Thread.sleep(INTERVAL); } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { Test gs = new Test(); Thread th = new Thread(gs); th.start(); } }
JavaCV的configuration也有
您可以修改代码并能够定期保存图像,并执行其他所需的处理。
前段时间我创build了一个通用的Java库,可以用来用PC摄像头拍照。 这个API非常简单,没有过度使用,可以独立工作,而且还支持OpenIMAJ,JMF,FMJ,LTI-CIVIL等附加networking摄像头驱动以及一些IP摄像头。
链接到该项目是https://github.com/sarxos/webcam-capture
示例代码(拍照并保存在test.jpg中):
Webcam webcam = Webcam.getDefault(); webcam.open(); BufferedImage image = webcam.getImage(); ImageIO.write(image, "JPG", new File("test.jpg"));
它也可以在Maven Central Repository中获得,或者作为一个单独的ZIP包含所有必需的依赖和第三方JAR。
JMyron使用非常简单。 http://webcamxtra.sourceforge.net/
myron = new JMyron(); myron.start(imgw, imgh); myron.update(); int[] img = myron.image();
这是一个类似的问题,有些答案还是未被接受。 其中之一提到FMJ作为JMF的Java替代品。
这种使用JavaCV的gt_ebuddy的答案,但我的video输出是在一个更高的质量,然后他的答案。 我还添加了一些其他的随机改进(如按ESC和CTRL + C时closures程序,并确保closures程序正确使用的资源)。
import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.image.BufferedImage; import javax.swing.AbstractAction; import javax.swing.ActionMap; import javax.swing.InputMap; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.KeyStroke; import com.googlecode.javacv.CanvasFrame; import com.googlecode.javacv.OpenCVFrameGrabber; import com.googlecode.javacv.cpp.opencv_core.IplImage; public class HighRes extends JComponent implements Runnable { private static final long serialVersionUID = 1L; private static CanvasFrame frame = new CanvasFrame("Web Cam"); private static boolean running = false; private static int frameWidth = 800; private static int frameHeight = 600; private static OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0); private static BufferedImage bufImg; public HighRes() { // setup key bindings ActionMap actionMap = frame.getRootPane().getActionMap(); InputMap inputMap = frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); for (Keys direction : Keys.values()) { actionMap.put(direction.getText(), new KeyBinding(direction.getText())); inputMap.put(direction.getKeyStroke(), direction.getText()); } frame.getRootPane().setActionMap(actionMap); frame.getRootPane().setInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW, inputMap); // setup window listener for close action frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { stop(); } }); } public static void main(String... args) { HighRes webcam = new HighRes(); webcam.start(); } @Override public void run() { try { grabber.setImageWidth(frameWidth); grabber.setImageHeight(frameHeight); grabber.start(); while (running) { final IplImage cvimg = grabber.grab(); if (cvimg != null) { // cvFlip(cvimg, cvimg, 1); // mirror // show image on window bufImg = cvimg.getBufferedImage(); frame.showImage(bufImg); } } grabber.stop(); grabber.release(); frame.dispose(); } catch (Exception e) { e.printStackTrace(); } } public void start() { new Thread(this).start(); running = true; } public void stop() { running = false; } private class KeyBinding extends AbstractAction { private static final long serialVersionUID = 1L; public KeyBinding(String text) { super(text); putValue(ACTION_COMMAND_KEY, text); } @Override public void actionPerformed(ActionEvent e) { String action = e.getActionCommand(); if (action.equals(Keys.ESCAPE.toString()) || action.equals(Keys.CTRLC.toString())) stop(); else System.out.println("Key Binding: " + action); } } } enum Keys { ESCAPE("Escape", KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)), CTRLC("Control-C", KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_DOWN_MASK)), UP("Up", KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0)), DOWN("Down", KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0)), LEFT("Left", KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)), RIGHT("Right", KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0)); private String text; private KeyStroke keyStroke; Keys(String text, KeyStroke keyStroke) { this.text = text; this.keyStroke = keyStroke; } public String getText() { return text; } public KeyStroke getKeyStroke() { return keyStroke; } @Override public String toString() { return text; } }
您也可以尝试Java Webcam SDK库。 SDK演示程序可在链接中find 。
我已经在video会议应用上使用了JMF,并且在两台笔记本电脑上运行良好:一台配有集成networking摄像头,另一台配有旧USB摄像头。 它需要事先安装和configurationJMF,但一旦完成,您可以很容易地通过Java代码访问硬件。
你可以尝试Marvin框架 。 它提供了一个界面来处理相机。 此外,它还提供了一组实时的video处理function,如对象跟踪和过滤。
看一看!
实时video处理演示:
http://www.youtube.com/watch?v=D5mBt0kRYvk
您可以使用下面的来源。 只需使用MarvinImageIO.saveImage()每5秒保存一帧。
networking摄像头video演示:
public class SimpleVideoTest extends JFrame implements Runnable{ private MarvinVideoInterface videoAdapter; private MarvinImage image; private MarvinImagePanel videoPanel; public SimpleVideoTest(){ super("Simple Video Test"); videoAdapter = new MarvinJavaCVAdapter(); videoAdapter.connect(0); videoPanel = new MarvinImagePanel(); add(videoPanel); new Thread(this).start(); setSize(800,600); setVisible(true); } @Override public void run() { while(true){ // Request a video frame and set into the VideoPanel image = videoAdapter.getFrame(); videoPanel.setImage(image); } } public static void main(String[] args) { SimpleVideoTest t = new SimpleVideoTest(); t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }
对于那些只想拍一张照片的人来说:
WebcamPicture.java
public class WebcamPicture { public static void main(String[] args) { try{ MarvinVideoInterface videoAdapter = new MarvinJavaCVAdapter(); videoAdapter.connect(0); MarvinImage image = videoAdapter.getFrame(); MarvinImageIO.saveImage(image, "./res/webcam_picture.jpg"); } catch(MarvinVideoInterfaceException e){ e.printStackTrace(); } } }
http://grack.com/downloads/school/enel619.10/report/java_media_framework.html
在Swing中使用播放器
玩家可以很容易地在Swing应用程序中使用。 以下代码创build一个基于Swing的电视捕捉程序,并在整个窗口中显示video输出:
import javax.media.*; import javax.swing.*; import java.awt.*; import java.net.*; import java.awt.event.*; import javax.swing.event.*; public class JMFTest extends JFrame { Player _player; JMFTest() { addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { _player.stop(); _player.deallocate(); _player.close(); System.exit( 0 ); } }); setExtent( 0, 0, 320, 260 ); JPanel panel = (JPanel)getContentPane(); panel.setLayout( new BorderLayout() ); String mediaFile = "vfw://1"; try { MediaLocator mlr = new MediaLocator( mediaFile ); _player = Manager.createRealizedPlayer( mlr ); if (_player.getVisualComponent() != null) panel.add("Center", _player.getVisualComponent()); if (_player.getControlPanelComponent() != null) panel.add("South", _player.getControlPanelComponent()); } catch (Exception e) { System.err.println( "Got exception " + e ); } } public static void main(String[] args) { JMFTest jmfTest = new JMFTest(); jmfTest.show(); } }
Java通常不喜欢访问硬件,所以你将需要某种驱动程序,正如goldenmean所说。 我已经在我的笔记本上find了一个命令行程序来捕捉图片。 然后就像goldenmean解释的那样; 你在takepicture()例程中运行你的java程序中的命令行程序,其余代码运行相同。
除了将像素值读入数组的部分之外,通过将文件保存到几乎已经是该格式的BMP,然后使用其上的标准Java图像库,可能会更好。
使用命令行程序会增加对程序的依赖性,使其不易携带,但networking摄像头也是如此,对不对?
我相信随着networking摄像头,或你本地的Windows摄像头软件的networking摄像头应用软件可以在打开networking摄像头后运行在一个批处理脚本(Windows / DOS脚本)(即如果它需要一个外部电源供应)。 在bacth脚本中,你可以在一段时间后添加适当的延迟来捕获。 并继续在循环中执行捕获命令。
我想这应该是可能的
-广告
在处理中有一个非常漂亮的界面,这是一个为graphicsdevise的pidgin java。 它被用于一些图像识别工作,如链接。
取决于你需要什么,你可能能够加载在那里使用的video库,或者如果你只是玩弄它,你可能能够通过使用处理本身。
FMJ可以做到这一点,它也可以使用LTI-CIVIL。 两者都在sourceforge上。
使用FMJ推荐多媒体相关的Java应用程序。
尝试使用JMyron 如何使用networking摄像头使用Java 。 我认为使用JMyron是使用Java访问摄像头的最简单的方法。 我试图用一个64位的处理器,但它给了我一个错误。 不过,它在32位处理器上工作得很好。
我使用networking摄像头捕捉API …你可以从这个http://webcam-capture.sarxos.pl/下载;
webcam = Webcam.getDefault(); webcam.open(); if (webcam.isOpen()) { //if web cam open BufferedImage image = webcam.getImage(); JLabel imageLbl = new JLabel(); imageLbl.setSize(640, 480); //show captured image imageLbl.setIcon(new ImageIcon(image)); int showConfirmDialog = JOptionPane.showConfirmDialog(null, imageLbl, "Image Viewer", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, new ImageIcon("")); if (showConfirmDialog == JOptionPane.YES_OPTION) { JFileChooser chooser = new JFileChooser(); chooser.setDialogTitle("Save Image"); chooser.setFileFilter(new FileNameExtensionFilter("IMAGES ONLY", "png", "jpeg", "jpg")); //this file extentions are shown int showSaveDialog = chooser.showSaveDialog(this); if (showSaveDialog == 0) { //if pressed 'Save' button String filePath = chooser.getCurrentDirectory().toString().replace("\\", "/"); String fileName = chooser.getSelectedFile().getName(); //get user entered file name to save ImageIO.write(image, "PNG", new File(filePath + "/" + fileName + ".png")); } } }