Opencv reading IP camera, Video stream, Web camera, images and

Opencv reading video files, video stream, Images, IP, and Web cameras. I would like to cover this all in one post. Yes, video writing is also important to store your results and achievements in video. There is a couple of simple tricks and if you follow them, you will never have a problem with reading and writing video, streaming, files in the future.
opencv web camera

Basic OpenCV web camera reading

There is a couple of things you need to take care. My favorite installation on the Windows platform is through the NUGET package system. It is easy in a few steps. I describe this many times for example VS 2017 here. Nuget set up your project without any linking settings, library path selection, or global environmental variables and you can directly start coding in a few seconds. Just select and install Nuget and compile the code below. Nothing else.  You need to take care if you have included several things. highgui.hpp core.hpp, imgproc.hpp, videoio, imgcodecs. All of them are not necessary to read the web camera but for example for video streaming from IP camera is possible that you really need them all.

VideoCapture web camera code

VideoCapture cap(0); is means opening the default camera web camera. Most of the time this means a web camera on your laptop or plugged in any USB camera. The video is read in 'never-ending for(;;) loop' which is break when the video from the camera is not available by condition if (!cap.isOpened()). Finally the Mat img; cap >> img; copy image from default camera devices into your MAT container. The rest is just display.
#include "opencv2\imgproc.hpp"
#include "opencv2\objdetect\objdetect.hpp"
#include "opencv2\videoio\videoio.hpp"
#include "opencv2\imgcodecs\imgcodecs.hpp"

