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