五种Mat元素的访问方法

发布时间:2015-11-16 13:57:44   来源:文档文库   
字号:

五种Mat元素的访问方法

方法1、使用Mat的成员函数at<>()

    Mat的成员函数at()是一个模板函数,我们这里用的是二维矩阵,所以我们使用的at()函数的声明如代码段3所示(取自OpenCV的源文件)。

[cpp] view plaincopy

1. template<typename _Tp> _Tp& at(int i0, int i1);  

代码段3 .at()函数的声明

    代码段4是本文第二部分描述的算法的实现,矩阵元素使用at<>()函数来索引。

[cpp] view plaincopy

1. Vec3b pix;  

2. for (int r = 0; r < im.rows; r++)  

3. {  

4.   for (int c = 0; c < im.cols; c++)  

5.   {     

6.     pix = im.at(r,c);  

7.     pix = pix*scale;  

8.     om.at(r,c) = pix;  

9.   }     

10. }  

代码段4. 使用at<>()函数访问矩阵元素

    注意:使用at函数时,应该知道矩阵元素的类型和通道数,根据矩阵元素类型和通道数来确定at函数传递的类型,代码段4中使用的是Vec3b这个元素类型,他是一个包含3unsigned char类型向量。之所以采用这个类型来接受at的返回值,是因为,我们的矩阵im3通道,类型为unsigned char类型的。

方法2、使用Mat的成员函数ptr<>()

    此函数也是模板函数,我们将会用到的ptr函数声明如代码段5所示。此函数返回指定的数据行的首地址。

[cpp] view plaincopy

1. template<typename _Tp> _Tp* ptr(int i0=0);  

代码段 5. ptr成员函数的声明

    使用ptr<>()成员函数完成本文第二部分所述算法的代码如代码段6所示。

[cpp] view plaincopy

1. Vec3b *ppix_im(NULL);  

2. Vec3b *ppix_om(NULL);  

3. for (int r = 0; r < im.rows; r++)  

4. {  

5.   ppix_im = im.ptr(r);  

6.   ppix_om = om.ptr(r);  

7.   for (int c = 0; c < im.cols; c++)  

8.   {  

9.      ppix_om[c] = ppix_im[c]*scale;  

10.   }  

11. }  

代码段 6. 使用ptr访问矩阵元素

方法3、使用迭代器

    这里使用的迭代器是OpenCV自己定义的。使用迭代器完成第二部分所述算法的代码如代码段7所示。

[cpp] view plaincopy

1. MatIterator_ it_im, itEnd_im;  

2. MatIterator_ it_om;  

3. it_im    = im.begin();  

4. itEnd_im = im.end();  

5. it_om    = om.begin();  

6. for (; it_im != itEnd_im; it_im++, it_om++)  

7. {  

8.   *it_om = (*it_im)*scale;  

9. }  

代码段 7. 使用迭代器访问矩阵元素

方法4、使用Mat_简化索引

    Mat_这个类的元素访问比较容易一点,把原Mat类的对象可以直接赋值给Mat_对象,当然赋值操作并不会开辟新的数据空间,这点大家放心。也就是说使用Mat_时,不会在内存拷贝上花时间。使用这种方法完成第二部分所述算法的代码如代码段8所示。

[cpp] view plaincopy

1. Mat_ im_, om_;  

2. im_ = im;  

3. om_ = om;  

4. for (int r = 0; r < im.rows; r++)  

5. {  

6.   for (int c = 0; c < im.cols; c++)  

7.   {  

8.     om_(r,c) = im_(r,c) * scale;  

9.   }  

10. }  

代码段 8. 使用Mat_访问矩阵数据元素

方法5、使用OpenCV原有的实现

    我们的算法实际上OpenCV中已经有实现。就是×运算符重载,代码如代码段9所示。

[cpp] view plaincopy

1. om = im*scale;  

代码段 9. 使用OpenCV的原有实现访问矩阵元素

四、实验测试

1、测试代码

    为了测试方便,将前面的方法统一写到一个c++源文件test.cpp中,其内容如代码段10所示。

[cpp] view plaincopy

1. /************************************************************************* 

2.   > File Name: test.cpp 

3.   > Author: aban 

4.   > Mail: sawpara@126.com  

5.   > Created Time: 2014年06月13日 星期五 18时47分19秒 

6.  ************************************************************************/  

7.   

8.   

9. #include   

10. #include   

11. using namespace cv;  

12. using namespace std;  

13.   

14. #if defined(_WIN32) && defined(_MSC_VER)  

15. #include   

