1. 程式人生 > >OpenCV不同型別Mat的at方法訪問元素時該如何確定模板函式的typename(轉)

OpenCV不同型別Mat的at方法訪問元素時該如何確定模板函式的typename(轉)

自從OpenCV推出了Mat後越來越像是Matlab了,使用起來方便了很多,但是,在用at方法訪問Mat時,如何選用合適的typename型別來訪問相應的Mat元素是個頭疼的問題。

比如:

 

int Height = 100;

int Width = 100;

Mat  ImageMat8U(Height, Width, CV_8UC1);

for(int i=0; i<Height; i++)

{

for(int j=0; j<Width;j++)

{

ImageMat8U.at<uchar>(i, j) = (uchar)0; //編譯可以通過,執行也正確

ImageMat8U.at<int>(i, j) = (uchar)0; //編譯可以通過,執行時會發生asser錯誤

}

}

 

通常如果選錯了typename,編譯仍然可以通過,但是執行時總會發生assert錯誤,原因是無法通過depth檢查。這裡對不同型別的Mat使用at方法時對應的typename做個總結:

CV_8U: bool或者uchar 
CV_8S: schar或者char
CV_16U: ushort
CV_16S: short 
CV_32S: int或者unsigned
CV_32F: float
CV_64F: double

實際上資料depth的檢查涉及到了一個模板類:

 

template<typename _Tp> class CV_EXPORTS DataDepth {};

 

這個類的特化就指定了Mat型別與typename型別之間的對應關係:

 

template<> class DataDepth<bool> { public: enum { value = CV_8U, fmt=(int)'u' }; };
template<> class DataDepth<uchar> { public: enum { value = CV_8U, fmt=(int)'u' }; };
template<> class DataDepth<schar> { public: enum { value = CV_8S, fmt=(int)'c' }; };
template<> class DataDepth<char> { public: enum { value = CV_8S, fmt=(int)'c' }; };
template<> class DataDepth<ushort> { public: enum { value = CV_16U, fmt=(int)'w' }; };
template<> class DataDepth<short> { public: enum { value = CV_16S, fmt=(int)'s' }; };
template<> class DataDepth<int> { public: enum { value = CV_32S, fmt=(int)'i' }; };
// this is temporary solution to support 32-bit unsigned integers
template<> class DataDepth<unsigned> { public: enum { value = CV_32S, fmt=(int)'i' }; };
template<> class DataDepth<float> { public: enum { value = CV_32F, fmt=(int)'f' }; };
template<> class DataDepth<double> { public: enum { value = CV_64F, fmt=(int)'d' }; };
template<typename _Tp> class DataDepth<_Tp*> { public: enum { value = CV_USRTYPE1, fmt=(int)'r' }; };
---------------------

轉自:https://blog.csdn.net/xxyhjy/article/details/45485619