使用Java中的OpenCv实现IP摄像头

9
我正在尝试获取并显示来自IP摄像机的视频流。我在这里找到了一些示例代码:http://answers.opencv.org/question/24012/reading-video-stream-from-ip-camera-in-opencv-java/ 但它对我没用。当我使用内置网络摄像头时,我的代码可以工作,但是当我切换到IP摄像头时,它就无法工作。我不知道为什么。有人能帮帮我吗? 以下是我的代码:
    import java.awt.BorderLayout;
    import java.awt.Image;
    import java.awt.image.BufferedImage;
    import java.awt.image.DataBufferByte;
    import java.io.File;
    import java.io.IOException;

    import javax.imageio.ImageIO;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;

    import org.opencv.core.Core;
    import org.opencv.core.CvType;
    import org.opencv.core.Mat;
    import org.opencv.highgui.VideoCapture;
    import org.opencv.imgproc.Imgproc;

    public class openCVTest
    {

    public openCVTest()
    {

        // TODO Auto-generated constructor stub
    }

    /**
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException
    {

        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        //VideoCapture camera = new VideoCapture("http://192.168.0.7/image.jpg");
        VideoCapture camera = new VideoCapture(0);

        if (camera.isOpened()) 
        {
            System.out.println("Video is captured");
        }
        else
        {
            System.out.println("");
        }
        videoCamera cam = new videoCamera(camera);

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
        frame.add(cam);
        frame.setSize(800,800);  
        frame.setVisible(true);


        while(camera.isOpened())
        {
            cam.repaint();


        }

    }



      }


import java.awt.Graphics;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.highgui.VideoCapture;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.core.*;



@SuppressWarnings("serial")
public class videoCamera extends JPanel
{
    VideoCapture camera; 

    public videoCamera(VideoCapture cam) 
    {

        camera  = cam; 

    }

    /**
     * @param args
     */
    public static void main(String[] args)
    {

        // TODO Auto-generated method stub

    }
    public BufferedImage Mat2BufferedImage(Mat m)
    {

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


    }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Mat mat = new Mat();

        if( camera.read(mat))
        {
            System.out.print("IMAGE");


        }

        BufferedImage image = Mat2BufferedImage(mat);
        //Mat gray = turnGray(mat);
        //MatOfRect objects = new MatOfRect();
        //CascadeClassifier cas = new CascadeClassifier();
        //cas.detectMultiScale(gray,objects);
        //Mat thresh  = threash( gray);

        //BufferedImage image = Mat2BufferedImage(thresh);
        g.drawImage(image,10,10,image.getWidth(),image.getHeight(), null);

    }
    public Mat turnGray( Mat img)

    {
        Mat mat1 = new Mat();
        Imgproc.cvtColor(img, mat1, Imgproc.COLOR_RGB2GRAY);
        return mat1;
    }
    public Mat threash(Mat img)
    {
        Mat threshed = new Mat();
        int SENSITIVITY_VALUE = 100;
        Imgproc.threshold(img, threshed, SENSITIVITY_VALUE,255,Imgproc.THRESH_BINARY);
        return threshed;
    }


}

