Search code examples
c++opencv

Can the OpenCV function cvtColor be used to convert a matrix in place?


The OpenCV function cvtColor converts the color space of a matrix (e.g. from RGB to grayscale). The function's C++ signature is

void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0 )

Can this function be used convert a matrix in place, i.e. with src the same object as dst?

cv::Mat mat = getColorImage();
cvtColor(mat, mat, CV_RGB2GRAY);

(I'm aware that either way, as the destination has a different number of channels than the source, it will still need to allocate a new block of memory for the destination.)

More generally, is there a convention within the OpenCV API to determine when a function may be used in this way?


Solution

  • Maybe it’s too late for answering, but I want to say that I don’t agree with some things that have been written here.
    You can place the same exact Mat as source and destination, with no problem, even if the destination matrix has not “the same number of channel”, or even if the dest matrix has not been created yet.
    OpenCV programmers designed it thoroughly.
    All users of this function have to do is to take care that the source Mat is correct, as to number of channels and type of data, and remember that after the function call they could change.

    The proof comes from looking at source code, on line 2406, just the first line inside the cv::cvtColor(…) function,

    Mat src = _src.getMat();
    

    is called, then Mat dst is created (and dst=_dst=_scr).
    So the situation inside cv::cvtColor(…) is the following when making in-place calling: src points to the old matrix, _src, _dst, dst all point to the same new allocated matrix, which will be the destination matrix.
    This means than now new variables src and dst (not the ones from function call _src and _dst) are ready to be passed to the real converting function.
    When function void cv::cvtColor(…) is done, src is disposed and _src, _dst and dst all point to the same Mat and refcount of _dst will go to 1.