16. double abtic() {  

17.     __int64 freq;  

18.     __int64 clock;  

19.     QueryPerformanceFrequency( (LARGE_INTEGER *)&freq );  

20.     QueryPerformanceCounter( (LARGE_INTEGER *)&clock );  

21.     return (double)clock/freq*1000*1000;  

22. }  

23. #else  

24. #include   

25. #include   

26. double abtic() {  

27.     double result = 0.0;  

28.     struct timeval tv;  

29.     gettimeofday( &tv, NULL );  

30.     result = tv.tv_sec*1000*1000 + tv.tv_usec;  

31.     return result;  

32. }  

33. #endif /* _WIN32 */  

34.   

35. #define ISSHOW 0  

36.   

37. int main(int argc, char** argv)  

38. {  

39.     double tRecorder(0.0);  

40.     Mat im = imread("./bigim.tif");  

41.     Mat om;  

42.     om.create(im.rows, im.cols, CV_8UC3);  

43.   

44. #if ISSHOW  

45.     imshow("orignal Image", im);  

46.     waitKey();  

47. #endif  

48.       

49.     float scale = 150.0f/255.0f;  

50.   

51.     // 1. using at()  

52.     tRecorder = abtic();  

53.     Vec3b pix;  

54.     for (int r = 0; r < im.rows; r++)  

55.     {  

56.         for (int c = 0; c < im.cols; c++)  

57.         {  

58.             pix = im.at(r,c);  

59.             pix = pix*scale;  

60.             om.at(r,c) = pix;  

61.         }  

62.     }  

63.     cout << (abtic() - tRecorder) << " using at<>()" << endl;  

64. #if ISSHOW  

65.     imshow("Scaled Image: using at<>()", om);  

66.     waitKey();  

67. #endif  

68.   

69.     // 2. using ptr  

70.     tRecorder = abtic();  

71.     Vec3b *ppix_im(NULL);  

72.     Vec3b *ppix_om(NULL);  

73.     for (int r = 0; r < im.rows; r++)  

74.     {  

75.         ppix_im = im.ptr(r);  

76.         ppix_om = om.ptr(r);  

77.         for (int c = 0; c < im.cols; c++)  

78.         {  

79.              ppix_om[c] = ppix_im[c]*scale;  

80.         }  

81.     }  

82.     cout << (abtic() - tRecorder) << " using ptr<>() " << endl;  

83. #if ISSHOW  

84.     imshow("Scaled Image: using ptr<>()", om);  

85.     waitKey();  

86. #endif  

87.   

88.     // 3. using iterator  

89.     tRecorder = abtic();  

90.     MatIterator_ it_im, itEnd_im;  

91.     MatIterator_ it_om;  

92.     it_im    = im.begin();  

93.     itEnd_im = im.end();  

94.     it_om    = om.begin();  

95.     for (; it_im != itEnd_im; it_im++, it_om++)  

96.     {  

97.         *it_om = (*it_im)*scale;  

98.     }  

99.     cout << (abtic() - tRecorder) << " using iterator " << endl;  

100. #if ISSHOW  

101.     imshow("Scaled Image: using iterator", om);  

102.     waitKey();  

103. #endif  

104.   

105.     // 4. using Mat_  

106.     tRecorder = abtic();  

107.     Mat_ im_, om_;  

108.     im_ = im;  

109.     om_ = om;  

110.     for (int r = 0; r < im.rows; r++)  

111.     {  

112.         for (int c = 0; c < im.cols; c++)  

113.         {  

114.             om_(r,c) = im_(r,c) * scale;  

115.         }  

116.     }  

117.     cout << (abtic() - tRecorder) << " using Mat_ " << endl;  

118. #if ISSHOW  

119.     imshow("Scaled Image: using Mat_", om);  

120.     waitKey();  

121. #endif  

122.   

123.     // 5. using *  

124.     tRecorder = abtic();  

125.     om = im*scale;  

126.     cout << (abtic() - tRecorder) << " using * " << endl;  

127. #if ISSHOW  

128.     imshow("Scaled Image: using *", om);  

129.     waitKey();  

130. #endif  

131.   

132.     return 0;  

133. }  

代码段10. 测试代码

    如果你想使用第一部分提到的Makefile,你需要将代码段10保存成test.cpp,或者保存成你希望的某个名字,但是同时应该修改Makfile中的所有“test.cpp”。

    在正确执行之前,将代码段10中的第40行代码改成你的图片名称。

本文来源:https://www.2haoxitong.net/k/doc/961aa5bcc5da50e2524d7fea.html

《五种Mat元素的访问方法.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

文档为doc格式