2012-06-27 2 views
7

Я передаю Mat другой функции и изменяю ее внутри вызываемой функции. Я ожидал, что, будучи более сложным типом, он автоматически передается по ссылке, чтобы матрица изменилась в вызывающей функции, но это не так. Может ли кто-нибудь указать мне на объяснение того, как правильно вернуть измененный Мат из функции?OpenCV change Mat внутри функции (область маштаба)

Вот фрагмент кода:

void callingFunction(Mat img) 
{ 
    Mat tst(100,500,CV_8UC3, Scalar(0,255,0)); 
    saveImg(tst, "Original image", true); 
    testImg(tst); 
    saveImg(tst, "Want it to be same as inside testImg but is same as Original", true); 
} 

void testImg(Mat img) 
{ 
    int rs = 50; // rows 
    int cs = 100; // columns 
    img = Mat(rs, cs, CV_8UC3, Scalar(255,0,0)); 
    Mat roi(img, Rect(0, 0, cs, rs/2)); 
    roi = Scalar(0,0,255); // change a subsection to a different color 

    saveImg(img, "inside testImg", true); 
} 

Спасибо!

ответ

8

Вы должны определить Mat как parameter-reference (&). Вот редактируется код:

void callingFunction(Mat& img) 
{ 
    Mat tst(100,500,CV_8UC3, Scalar(0,255,0)); 
    saveImg(tst, "Original image", true); 
    testImg(tst); 
    saveImg(tst, "Want it to be same as inside testImg but is same as Original", true); 
} 

void testImg(Mat& img) 
{ 
    int rs = 50; // rows 
    int cs = 100; // columns 
    img = Mat(rs, cs, CV_8UC3, Scalar(255,0,0)); 
    Mat roi(img, Rect(0, 0, cs, rs/2)); 
    roi = Scalar(0,0,255); // change a subsection to a different color 

    saveImg(img, "inside testImg", true); 
} 
+0

Так что я должен явно передать ссылку. Благодаря! – zzzz

-2

Если это правда, что вы должны явно передавать по ссылке, то, как работают все функции OpenCV? Ни один из них не передает значения по ссылке, но они каким-то образом, похоже, очень хорошо записывают переданный в Mat. Например, здесь есть декларация функции Собела в imgproc.hpp:

//! applies generalized Sobel operator to the image 
CV_EXPORTS_W void Sobel(InputArray src, OutputArray dst, int ddepth, 
         int dx, int dy, int ksize=3, 
         double scale=1, double delta=0, 
         int borderType=BORDER_DEFAULT); 

, как вы можете видеть, она проходит в ЦСИ и целевой_адрес без &. И все же я знаю, что после того, как я позвоню Собелю с пустым dst, он будет заполнен. Нет «&».

+2

typedef _OutputArray & OutputArray; - Ты просто ошибаешься. – berak

2

Я задавался вопросом о том же самом вопросе, поэтому хотел бы еще раз пояснить ответ, данный @ArtemStorozhuk (что правильно).

Документации OpenCV вводит в заблуждении здесь, потому что кажется, вы передаете матрицу по значению, но на самом деле :: OutputArray определяется конструктор сорта следующим образом:

_OutputArray::_OutputArray(Mat& m) 

поэтому он получает матрицу по ссылке!

Поскольку операции типа cv :: Mat :: create создают новую матрицу, операция освобождает ссылку и устанавливает бит на 1. Таким образом, чтобы сохранить результат в вызывающей функции, вы должны передать матрицу по ссылке.

Смежные вопросы