文章要說的内容如題:用vec類型變量構造Mat
在OpenCV2.3.1的英文版官方手冊的25頁有一段執行個體代碼:
std::vector<Point3f> vec;
...
Mat pointMat = Mat(vec). // convert vector to Mat, O(1) operation
reshape(1). // make Nx3 1-channel matrix out of Nx1 3-channel.
// Also, an O(1) operation
t(); // finally, transpose the Nx3 matrix.
// This involves copying all the elements
第一行,當我們利用Mat(vec)來構造了一個Mat類型的後,如果我們直接利用Mat中的Mat.at<float>(i,j)來輸出元素的時候,我發現它隻是輸出了Point3f一個三維空間點的第一個坐标值,那麼問題出在什麼地方呢?
讓我們在Mat pointMat = Mat(vec). 一行按F9插入斷點,然後按F11進入程式中去檢視真相:
程式進入到了mat.hpp檔案中如下圖中的位置:

然後我們仔細分析代碼:
template<typename _Tp> inline Mat::Mat(const vector<_Tp>& vec, bool copyData)
: flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), //初始化清單
dims(2), rows((int)vec.size()), cols(1), data(0), refcount(0), //初始化清單
datastart(0), dataend(0), allocator(0), size(&rows) //初始化清單
{
if(vec.empty())
return;
if( !copyData )
{
step[0] = step[1] = sizeof(_Tp);
data = datastart = (uchar*)&vec[0];
datalimit = dataend = datastart + rows*step[0];
}
else
Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
}
如紅色部分顯示,原來我們構造的Mat類型資料的行數row等于vec.size()。那麼因為vec的元素類型是Point3f類型的,是以其實我們産生的Mat的行數就是1.自然當我們利用循環來顯示Mat資料時,就隻顯示出了一個元素,如果想顯示三個坐标:那麼我們隻能利用data(指向真實資料的char*類型指針來操作了)
如下:
cout<<*((float*)pointMat.data)<<endl;
cout<<*((float*)pointMat.data+1)<<endl;
cout<<*((float*)pointMat.data+2)<<endl;
就可以顯示Point3f三個坐标系的值了。