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
7. pix = pix*scale;
8. om.at
9. }
10. }
代码段4. 使用at<>()函数访问矩阵元素
注意:使用at函数时,应该知道矩阵元素的类型和通道数,根据矩阵元素类型和通道数来确定at函数传递的类型,代码段4中使用的是Vec3b这个元素类型,他是一个包含3个unsigned char类型向量。之所以采用这个类型来接受at的返回值,是因为,我们的矩阵im是3通道,类型为unsigned char类型的。
此函数也是模板函数,我们将会用到的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
6. ppix_om = om.ptr
7. for (int c = 0; c < im.cols; c++)
8. {
9. ppix_om[c] = ppix_im[c]*scale;
10. }
11. }
代码段 6. 使用ptr访问矩阵元素
这里使用的迭代器是OpenCV自己定义的。使用迭代器完成第二部分所述算法的代码如代码段7所示。
[cpp] view plaincopy
1. MatIterator_
2. MatIterator_
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. 使用迭代器访问矩阵元素
Mat_这个类的元素访问比较容易一点,把原Mat类的对象可以直接赋值给Mat_对象,当然赋值操作并不会开辟新的数据空间,这点大家放心。也就是说使用Mat_时,不会在内存拷贝上花时间。使用这种方法完成第二部分所述算法的代码如代码段8所示。
[cpp] view plaincopy
1. Mat_
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_访问矩阵数据元素
我们的算法实际上OpenCV中已经有实现。就是×运算符重载,代码如代码段9所示。
[cpp] view plaincopy
1. om = im*scale;
代码段 9. 使用OpenCV的原有实现访问矩阵元素
为了测试方便,将前面的方法统一写到一个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
59. pix = pix*scale;
60. om.at
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
76. ppix_om = om.ptr
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_
91. MatIterator_
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_
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
文档为doc格式