Почему перенос setMouseCallback приводит к тому, что объект Mat становится пустым? - PullRequest
0 голосов
/ 05 апреля 2019

Я не понимаю, почему в результате переноса setMouseCallback объект Mat в onMouse становится пустым, в то время как вызов setMouseCallback непосредственно в main не делает.

#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);
}

Редактировать

Аргументация в ответ Алексис Уилк имеет смысл, но она может быть не на 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);
}

Ответы [ 2 ]

0 голосов
/ 05 апреля 2019

Рассуждение оставлено как неизвестное, но следующее решило проблему!

#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();             
}
0 голосов
/ 05 апреля 2019

Вы хотите объявить 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)

, хотя я подозреваю, что выиспользуя ссылку, чтобы избежать указателя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...