感谢您的帮助。我能够使用您所说的内容找到正确的IP地址 (http://192.168.0.6/VIDEO.CGI)(是的,我知道7变成了6,这是另一个摄像头),在浏览器中获取视频。但我仍然遇到以下错误。
 Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Width (0) and height (0) must be > 0
        at java.awt.image.SampleModel.<init>(Unknown Source)
        at java.awt.image.ComponentSampleModel.<init>(Unknown Source)
        at java.awt.image.PixelInterleavedSampleModel.<init>(Unknown Source)
        at java.awt.image.Raster.createInterleavedRaster(Unknown Source)
        at java.awt.image.Raster.createInterleavedRaster(Unknown Source)
        at java.awt.image.Raster.createInterleavedRaster(Unknown Source)
        at java.awt.image.ComponentColorModel.createCompatibleWritableRaster(Unknown Source)
        at java.awt.image.BufferedImage.<init>(Unknown Source)
        at videoCamera.Mat2BufferedImage(videoCamera.java:54)
        at videoCamera.paintComponent(videoCamera.java:74)
        at javax.swing.JComponent.paint(Unknown Source)
        at javax.swing.JComponent.paintChildren(Unknown Source)
        at javax.swing.JComponent.paint(Unknown Source)
        at javax.swing.JComponent.paintChildren(Unknown Source)
        at javax.swing.JComponent.paint(Unknown Source)
        at javax.swing.JLayeredPane.paint(Unknown Source)
        at javax.swing.JComponent.paintChildren(Unknown Source)
        at javax.swing.JComponent.paintToOffscreen(Unknown Source)
        at javax.swing.BufferStrategyPaintManager.paint(Unknown Source)
        at javax.swing.RepaintManager.paint(Unknown Source)
        at javax.swing.JComponent.paint(Unknown Source)
        at java.awt.GraphicsCallback$PaintCallback.run(Unknown Source)
        at sun.awt.SunGraphicsCallback.runOneComponent(Unknown Source)
        at sun.awt.SunGraphicsCallback.runComponents(Unknown Source)
        at java.awt.Container.paint(Unknown Source)
        at java.awt.Window.paint(Unknown Source)
        at javax.swing.RepaintManager$3.run(Unknown Source)
        at javax.swing.RepaintManager$3.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
        at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
        at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
        at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
        at javax.swing.RepaintManager.access$1100(Unknown Source)
        at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
        at java.awt.event.InvocationEvent.dispatch(Unknown Source)
        at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
        at java.awt.EventQueue.access$200(Unknown Source)
        at java.awt.EventQueue$3.run(Unknown Source)
        at java.awt.EventQueue$3.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
        at java.awt.EventQueue.dispatchEvent(Unknown Source)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.run(Unknown Source)

我认为这是因为VideoCapture没有正确地抓取帧。
这是我正在尝试使用的相机 http://www.trendnet.com/products/proddetail.asp?prod=150_TV-IP100W-N
2个回答

13

.jpg指的是单个图像文件,而.mjpg提供了访问视频流的方式。重要的是要定义用于连接的IP和PORT。

根据您拥有的设备以及摄像机Web接口中定义的设置,URL将有所不同:

VideoCapture camera = new VideoCapture("http://192.168.0.7:8080/?dummy=param.mjpg");

VideoCapture camera = new VideoCapture("http://192.168.0.7:8080/mjpeg.cgi");

VideoCapture camera = new VideoCapture("http://192.168.0.7:8080/mjpg/mjpeg.cgi");

VideoCapture camera = new VideoCapture("http://192.168.0.7:8080/video.mjpeg");

VideoCapture camera = new VideoCapture("http://192.168.0.7:8080/video.cgi?.mjpg");
当您通过浏览器访问有效的URL时,它应该显示视频流。一旦找到可用的地址,只需将其传递给VideoCapture构造函数即可。在这些示例中,我展示了如何通过HTTP访问流,但RTSP协议也受支持。

4
在经过3到4周的努力后,我找到了一个100%工作的解决方案。
首先,您必须动态加载ffmpeg的dll文件,即使用 System.loadLibrary("[YOUR DLL FILE的名称]") 您可以在**opencv/build/x64/vc11/bin**中找到所需的dll文件。在我的情况下,DLL的名称是"opencv_ffmpeg2413_64.dll"。将该文件复制到项目的默认路径并使用即可。
System.loadLibrary("opencv_ffmpeg2413_64");//You May have different File Name Depending on the Version of OpenCV Installed on your Computer

那么您可以简单地使用。
VideoCapture ipcamera = new VideoCapture("[RTSP URL OF THE IP Camera]")//I used this Demo Link (rtsp://184.72.239.149/vod/mp4:BigBuckBunny_175k.mov)

我该如何在Mac上完成这个任务?DLL文件与OS X系统不兼容。 - mccoyLBI
如果你想在Mac上运行它,那么你可以尝试采用一种冗长的方式来完成同样的事情。首先,使用VLC流式传输IP摄像头并将输出导入文件,然后在不同的线程上读取相同的文件,这些线程是并行运行的。 - Anas khan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接