2
votes

I want to take images from my IP camera. I work in visual studio 2012. At first, I've used openCV to connect to it. Here is my code.

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/opencv.hpp"

int main()
{
cv::VideoCapture vcap;

const std::string videoStreamAddress = "rtsp://admin:[email protected]/snl/live/1/1/stream1.cgi";

if (!vcap.open(videoStreamAddress))
{
    printf("camera is null\n");
    return -1;
}
else
{
    cv::Mat image;
    cv::namedWindow("Video", CV_WINDOW_AUTOSIZE);

    while(1)
    {

        vcap >> image;
        imshow("Video", image);
        if(cv::waitKey(10) == 99 ) break;
     }
 }

 cv::waitKey(1000);
 return 0;
}

It shows the stream. But some of its images have distortion. I think it is because of decoding error. The error is this:

[h264 @ 00decfe0] error while decoding MB 37 22, bytestream <td>

To solve this error I write another code inspired from http://answers.opencv.org/question/65932/how-to-stream-h264-video-with-rtsp-in-opencv-partially-answered/ . It uses libVLC to get the stream. here is my second code.

#include "opencv2/opencv.hpp"
#include "vlc/libvlc.h"
#include "vlc/libvlc_media.h"
#include "vlc/libvlc_media_player.h"

#include "ctime"
#include "Windows.h"
#include "string"

struct ctx
{
   IplImage* image;
   HANDLE mutex;
   uchar*    pixels;
};

void *lock(void *data, void**p_pixels)
{
    struct ctx *ctx = (struct ctx*)data;
    WaitForSingleObject(ctx->mutex, INFINITE);
    *p_pixels = ctx->pixels;   
    return NULL;

}
void display(void *data, void *id){
   (void) data;
   assert(id == NULL);
}
void unlock(void *data, void *id, void *const *p_pixels){
   struct ctx *ctx = (struct ctx*)data;
   /* VLC just rendered the video, but we can also render stuff */
   uchar *pixels = (uchar*)*p_pixels;
   cvShowImage("image", ctx->image);
   ReleaseMutex(ctx->mutex);
   assert(id == NULL); /* picture identifier, not needed here */
}

int main()
{
    // VLC pointers
    libvlc_instance_t *vlcInstance;
    libvlc_media_player_t *mp;
    libvlc_media_t *media;

    const char * const vlc_args[] = {
  "-I", "dummy", // Don't use any interface
  "--ignore-config", // Don't use VLC's config
  "--extraintf=logger", // Log anything
  "--verbose=2", // Be much more verbose then normal for debugging purpose
    };

    vlcInstance = libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);
    media = libvlc_media_new_location(vlcInstance, "rtsp://admin:[email protected]/snl/live/1/1/stream1.cgi");

    mp = libvlc_media_player_new_from_media(media);
    libvlc_media_release(media);
    context->mutex = CreateMutex(NULL, FALSE, NULL);
    context->image = new Mat(VIDEO_HEIGHT, VIDEO_WIDTH, CV_8UC3);
    context->pixels = (unsigned char *)context->image->data;

    // show blank image
    imshow("test", *context->image);

    libvlc_video_set_callbacks(mp, lock, unlock, display, context);
    libvlc_video_set_format(mp, "RV24", VIDEO_WIDTH, VIDEO_HEIGHT, VIDEO_WIDTH * 24 / 8); // pitch = width * BitsPerPixel / 8

    int ii = 0;
    int key = 0;
    while(key != 27)
    {
        ii++;
        if (ii > 5)
        {
            libvlc_media_player_play(mp);
        }
        float fps =  libvlc_media_player_get_fps(mp);
        //printf("fps:%f\r\n",fps);
        key = waitKey(100); // wait 100ms for Esc key
    }

    libvlc_media_player_stop(mp);

    return 0;

}

But it has nearly the same error. Some pixels losts and images has distortion.

[h264 @ 02a3b660] Frame num gap 6 4
[h264 @ 02a42220] no picture oooo

How Can I fix this problem? The problem rooted from my code and the using libraries or my camera?

1
Have you tried to use another stream of your IP camera? I also suggest to tune the stream parameters (resolution, framerate, h264 profiles, etc.), maybe the bandwidth cannot serve the current settings. What do you experience when you open the stream directly in VLC? - Kornel
@Kornel I have tried all possible URL of my camera using its documentation. They have that mentioned error. - zahra rah
@Kornel As you suggest, I've changed the camera parameters, i've reduced resolution and framerate but it didn't get bettter. I've also opened my stream with VLC program. Some of its frames are corrupted. - zahra rah
but does it mean that in VLC it has a better quality? Have you also tried with a different switch/router or cable? - Kornel
@Kornel Thanks for the comments. Yes , VLC has a better quality. Since I just need a single image to process in every 5 Sec (not stream) I removed the stream show. Also, I have tuned camera parameters. now it takes good images, but after about half an hour it freezes. (It shows "not responding" in Task Manager) - zahra rah

1 Answers

1
votes

im working on some project like you,this error is because openCVcant deal with H264 , i suggest you use VLC library as mentioned in here,and cause you use VS2012 you can use VLCDotNetin your project.other options is FFmpeg,aforgethat are compatible with H264.