Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Is cv::Mat copy constructor legit?

I use const to protect my objects during function calls. What I didn't know is that if you pass a const cv::Mat and inside the function you duplicate this header, you gain access to the imageData. Consider the example code:

void funct(const cv::Mat &img)
{
    //img.at<uchar>(0,0)=0; // Cannot be compiled due to const protection.
    std::vector<cv::Mat> myMats;
    myMats.push_back(img);
    myMats.front().at<uchar>(0,0)=0; //Successful modification to image.
    return;
}

int main(int argc, char* argv[])
{
    cv::Mat myImg(1,1,CV_8U,cv::Scalar(255));
    std::cout<<myImg; //Prints [255]
    funct(myImg);
    std::cout<<myImg; //Prints [0] which should not happen according to 'const'.
}

I solved this issue by pushing_back a clone() of the image (myMats.pu_back(img.clone()). Isn't a bad tactic to design an object like this? The const protection becomes useless.

I know that opencv is huge now, but isn't this a very basic design flaw or something calculated? I personally prefer the copy constructor to return a deep copy of the image and if I want memory efficiency, I'll use references (const cv::Mat &). Any opinions?

Is cv::Mat copy constructor legit?

I use const to protect my objects during function calls. What I didn't know is that if you pass a const cv::Mat and inside the function you duplicate this header, you gain access to the imageData. Consider the example code:

void funct(const cv::Mat &img)
{
    //img.at<uchar>(0,0)=0; // Cannot be compiled due to const protection.
    std::vector<cv::Mat> myMats;
    myMats.push_back(img);
    myMats.front().at<uchar>(0,0)=0; //Successful modification to image.
    return;
}

int main(int argc, char* argv[])
{
    cv::Mat myImg(1,1,CV_8U,cv::Scalar(255));
    std::cout<<myImg; //Prints [255]
    funct(myImg);
    std::cout<<myImg; //Prints [0] which should not happen according to 'const'.
}

I solved this issue by pushing_back pushing_back a clone() of the image (myMats.pu_back(img.clone())myMats.push_back(img.clone()). Isn't a bad tactic to design an object like this? The const protection becomes useless.

I know that opencv is huge now, but isn't this a very basic design flaw or something calculated? I personally prefer the copy constructor to return a deep copy of the image and if I want memory efficiency, I'll use references (const cv::Mat &). Any opinions?