Search code examples
c++opencvobservers

How to retrieve a cv::Mat object from an object of this API class?


I am stuck trying to get a cv::Mat object from another class (third party code) into my main function.

I have a class:

FrameObserver.h

class FrameObserver : virtual public IFrameObserver
{
public:

    FrameObserver( CameraPtr pCamera, FrameInfos eFrameInfos, ColorProcessing eColorProcessing );
    cv::Mat m_ConvertImage;
    // This is our callback routine that will be executed on every received frame
    virtual void FrameReceivedLeft( const FramePtr pFrame );
    virtual void FrameReceivedRight(const FramePtr pFrame);
    void ProcessCvLeft(const FramePtr pFrame);
    void ProcessCvRight(const FramePtr pFrame);
    static cv::Mat FrameObserver::getCurrentFrame() { return currentFrame; }

private:
    static cv::Mat currentFrame;

#ifdef WIN32
    double      m_dFrequency;
#endif //WIN32
};

}}} // namespace AVT::VmbAPI::Examples

FrameObserver.cpp

void FrameObserver::ProcessCvLeft(const FramePtr pFrame)
{
    VmbUchar_t *pBuffer;
    VmbUint32_t FrameWidth;
    VmbUint32_t FrameHeight;

    pFrame->GetWidth(FrameWidth);
    pFrame->GetHeight(FrameHeight);
    pFrame->GetImage(pBuffer);

    ShowFrameInfos(pFrame);

    IplImage *img1 = cvCreateImageHeader(cvSize(
        FrameWidth,
        FrameHeight),
        IPL_DEPTH_8U,
        1);
    cvSetData(img1, pBuffer, img1->widthStep);

    cv::Mat copyimageL = cv::cvarrToMat(img1);

    currentFrame = copyimageL;  //copies to currentFrame here
}

Then I have main.cpp:

cv::Mat Mainframe;

int main( int argc, char* argv[] )
{
//I need to pull the currentFrame Mat stream into the frame Mat above.
}

What is the best way to do this? I have tried:

FrameObserver fo;
cv::Mat test = fo.currentFrame;

But it gives me the following error:

no default constructor exists for class "FrameObserver"

Thank you.


Solution

  • As far as C++ goes, your mistake is that the class FrameObserver has no default constructor (i.e. a constructor that can be called without arguments). It's not defined explicitly, nor will it be generated, since another constructor has already been defined (see here). Thus, you can't write

    FrameObserver fo;
    

    Since this invokes the default constructor FrameObserver::FrameObserver() which (see above) is not present. Thus, you should create the FrameObserver object using the existing constructor with arguments FrameObserver::FrameObserver( CameraPtr pCamera, FrameInfos eFrameInfos, ColorProcessing eColorProcessing );

    Now on to the actual problem. Since this class is a part of a supplied API, you shouldn't try to change it, rather learn to use it correctly. By the name of it, it appears to be an observer. Thus, you need to create an instance of it (a single one, at that), and carefully read the docs on how it's supposed to supply you frame data as a matrix. I don't know how exactly it works, but by common sense, since it's an "observer", it should automatically provide you with notifications about incoming frames. Again, have a close look at the documentation.

    Important edit:

    Here it is, look at the header:

    // This is our callback routine that will be executed on every received frame
    virtual void FrameReceivedLeft( const FramePtr pFrame );
    virtual void FrameReceivedRight(const FramePtr pFrame);
    

    By the looks of it, you are supposed to subclass FrameObserver and reimplement the two above functions. That means that the code to process or extract those frames must reside inside those routines in the subclass you're going to create.

    Anyway, while the details may vary, the concept stays: the observer is going to call some methods on its own. You can only wait for it to call those methods and react accordingly. More precisely, you register your class object or function within the observer object, and then let the observer call those methods automatically. (It is said that you "subscribe to the notifications" provided by the observer).