我想遍历一个二cv::Mat值化并保存值为255.
cv::Mat bin;
std::vector<cv::Point2i> binVec;
int h = 0;
int white = 254; //Just for comparison with pointer of Matrix value
for (int i = 0; i < bin.rows; i++, h++) {
for (int j = 0; j < bin.cols; j++, h++) {
int* p = bin.ptr<int>(h); //Pointer to bin Data, should loop through Matrix
if (p >= &white) //If a white pixel has been found, push i and j in binVec
binVec.push_back(cv::Point2i(i, j));
}
}
Run Code Online (Sandbox Code Playgroud)
此代码段不起作用,我不知道为什么。
在 example.exe 中的 0x76C6C42D 处引发异常:Microsoft C++ 异常:内存位置 0x0019E4F4 处的 cv::Exception。
example.exe 中 0x76C6C42D 处未处理的异常:Microsoft C++ 异常:内存位置 0x0019E4F4 处的 cv::Exception。
那么我怎样才能计数h并让指针工作呢?
您可以避免扫描图像。要将所有白色像素的坐标保存在向量中,您可以这样做:
Mat bin;
// fill bin with some value
std::vector<Point> binVec;
findNonZero(bin == 255, binVec);
Run Code Online (Sandbox Code Playgroud)
您可以使用Point代替Point2i,因为它们是相同的:
typedef Point2i Point;
Run Code Online (Sandbox Code Playgroud)
如果你真的想使用 for 循环,你应该这样做:
const uchar white = 255;
for (int r = 0; r < bin.rows; ++r)
{
uchar* ptr = bin.ptr<uchar>(r);
for(int c = 0; c < bin.cols; ++c)
{
if (ptr[c] == 255) {
binVec.push_back(Point(c,r));
}
}
}
Run Code Online (Sandbox Code Playgroud)
请记住:
CV_8UC1,而不是CV_32SC1,因此您应该使用uchar代替int。bin.ptr<...>(i) 给你一个指向第 i 行开头的指针,所以你应该把它从内部循环中取出。Point将x( cols ) 和y( rows )作为参数,同时传递i( rows ) 和j( cols )。所以你需要交换它们。findNonZero方法,所以我不在这里展示。