【Opencv-Ubuntu】论clone对Mat的重要性

今天在写代码的时候遇到这样一个问题

先来看个函数,这是一段更新subShape的函数:

void updateSubShape()
{
    double sub_shape_01_brow_left_data[10] = {
        mShape.part(17).x(),mShape.part(17).y(),
        mShape.part(18).x(),mShape.part(18).y(),
        mShape.part(19).x(),mShape.part(19).y(),
        mShape.part(20).x(),mShape.part(20).y(),
        mShape.part(21).x(),mShape.part(21).y()};
    sub_shape_01_brow_left = cv::Mat(5, 2, CV_64FC1, sub_shape_01_brow_left_data);
    double sub_shape_02_brow_right_data[10] = {
        mShape.part(22).x(),mShape.part(22).y(),
        mShape.part(23).x(),mShape.part(23).y(),
        mShape.part(24).x(),mShape.part(24).y(),
        mShape.part(25).x(),mShape.part(25).y(),
        mShape.part(26).x(),mShape.part(26).y()};
    sub_shape_02_brow_right = cv::Mat(5, 2, CV_64FC1, sub_shape_02_brow_right_data);
    double sub_shape_03_eye_left_data[12] = {
        mShape.part(36).x(),mShape.part(36).y(),
        mShape.part(37).x(),mShape.part(37).y(),
        mShape.part(38).x(),mShape.part(38).y(),
        mShape.part(39).x(),mShape.part(39).y(),
        mShape.part(40).x(),mShape.part(40).y(),
        mShape.part(41).x(),mShape.part(41).y()};
    sub_shape_03_eye_left = cv::Mat(6, 2, CV_64FC1, sub_shape_03_eye_left_data);
    double sub_shape_04_eye_right_data[12] = {
        mShape.part(42).x(),mShape.part(42).y(),
        mShape.part(43).x(),mShape.part(43).y(),
        mShape.part(44).x(),mShape.part(44).y(),
        mShape.part(45).x(),mShape.part(45).y(),
        mShape.part(46).x(),mShape.part(46).y(),
        mShape.part(47).x(),mShape.part(47).y()};
    ......
    sub_shape_04_eye_right = cv::Mat(6, 2, CV_64FC1, sub_shape_04_eye_right_data);
    std::cout << "sub_shape_01_brow_left:" << sub_shape_01_brow_left << std::endl;
    std::cout << "sub_shape_02_brow_right:" << sub_shape_02_brow_right << std::endl;
    std::cout << "sub_shape_03_eye_left:" << sub_shape_03_eye_left << std::endl;
    std::cout << "sub_shape_04_eye_right:" << sub_shape_04_eye_right << std::endl;
    ......
}

笔者在当前函数内打印出01,02,03,04四个Mat的信息如下:

sub_shape_01_brow_left:

[77, 83;
 83, 78;
 92, 77;
 100, 79;
 107, 84]
sub_shape_02_brow_right:

[122, 86;
 131, 84;
 141, 85;
 150, 90;
 156, 97]
sub_shape_03_eye_left:

[85, 96;
 90, 95;
 96, 96;
 101, 99;
 95, 100;
 90, 99]
sub_shape_04_eye_right:

[128, 103;
 134, 102;
 139, 103;
 145, 106;
 139, 106;
 133, 106]

 然而神奇的一幕来啦,当笔者在另外一个函数中调用上述函数,打印出01,02,03,04四个Mat的信息如下:

sub_shape_01_brow_left:

[77, 83;
 83, 78;
 92, 77;
 100, 79;
 107, 84]
sub_shape_02_brow_right:

[122, 86;
 131, 84;
 141, 85;
 150, 90;
 156, 97]
sub_shape_03_eye_left:

[85, 96;
 1.197398590121304e-47, 95;
 6.952696120312864e-310, 6.952696120312864e-310;
 6.444060669718295e-316, 1.427990031124621e-316;
 6.952696120331045e-310, 4.940656458412465e-324;
 3.458459520888726e-323, 6.937713299605351e-310]
sub_shape_04_eye_right:

[128.0001200092957, 6.444533391728236e-316;
 6.444533391728236e-316, 6.444533391728236e-316;
 6.444533391728236e-316, 6.444533638761059e-316;
 6.444533737574188e-316, 6.444533391728236e-316;
 6.444533737574188e-316, 0;
 0, 0]

发现竟然01,02指向的Mat数据正确,03,04指向的数据就完全错了,这是神马情况。然而在cv::Mat(xxx)后添加.clone()后就可以解决上述问题。

原来Mat有浅拷贝和深拷贝的区分,cv::Mat C(xxx)只是一个浅拷贝的状况,浅拷贝后的变量指针都会与Mat指向同一个内存地址,在上述函数中笔者使用了大量的cv::Mat(xxx)进行浅拷贝,笔者猜测应当是opencv在函数操作中对Mat的内存分配是存在一定限制的,由于笔者使用的cv::Mat(xxx)过多,已经超出了opencv的限制,因此在函数结束后,部分内存被自动释放,所以导致了上述这个问题。而采用clone的深拷贝的方式,会完整的为变量字段开辟一个属于自己的内存空间,函数结束后,内存不能被自动释放,所以不会出现上述问题。

由此可见,使用opencv的Mat,一定要深入理解浅拷贝和深拷贝的含义啊,clone也对于Mat变得无比重要。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二十四桥下一句

您的鼓励是我最大的创作动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值