OpenCV More with cameras.

Nov 3, 2008 by     81 Comments    Posted under: OpenCV, Tutorials

In last tutorial we learn how to get frames of our camera, now we go to learn some basic OpenCV functions to work with our captured frames or video. There is nothing special, but it’s the first steps to introduce to work with OpenCV

Imagine we want create a basic OpenCV program that get a video o camera capture and process the images to get a binary image difference between actual frame and last frame.

Then we have a actual image, lastImage, diffImage where we store the difference images, and the bitImage result that are IplImage instance.

IplImage* image;
IplImage* lastImage;
IplImage* diffImage;
IplImage* bitImage;

Whe need create these variables and initialize with cvCreateImage, this function create and allocate in memory the structure and headers of our image, this function need as attribute image size, depth and number of channels. We get frame as reference to initialize the variables.

image=cvCreateImage(cvSize(frame->width,frame->height),frame->depth,1);

The frame whe get sure is a RGB image, but we go to working with gray level images the we need conver captured frame to Gray Level. The cvCvtColor conver color spaces of image to another and is defined:

void cvCvtColor( const CvArr* src, CvArr* dst, int code );

src is the source 8-bit (8u), 16-bit (16u) or single-precision floating-point (32f) image. dst is the destination image of the same data type as the source one. The number of channels may be different. And code is color conversion operation that can be specified using CV_<src_color_space>2<dst_color_space> constants

cvCvtColor(frame, image, CV_BGR2GRAY);

We can get a new copy in memory of image withcvCloneImage

lastImage=cvCloneImage(image);

To get the image differences we use cvAbsDiff function, to get absolute diference between images:

cvAbsDiff(image,lastImage,diffImage);

The function definition

void cvAbsDiff( const CvArr* src1, const CvArr* src2, CvArr* dst );

Where src1 is the first source array. src2 is the second source array, and dst is the destination array.

Then to finish we only need get a threshold of image, and we do it with cvThreshold function

cvThreshold(diffImage,bitImage,tr,255,CV_THRESH_BINARY);

And this function have this definition:

double cvThreshold( const CvArr* src, CvArr* dst, double threshold,
double max_value, int threshold_type );

Where src is source array (single-channel, 8-bit of 32-bit floating point), dst is destination array; must be either the same type as src or 8-bit, threshold is the threshold value, max_value is the maximum value to use with CV_THRESH_BINARY and CV_THRESH_BINARY_INV thresholding types, and threshold_type is thresholding type

This is the main loop program:

for(;;){
IplImage* frame = 0;
int c;

frame = cvQueryFrame( capture );
if( !frame )
break;
//If is the first frame
if(!image){
//Create image header same as frame but with 1 channel to gray
image=cvCreateImage(cvSize(frame->width,frame->height),frame->depth,1);
bitImage=cvCreateImage(cvSize(frame->width,frame->height),frame->depth,1);
}
//Convert frame to gray and store in image
cvCvtColor(frame, image,CV_BGR2GRAY);

//If is the first frame
if(!lastImage){

//If no lastImage clone actual image;
lastImage=cvCloneImage(image);
}
if(!diffImage){
//Create image header same as frame but with 1 channel to gray
diffImage=cvCreateImage(cvSize(frame->width,frame->height),frame->depth,1);
}

cvShowImage( “CamSub”, frame );
//Differences with actual and last image
cvAbsDiff(image,lastImage,diffImage);
//threshold image
cvThreshold(diffImage,bitImage,tr,255,CV_THRESH_BINARY);
//Change datas;
lastImage=cvCloneImage(image);

cvShowImage(“CamSub 1″,bitImage);

c = cvWaitKey(10);
if( (char) c == 27 )
break;
}

Demo Source

