为什么包装 setMouseCallback 会导致 Mat 对象为空

Why does wrapping setMouseCallback cause Mat object to be empty?

本文关键字:Mat 对象 包装 setMouseCallback 为什么      更新时间:2023-10-16

我不明白为什么包装setMouseCallback会导致onMouse中的Mat对象为空,而直接在main中调用setMouseCallback则不然。

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;

void onMouse(int event, int x, int y, int flags, void* param)
{
    Mat* image = reinterpret_cast<Mat*>(param);
    if (image->empty())
        cout << "The image is empty." << endl;
}
void Wrapper(Mat input)
{
    setMouseCallback("Input Window", onMouse, reinterpret_cast<void*>(&input));
}
int main()
{
    Mat input = imread("filename.jpg", IMREAD_UNCHANGED);
    namedWindow("Input Window", WINDOW_NORMAL);
    imshow("Input Window", input);
    // Wrapper(input); // A
    //setMouseCallback("Input Window", onMouse, reinterpret_cast<void*>(&input)); //B
    waitKey(0);
}

编辑

亚历克西斯·威尔克(Alexis Wilke(回答中的推理是有道理的,但可能不是100%正确的。在下面的代码中,我包装了整个代码,这样就不需要Mat传递给Wrapper但问题仍然存在。那么是什么原因造成的呢?

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;

void onMouse(int event, int x, int y, int flags, void* param)
{
    Mat* image = reinterpret_cast<Mat*>(param);
    if (image->empty())
        cout << "The image is empty." << endl;
}
void Wrapper()
{
    Mat input = imread("filename.jpg", IMREAD_UNCHANGED);
    namedWindow("Input Window", WINDOW_NORMAL);
    imshow("Input Window", input);
    setMouseCallback("Input Window", onMouse, reinterpret_cast<void*>(&input));
}
int main()
{
    Wrapper(); 
    waitKey(0);
}

你的意思是用引用值声明Wrapper(),而不是通过复制来声明值:

void Wrapper(Mat & input)
{
    setMouseCallback("Input Window", onMouse, reinterpret_cast<void*>(&input));
}

查看附加&

如果没有&,您将传递一份input的副本,并且您的原始副本不会被修改。

Mat input;
Wrapper(input);   // without the `&`, input is copied and whatever happens
                  // to the copy is not known by the caller

您也可以使用指针:

void Wrapper(Mat * input)

虽然我怀疑你正在使用引用来避免指针。

原因未知

,但以下解决了问题!

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;

void onMouse(int event, int x, int y, int flags, void* param)
{
    Mat* image = reinterpret_cast<Mat*>(param);
    if (image->empty())
        cout << "The image is empty." << endl;
}
void Wrapper()
{
    Mat input = imread("filename.jpg", IMREAD_UNCHANGED);
    namedWindow("Input Window", WINDOW_NORMAL);
    imshow("Input Window", input);
    setMouseCallback("Input Window", onMouse, reinterpret_cast<void*>(&input));
    waitKey(0);
}
int main()
{    
    Wrapper();             
}