项目中的一个小功能,需要实现视频特定区域的背景替换,遂写下这样一个函数:
void bgReplace(Mat& dst, Mat&bg, Rect rec)
{
assert(dst.size()==bg.size());
assert(dst.depth() == bg.depth());
dst(rec) = bg(rec).clone();//可深可浅
}
功能,用rec指定需要替换的区域,用bg的该区域值替换dst的该区域值。
但是,出乎意料的是这个函数什么也没做,根本没有达到预期,按我所想,对ROI 区域的一切操作就是对源图像的直接操作啊,因为两者是共享同一块内存区域啊,而且我还用了深复制,然而,真是想多了。
具体原因,我们可以将程序分解一下再看:
void bgReplace(Mat& dst, Mat&bg, Rect rec)
{
assert(dst.size()==bg.size());//1
assert(dst.depth() == bg.depth());//2
Mat tmp=dst(rec);//3
tmp= bg(rec);//可深可浅//4
}
在3句执行完后,tmp和dst共享同一块数据,但是在4句执行完时,tmp是和bg共享同一块数据,而不是dst,这里只是进行了一次矩阵头信息的改变,并未改变原始数据。
修改后程序为:
void bgReplace(Mat& dst, Mat&bg, Rect rec)
{
assert(dst.size()==bg.size());
assert(dst.depth() == bg.depth());
bg(rec).copyTo(dst(rec));//可深可浅
}
问题很简单,只因自己犯了错误。