81 Comments + Add Comment

  • Thanks,withot using from command line,if suppose in the middle of a program i need to ask the user the name of image and get it substituted like the one program snippet which is not working.

    please tell me where i’m going wrong.

    IplImage *myimage;

    // load an image
    char imagename[20];
    cout<>imagename;

    myimage = cvLoadImage(“imagename”,1);

  • Thanks for the reply damiles.

    In the middle of program execution ,i need to ask the user to enter the image name and the display the image.please suggest the code snippet like that shown below which is not getting executed.

    IplImage *myimage;

    load an image
    string imagename;
    cout<<"enter the name of the image";
    getline(cin,imagename);

    myimage = cvLoadImage("imagename",1);

  • Excellent Man!
    I Appreciate.

  • Hai Damiles,

    I’m new in openCV, i’ve tried to capture from camera in windows and linux using logitech webcam.

    But now, i am trying to capture video from CCD camera (firewire input), what i get is only grayscale video.

    I’v e searched and some said it because CCD Camera with firewire input only be supported with OpenCV in 8bit. Other one said it needs directshow sdk, then what should i do?

    I’ve tried to convert each frame using cvCvtColor(frame, frameColor, CV_GRAY2BGR), but i couldn’t works. Do you have any idea why??

    Thanks Before.

  • You are sure you get a frame with this camera? If you are under linux, you have to ensure the camera is working ok, check with xawtv for example. Then if xawtv works correctly then check you get a frame in opencv.

  • Thanks for your quick reply,

    how to check whether i get frame or not??
    That i sure is i can display the video and i can manipulate the video that i get from the camera, but the problem is i only get grayscale video. If i use my webcam i get perfect video with color video.

    i just searched and i get UYVY something which i don’t understand.

  • have you tried to use directshow sdk along with opencv?

    i just wonder if i can capture the video using directshow and then manipulate the video using opencv..

    is it possible?

  • Hi, i no use win… and don’t test with directshow, but yes, you can capture with any sdk and convert the frame to iplImage structure.

  • Why don’t test with directshow??
    Is it bad???

    I’ve tried also this problem in Linux (Ubuntu). The result is the same.

    Ok then, thank you very much for your responds.

  • I don’t need test with directshow because i no need it at this moment, but in future i will need use it.

    Directshow is not bad, is other way to capture images. As V4l or specific camera driver or similar…

  • How do u save all the frames in a single video and save them with the correct filename like “pic_0001″, “pic_0002″??
    Thanks for your help. Really appreciate it.

  • There are another way to write avi with opencv, you can use videowriter class (C++): http://opencv.willowgarage.com/documentation/cpp/reading_and_writing_images_and_video.html#videowriter

    Or with c: http://opencv.willowgarage.com/documentation/c/reading_and_writing_images_and_video.html#writeframe

    You can see an example here:

    CvSize imgSize;
    imgSize.width = image->width;
    imgSize.height = image->height;

    double fps = cvGetCaptureProperty(
    input,
    CV_CAP_PROP_FPS
    );

    CvVideoWriter *writer = cvCreateVideoWriter(
    “out.avi”,
    CV_FOURCC(‘M’, ‘J’, ‘P’, ‘G’),
    fps,
    imgSize
    );

    IplImage* colourImage;
    //Keep processing frames…
    for (;;) {

    //Get a frame from the input video.
    colourImage = cvQueryFrame(input);
    cvWriteFrame(writer, colourImage);

    }

    cvReleaseVideoWriter(&writer);
    cvReleaseCapture(&input);

    }

  • Hi.
    What i’m trying to do is to try and save all the frame in a single avi video and save those frames in .jpg format with the correct filenameeg “depthmap0000.jpg”, ” depthmap0001.jpg” etc.

    Firstly, get the number of frames the avi video is holding.

    Secondly, loop over the number of frames one by one, then save these frames into the folder with the correct name accordingly to whichever frame they belong to.

    Can you like teach me cause i’m new to OpenCV.
    Thank you very much for your respond above. That was quick. *smile*

  • Ok the you want save each frames with correct name…

    You only need open video and read each frame in bucle and save it in correct file name.

    This can be a c example for get filename correctly with fixed number of characters:

    #include “stdio.h”;

    int main(){
    int totalFrames=30;
    int frameNum=0;
    int numChars=4;
    char parser[255];
    char fileName[255];

    //Create the file pattern with fixed number of characters
    sprintf(parser, “FileName_%%.%dd.ext”,numChars);
    printf(“%s\n”,parser);

    //Main bucle for save each frame.
    for(frameNum=0;frameNum<totalFrames; frameNum++){
    sprintf(fileName, parser, frameNum);
    printf("%s\n", fileName);
    //Now we can save the frame with name "fileName"
    /*

    */
    }
    return 0;
    }

    Regards.

  • Thanks again for your help. Much appreciated

  • Hello,

    Good article but memory management is not shown. where are you releasing your memory? Give 5-10 mins and memory heap shall be full and not surprisingly program will crash!

  • I’m sorry Damiles,
    I didn’t understeand the explanation you gave to lokye about saving each frame of a video in different images like out[fps].png, could you please be more specific, it would mean a lot to my graduation project, since i’ve got to learn openCV on my own! Thank you so much

  • It’s very simple, but my english is too bad.

    If you want save all images/frames you capture with your cam, you only need save each image in the main loop you use to show the image:

    example:
    for(;;){
    IplImage* frame = 0;
    int c;

    frame = cvQueryFrame( capture );
    if( !frame )
    break;

    cvSaveImage(“name_image.jpg”, frame);

    ….

  • Hi Damiles,

    I really appreciate your tutorials. It really helps me a lot :D

    From this tutorial, I try to get the next frame and I really have no idea how to get it. Can you help me?

    Thanks a lot

  • inside a loop yo u must do cvQeuryFrame

    Regards.

  • Sorry for my poor explanation.

    Actually I mean the next frame of the current frame in the loop. In this tutorial, you calculate the difference between current frame and the previous one.

    I want to know how to calculate the difference between current frame and the next one.

    Hope you understand

    Thanks a lot

  • you never can get the future!
    You can’t get next frame, if you get next frame then your actual frame is the past, no is actual ;) and next frame is the actual frame ;)

  • Yeah you’re right.. haha how stupid I am – -”

  • it was great help.thanks.i appreciate it.

  • Hi I want your help to extract unique frames from video i.e. there should not be any duplicate Frame in the video if so discard it while saving the image.
    plz help me in this respect

  • What do you want to do exactly? you don’t want save the image it’s similar to other saved image? then you can do a basic math operation

    sum(Frame(t) – Frame(t-1)) < threshold

    then the image are same and you don't need save it. the sum function is you sum each pixel value.

    You can create your own function to solve your problem this function is a very simply and basic idea.

    Regards David.

  • thx a lot it helped me alot.keep up tha good work

  • hi, i meet a problem regarding “cvAbsDiff(foreground,background,subtract);”

    Using break point, I meet a runtime error saying that “Unhandled exception at 0x74efd36f in test1.exe: Microsoft C++ exception: cv::Exception at memory location 0x001ffa08..”

    I need to click “break”, then a message showing that “No symbols are loaded for any call stack frame. The source code cannot be displayed.” pops out.

    In my exe file, the openCV Error: Assertion failed <src1.size == dst.size && src1.type == dst.type>

    My “foreground,background,subtract” are initialized as:
    IplImage* background=NULL;
    IplImage* foreground=NULL;
    IplImage* subtract=NULL;

    However, I found that the definition of cvAbsDiff is:
    /* dst(x,y,c) = abs(src1(x,y,c) – src2(x,y,c)) */
    CVAPI(void) cvAbsDiff( const CvArr* src1, const CvArr* src2, CvArr* dst );

    So, I am very curious how your program can run when you using different ‘type’ from original type of definition?

    Please help me, this problem has bothering me few days…:(

  • Hi, IplImage is a extension of CvArr then you can use as you do, the error is because you don’t have initialized with image some of your images.

  • OpenCV Error: Bad argument (Unknown array type) in cvarrToMat, file /home/sumit/Downloads/OpenCV-2.2.0/modules/core/src/matrix.cpp, line 641
    terminate called after throwing an instance of ‘cv::Exception’
    what(): /home/sumit/Downloads/OpenCV-2.2.0/modules/core/src/matrix.cpp:641: error: (-5) Unknown array type in function cvarrToMat

    Aborted (core dumped)

  • This is what I receive when I run the above code,

    OpenCV Error: Bad argument (Unknown array type) in cvarrToMat, file /home/sumit/Downloads/OpenCV-2.2.0/modules/core/src/matrix.cpp, line 641
    terminate called after throwing an instance of ‘cv::Exception’
    what(): /home/sumit/Downloads/OpenCV-2.2.0/modules/core/src/matrix.cpp:641: error: (-5) Unknown array type in function cvarrToMat

    Aborted (core dumped)

Got anything to say? Go ahead and leave a comment!

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

Category

Polls

How Is My Site?

View Results

Loading ... Loading ...

Twitter: damiles3D

  • Could not connect to Twitter