IP camera with OpenCv in Java

2020-02-12 05:38发布

问题:

I am trying to get and display an video stream from a IP camera. I found some sample code here:http://answers.opencv.org/question/24012/reading-video-stream-from-ip-camera-in-opencv-java/

But it is not working for me. my code works when I use my internal webcam, but when I switch the camera to the IP, it does not work. I have no idea why. Can someone please help me? Here is my code:

    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;
    }


}

Thank you for the help. I was able to use what you said to find the proper IP address (http://192.168.0.6/VIDEO.CGI) (yes, I know the 7 became a 6, its a different camera) to get a video in my browser. but I am still get the following error.

 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)

I think it is because VideoCapture is not grabbing the frame correctly.

This is the camera I am trying to use http://www.trendnet.com/products/proddetail.asp?prod=150_TV-IP100W-N

回答1:

.jpg refers to a single image file, while .mjpg gives access to the video stream. It's important to define the IP and the PORT used to connect.

Depending on the device you have and the settings defined in the web interface of the camera, the URL is going to be different:

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");

When you access a valid URL via browser it should display the video stream. Once you find the address that works, simply pass it to VideoCapture constructor. In this examples I showed how to access the stream via HTTP, but the RTSP protocol is also supported.



回答2:

After 3 to 4 weeks of hardwork,I found a 100% working solution for this

First of All you have to load the ffmpeg's dll file Dynamically i-e Using

System.loadLibrary("[NAME OF YOUR DLL FILE]") You can find the required dll file in **opencv/build/x64/vc11/bin** The name of DLL in my case is "opencv_ffmpeg2413_64.dll" copy the file to default path of the Project and use

System.loadLibrary("opencv_ffmpeg2413_64");//You May have different File Name Depending on the Version of OpenCV Installed on your Computer

Then You can Simply use

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)