Understanding OpenCV Clone

Asked 1 years ago, Updated 1 years ago, 62 views

An "Access Violation" error occurs when creating programs using OpenCV and analog cameras.
I'm multi-threaded and I'm converting the image I got from the camera on the first thread to cv::Mat. I'm trying to process this image on the second thread.

<Threads retrieving images>

 cv::Mat frame;
DWORD WINAPI ImageThread (LPVOID lpData)
{   
    while(!lpd->bEnd){

        if(mJpegData!=nullptr&mJpegSize>0){
            std::vector<unsigned char>tmp(mJpegData, mJpegData+mJpegSize);
            frame=cv::imdecode(tmp,cv::IMREAD_COLOR);
            cv::imwrite("img_debug.bmp", frame);
        }
    }
    return 0;
}

<Threads copying images>

DWORD WINAPI ConThread (LPVOID lpData)
{
    cv::Matimg;

    while(!lpd->bEnd){
        if(!frame.empty){
            img = frame.clone(); // Comment out here without error
        }
    }
}

The OpenCV version is 3.3.
Could someone please tell me the solution?

c++ opencv multi-threaded

2022-09-30 19:42

1 Answers

 frame=cv::imdecode(tmp,cv::IMREAD_COLOR);

This line refers to cv::Mat::operator=().

Before assigning new data, the old data is de-referenced via Mat::release.

Data held by the frame is released as described in .If you read it from a different thread using frame.clone(), you will naturally get an error.

Although it can be resolved by inserting an exclusive action, we recommend that you consider what to do with the lock range and whether there are any other exclusions besides the frame variable.

<Threads retrieving images>

 cv::Mat frame;
cv::Mutex mutex;
DWORD WINAPI ImageThread (LPVOID lpData)
{   
    while(!lpd->bEnd){

        if(mJpegData!=nullptr&mJpegSize>0){
            std::vector<unsigned char>tmp(mJpegData, mJpegData+mJpegSize);
            cv::AutoLock lock (mutex);
            frame=cv::imdecode(tmp,cv::IMREAD_COLOR);
            cv::imwrite("img_debug.bmp", frame);
        }
    }
    return 0;
}

<Threads copying images>

DWORD WINAPI ConThread (LPVOID lpData)
{
    cv::Matimg;

    while(!lpd->bEnd){
        cv::AutoLock lock (mutex);
        if(!frame.empty){
            img = frame.clone();
        }
    }
}

Am I correct in understanding that when (!frame.empty()) is done on the thread copying the image, an error may occur because there may be an undefined (irregular) timing between this if statement and "img=frame.clone()" in frame?

Access violations occur if Mat::release releases memory on a separate thread, even if frame.clone() is running as well as frame.clone().Because objects are not GC-managed in the C++ language, there is no guarantee that they will not be released because they are running.


2022-09-30 19:42

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.