Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# EMGU EMGUCV
I am using EmguCV 2.3.0 and am querying frames at random intervals from a Capture to be saved to hard drive. The problem is when I call the Capture.QueryFrame() or Capture.QuerySmallFrame() it is delayed by a frame. To make this more clear: I start the program and query a frame pointed at my face. My face appears in the .jpeg. I then point the camera away from my face and query another frame, and my face appears in the .jpeg again. I then point it back at my face once more, query a frame and the .jpeg contains the image pointed away from my face. There appears to be a 1 frame delay in a query. Is there some underlying buffer? What is causing this? And most importantly: how can I solve this problem without querying multiple frames for a single captured image?
 
Another question I have is that when I set the webcam resolution to 1600x1200, the program and computer begins to lag - even without making use of the images or querying frames. Is that caused only because I create a Capture and keep it in memory? Is there a way to lessen the affects of this?
Posted 20-Sep-11 13:58pm
Edited 29-Sep-11 9:34am
C_Johnson38.1K
v2

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Hi
 
(I'm the same person who gave you this answer on Stackoverflow in case you think I'm copying Smile | :) , this is just in case others stumble across this question)
 
Well the problem you have is that your not disposing of your old capture so when you send of for another it will always return the old one and then get another. The following code adjusted from the Web camera example should do the trick.
 
    _capture = new Capture();
    Image<Bgr, Byte> frame = _capture.QueryFrame();
    
    Image<Gray, Byte> grayFrame = frame.Convert<Gray, Byte>();
    Image<Gray, Byte> smallGrayFrame = grayFrame.PyrDown();
    Image<Gray, Byte> smoothedGrayFrame = smallGrayFrame.PyrUp();
    Image<Gray, Byte> cannyFrame = smoothedGrayFrame.Canny(new Gray(100), new Gray(60));
 
    captureImageBox.Image = frame;
    grayscaleImageBox.Image = grayFrame;
    smoothedGrayscaleImageBox.Image = smoothedGrayFrame;
    cannyImageBox.Image = cannyFrame;
    _capture.Dispose();
 
It is the _capture.Dispose(); that is the important bit.
 
As for your 1600x1200 yes your right it is because you have a large amount of data in memory. First of start by efficiently 'using' the memory stream and disposing of it when where done with it. This is done with the 'using' statement which automatically creates the object at the start and calls its .Dispose function at the end, just so you don't have to. Note the copy procedure else a pointer is passed and when you exit the using code you will dispose of frame as well. You should also practice the 'using' statement when using images. But the above code will now look like this:
 
    Image<Bgr, Byte> frame;
    using (Capture capture = new Capture())
    {
        frame = capture1.QueryFrame().Copy(); //You must copy else frame will be disposed off
    }
    Image<Gray, Byte> grayFrame = frame.Convert<Gray, Byte>();
    Image<Gray, Byte> smallGrayFrame = grayFrame.PyrDown();
    Image<Gray, Byte> smoothedGrayFrame = smallGrayFrame.PyrUp();
    Image<<gray,> cannyFrame = smoothedGrayFrame.Canny(new Gray(100), new Gray(60));
 
    grayscaleImageBox.Image = grayFrame;
    smoothedGrayscaleImageBox.Image = smoothedGrayFrame;
    cannyImageBox.Image = cannyFrame;
 
Second of all you can resize the captured image using .Resize(scale, Interpolation Method). Large images are usually passed from a camera using a dedicated frame grabber so system dependency is avoided obviously this is no longer the case with HD USB web cams.
 
You can resize your input image like so and with your 'using' statements efficiently your final code will look like this:
 
    Image<Bgr, Byte> frame;
    using (Capture capture1 = new Capture())
    {
        frame = capture1.QueryFrame().Resize(0.5, Emgu.CV.CvEnum.INTER.CV_INTER_AREA).Copy();
        captureImageBox.Image = frame;
    }
    
    using (Image<Gray, Byte> grayFrame = frame.Convert<Gray, Byte>())
    {
        grayscaleImageBox.Image = grayFrame;
        using (Image<Gray, Byte> smallGrayFrame = grayFrame.PyrDown())
        {
            using (Image<Gray, Byte> smoothedGrayFrame = smallGrayFrame.PyrUp())
            {
                smoothedGrayscaleImageBox.Image = smoothedGrayFrame;
                using (Image<Gray, Byte> cannyFrame = smoothedGrayFrame.Canny(new Gray(100), new Gray(60)))
                {
                    cannyImageBox.Image = cannyFrame;
                }
            }
        }
    }
 
Cheers
Chris
  Permalink  
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 6,769
1 Sergey Alexandrovich Kryukov 6,338
2 DamithSL 5,408
3 Manas Bhardwaj 4,816
4 Maciej Los 4,195


Advertise | Privacy | Mobile
Web01 | 2.8.1411023.1 | Last Updated 29 Sep 2011
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100