#include "opencv2\core\core.hpp"
#include "opencv2\highgui.hpp"
#include <vector>
#include <stdio.h>
#include <windows.h>
#include <iostream>
#include <time.h>
using namespace cv;
using namespace std;
int main(int argcconst char** argv)
{
 VideoCapture cap(0);
 for (;;)
 {
  if (!cap.isOpened()) {
   cout << "Video Capture Fail" << endl;
   break;
  }
  else {
   Mat img;
   cap >> img;
   namedWindow("Video", WINDOW_AUTOSIZE);
   imshow("Video", img);

   int key2 = waitKey(20);
  }
 }
 return 0;

Opencv video file reading

Look at the example above for reading the camera. There is almost no difference. Just one, small and straightforward. As a parameter of cap put instead of default devices cap(0) the file name or path you want to open. There is almost always trouble with the path.  In this example, you just read the files that are located under your project. You can also read the file from a different location or in one place by using the full path into some video folder as you can see in the following examples. 

VideoCapture cap("movie.vmw");

VideoCapture cap("movie.mp4");
VideoCapture cap("movie.mov");
VideoCapture cap("movie.xxx");
VideoCapture cap("C:/cm/movie.mov");
VideoCapture cap("C:/cm/movie.mp4");

Opencv Image read from file and writing 

This is a super easy task. Into our Mat container image load the image 6.jpg on this C:/adress/ path. There is something different that is great to have in case you are reading lots of images inside the folder. 

Mat image;
image = imread("C:/adress/6.jpg", CV_LOAD_IMAGE_COLOR);

CV_LOAD_IMAGE_COLOR is a defined parameter to tell the reader that I want MAT with 3 colors. Basically 3 MAT array containers of image size. One for blue, red, and green color channels. CV_LOAD_IMAGE_GRAYSCALE is defined to the tell reader that I want grayscale. Basically only one Mat of the weight(cols) and height (rows) of the image.
To write results into a file just use imwrite where the first string is just the name of your result and image. The image is MAT containing what you want to save.

imwrite("image.jpg", image);

Opencv video stream verification

I am using good practice. instead of trying to stream directly in OpenCV. I prefer to verify my stream in the VLC player. It is faster than modifying code and compiling again bypassing the camera URL as a parameter. Also, the VLC asks for a potential username and password if it's necessary. What is annoying is that all the cameras own stream URL format.  The best approach is to find your IP camera model on http://www.ispyconnect.com and apply it to verify inside the VLC. After verification put this directly to VideoCapture cap("http://IP:PORT/mjpeg/video.mjpg?counter"); 

http://IP:PORT/mjpeg/video.mjpg?counter
rtsp://IP:PORT/various url
rtsp://IP:PORT/axis-cgi/mjpg/video.cgi
http://IP:PORT/mjpg/video.mjpg
Remember that VLC ask for the password Opencv NOT. Just add rtsp://username:password@IP:PORT
("rtsp://USER:PASS@xxx.xxx.xxx.xxx/axis-media/media.amp?camera=2")
Important FFMPEG is needed in Linux. In case of Nuget packages depends but the stream sometimes needs special installation. 

Opencv tutorial code IP camera pseudo code

There is 3 function.
First of all, the main function at the end, where is established 2 threads to read the camera stream..

In Main
  • The thread calls the stream function for both cameras with different IP camera URL                       thread cam1(stream, "http://xxxxxxxR");
  • To run the function stream inside the thread with URL as parameter use.                       cam1.join();
void stream
  • Capture video from url strCamera VideoCapture cap(strCamera) 
  • Fill the frame from cap  cap >> frame;
  • Detect people in camera detect(frame, strCamera);
void detect

Opencv C++ IP camera code, video stream

#include <iostream>
#include <thread>
#include "opencv2/opencv.hpp"
#include <vector>
using namespace std;
using namespace cv;
void detect(Mat imgString strCamera) {
  string cascadeName1 = "haar_cascade_for_people_detection.xml";
  CascadeClassifier detectorBody;
  bool loaded1 = detectorBody.load(cascadeName1);
  Mat original;
  img.copyTo(original);
  vector human;
  cvtColor(img, img, CV_BGR2GRAY);
  equalizeHist(img, img);
  detectorBody.detectMultiScale(img, human, 1.120 | 1Size(4080), Size(400,480 ));
  if (human.size() > 0
    {
      for (int gg = 0; gg < human.size(); gg++) 
      {
      rectangle(original, human[gg].tl(), human[gg].br(), Scalar(00255), 280);
      }
    }
  imshow("Detect " + strCamera, original);
  int key6 = waitKey(40);
//End of the detect
}
void stream(String strCamera) {
VideoCapture cap(strCamera);
 if (cap.isOpened()) { 
      while (true) {
        Mat frame;
        cap >> frame; 
        resize(frame, frame, Size(640480));
        detect(frame, strCamera);
     }
   }
}
int main() {
    thread cam1(stream, "http://xxxxxxxR");
    thread cam2(stream, "http://xxxxxxxR");
    cam1.join();
    cam2.join();
    return 0;
}

Write the video into a file

On Windows machine, I usually work with a simple wmv format. Works perfectly. Remember the golden rule of video writer in OpenCV. image Mat has to match the same size as VideoWriter. The image is a mat that I want to write as a frame into the video. Before I put them into the VideoWriter, I always resize them to the target size. This causes lots of trouble. You cannot see the video result only for that reason.  
Size SizeOfVideo = cv::Size(1024740);  VideoWriter video("Result.wmv"
CV_FOURCC('W''M''V''2'), CAP_PROP_FPS,SizeOfVideotrue);
resize(image, image, Size(800600)); 
 video << image; 
OR
 video.write(image);
Next Post Previous Post
8 Comments
  • Unknown
    Unknown August 17, 2017 at 12:15 AM

    I am using Raspberry pi cam as IP camera and it shows "std::invoke no matching overloaded function found" error.

  • Unknown
    Unknown November 15, 2017 at 9:48 PM

    This comment has been removed by a blog administrator.

  • jhon
    jhon December 7, 2017 at 6:14 AM

    Now you have a video stream available and you need to capture still images from it. For that, use getsnapshot() command. Hikvision 8MP Cameras

  • Ener-jblog
    Ener-jblog September 3, 2018 at 10:40 PM

    Fantastic and useful we blog thanks for publishing this.it's useful and informative.keep up the great.
    ENER-J CCTV Security Camera

  • Unknown
    Unknown October 24, 2018 at 12:28 AM

    PeopleLink iCam WHD 720 USB cameras are designed for boardrooms.The sleek and compact design of these cameras help in easy portability and storage.They offer easy connectivity with laptops/PC through USB ports and deliver HD quality video and the Pan and Tilt feature allows a wider angle coverage capturing a larger audience

  • zicom
    zicom December 14, 2018 at 3:00 AM

    Thanks for sharing this kind of useful information zicom offers best advance home security.
    For More Information. click here

  • Anonymous
    Anonymous December 23, 2018 at 11:02 PM

    Nice blog. Easy to understable,thanks for sharing

    PeopleLink Fisheye camera are designed for conference rooms. They offer easy connectivity with laptops/PC through USB ports and deliver HD quality video.

  • Laghari Bedi
    Laghari Bedi June 5, 2020 at 9:33 AM

    Fantastic Post! Lot of information is helpful in some or the other way. Keep updating.mini home security IP camera

Add Comment
comment url