1 inline 2 Mat Mat::clone() const 3 { 4 Mat m; 5 copyTo(m); 6 return m; 7 }

1 void Mat::copyTo( OutputArray _dst ) const 2 { 3 int dtype = _dst.type(); 4 if( _dst.fixedType() && dtype != type() ) 5 { 6 CV_Assert( channels() == CV_MAT_CN(dtype) ); 7 convertTo( _dst, dtype ); 8 return; 9 } 10 11 if( empty() ) 12 { 13 _dst.release(); 14 return; 15 } 16 17 if( _dst.isUMat() ) 18 { 19 _dst.create( dims, size.p, type() ); 20 UMat dst = _dst.getUMat(); 21 22 size_t i, sz[CV_MAX_DIM], dstofs[CV_MAX_DIM], esz = elemSize(); 23 for( i = 0; i < (size_t)dims; i++ ) 24 sz[i] = size.p[i]; 25 sz[dims-1] *= esz; 26 dst.ndoffset(dstofs); 27 dstofs[dims-1] *= esz; 28 dst.u->currAllocator->upload(dst.u, data, dims, sz, dstofs, dst.step.p, step.p); 29 return; 30 } 31 32 if( dims <= 2 ) 33 { 34 _dst.create( rows, cols, type() ); 35 Mat dst = _dst.getMat(); 36 if( data == dst.data ) 37 return; 38 39 if( rows > 0 && cols > 0 ) 40 { 41 // For some cases (with vector) dst.size != src.size, so force to column-based form 42 // It prevents memory corruption in case of column-based src 43 if (_dst.isVector()) 44 dst = dst.reshape(0, (int)dst.total()); 45 46 const uchar* sptr = data; 47 uchar* dptr = dst.data; 48 49 CV_IPP_RUN( 50 (size_t)cols*elemSize() <= (size_t)INT_MAX && 51 (size_t)step <= (size_t)INT_MAX && 52 (size_t)dst.step <= (size_t)INT_MAX 53 , 54 ippiCopy_8u_C1R(sptr, (int)step, dptr, (int)dst.step, ippiSize((int)(cols*elemSize()), rows)) >= 0 55 ) 56 57 Size sz = getContinuousSize(*this, dst); 58 size_t len = sz.width*elemSize(); 59 60 for( ; sz.height--; sptr += step, dptr += dst.step ) 61 memcpy( dptr, sptr, len ); 62 } 63 return; 64 } 65 66 _dst.create( dims, size, type() ); 67 Mat dst = _dst.getMat(); 68 if( data == dst.data ) 69 return; 70 71 if( total() != 0 ) 72 { 73 const Mat* arrays[] = { this, &dst }; 74 uchar* ptrs[2]; 75 NAryMatIterator it(arrays, ptrs, 2); 76 size_t sz = it.size*elemSize(); 77 78 for( size_t i = 0; i < it.nplanes; i++, ++it ) 79 memcpy(ptrs[1], ptrs[0], sz); 80 } 81 }
测试代码:
#include <iostream> #include <vector> #include <numeric> #include "opencv2/opencv.hpp" using namespace std; int main() { const std::string path = "415-DST.bmp"; cv::Mat src = cv::imread(path, cv::IMREAD_COLOR); cv::Mat dst1; cv::Mat dst2; std::vector<double> ratios; for (int i = 0; i < 1000; i++) { double t = cv::getTickCount(); dst1 = src.clone(); t = (cv::getTickCount() - t); cout << "clone:" << t << endl; double t1 = cv::getTickCount(); src.copyTo(dst2); t1 = (cv::getTickCount() - t1) ; cout << "copyTo:" << t1 << endl; double r = t / t1; ratios.push_back(r); cout << "clone-CopytTo Ratio: " << r << endl; cout << "--------------------------------\n"; } double avg = std::accumulate(ratios.begin(), ratios.end(), 0.0) / ratios.size(); cout << "average ratio:" << avg << endl; system("pause"); return 0; }
结论: clone()函数要比copyTo函数慢3倍左右