OpenCV Mat.row() 的迭代器是否不适用于 stdlib 算法?
Do iterators of OpenCV Mat.row()'s not work with stdlib algortihms?
在实现一些图像处理算法时,我遇到了 OpenCV 的一个奇怪行为。目标是使用此行的 Mat.row(i) 和 OpenCV 迭代器 (Mat.begin() / Mat.end()) 来应用 C++ 标准库的算法(如 std::transform, std::accumulate, 等等)到底层数据。
#include <numeric>
#include "opencv2/opencv.hpp"
using namespace std;
int main() {
int rows = 3;
int cols = 4;
int x = 1;
int y = 1;
cv::Mat_<float> mat(rows,cols);
iota(mat.begin(),mat.end(),0);
// Element access works (result is always 5)
cout << mat(x,y) << endl;
cout << *(mat.begin()+x*mat.cols+y) << endl;
cout << *(mat.row(x).begin()+y) << endl;
// Range is correct for the Mat (result is 12 = rows * cols) ...
cout << mat.end() - mat.begin() << endl;
cout << mat.begin()+x*mat.cols - mat.begin()+(x+1)*mat.cols << endl;
// ... but incorrect for the row (9223372036854775807)
cout << mat.row(x).end() - mat.row(x).begin() << endl;
// So this works (result is 22 = 4+5+6+7 = sum of row 1) ...
cout << accumulate(mat.begin()+x*mat.cols,mat.begin()+(x+1)*mat.cols,static_cast<float>(0)) << endl;
// ... but this does not.
cout << accumulate(mat.row(x).begin(),mat.row(x).end(),static_cast<float>(0)) << endl;
}
看起来行选择的迭代器不能执行“-”操作,而整个Mat的迭代器可以。
您可以使用 Mat::begin 和 Mat::end 但这些函数必须应用于相同的 Mat
目的。在这一行
cout << mat.row(x).end() - mat.row(x).begin() << endl;
mat.row(x)
的第一次调用创建了新的 Mat
对象,mat.row(x)
的第二次调用创建了另一个新的 Mat
对象。您不能减去 end() 和 begin() 的结果,因为它们引用不同的对象。
你可以写
cv::Mat_<float> rowMat = mat.row(x);
cout << rowMat.end() - rowMat.begin() << endl; // works
和
cout << accumulate(rowMat.begin(),rowMat.end(),static_cast<float>(0)) << endl;
也适用。
在实现一些图像处理算法时,我遇到了 OpenCV 的一个奇怪行为。目标是使用此行的 Mat.row(i) 和 OpenCV 迭代器 (Mat.begin() / Mat.end()) 来应用 C++ 标准库的算法(如 std::transform, std::accumulate, 等等)到底层数据。
#include <numeric>
#include "opencv2/opencv.hpp"
using namespace std;
int main() {
int rows = 3;
int cols = 4;
int x = 1;
int y = 1;
cv::Mat_<float> mat(rows,cols);
iota(mat.begin(),mat.end(),0);
// Element access works (result is always 5)
cout << mat(x,y) << endl;
cout << *(mat.begin()+x*mat.cols+y) << endl;
cout << *(mat.row(x).begin()+y) << endl;
// Range is correct for the Mat (result is 12 = rows * cols) ...
cout << mat.end() - mat.begin() << endl;
cout << mat.begin()+x*mat.cols - mat.begin()+(x+1)*mat.cols << endl;
// ... but incorrect for the row (9223372036854775807)
cout << mat.row(x).end() - mat.row(x).begin() << endl;
// So this works (result is 22 = 4+5+6+7 = sum of row 1) ...
cout << accumulate(mat.begin()+x*mat.cols,mat.begin()+(x+1)*mat.cols,static_cast<float>(0)) << endl;
// ... but this does not.
cout << accumulate(mat.row(x).begin(),mat.row(x).end(),static_cast<float>(0)) << endl;
}
看起来行选择的迭代器不能执行“-”操作,而整个Mat的迭代器可以。
您可以使用 Mat::begin 和 Mat::end 但这些函数必须应用于相同的 Mat
目的。在这一行
cout << mat.row(x).end() - mat.row(x).begin() << endl;
mat.row(x)
的第一次调用创建了新的 Mat
对象,mat.row(x)
的第二次调用创建了另一个新的 Mat
对象。您不能减去 end() 和 begin() 的结果,因为它们引用不同的对象。
你可以写
cv::Mat_<float> rowMat = mat.row(x);
cout << rowMat.end() - rowMat.begin() << endl; // works
和
cout << accumulate(rowMat.begin(),rowMat.end(),static_cast<float>(0)) << endl;
也适用。