我想遍历一个二值化的 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));
}
}
此代码段无效,我不知道为什么。
Exception thrown at 0x76C6C42D in example.exe: Microsoft C++ exception: cv::Exception at memory location 0x0019E4F4.
Unhandled exception at 0x76C6C42D in example.exe: Microsoft C++ exception: cv::Exception at memory location 0x0019E4F4.
那么如何计算h
并让指针起作用呢?
最佳答案
您可以避免扫描图像。要将所有白色像素的坐标保存在 vector 中,您可以这样做:
Mat bin;
// fill bin with some value
std::vector<Point> binVec;
findNonZero(bin == 255, binVec);
您可以使用 Point
而不是 Point2i
,因为它们是相同的:
typedef Point2i Point;
如果你真的想使用 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));
}
}
}
请记住:
- 你的二进制图像可能是
CV_8UC1
, 而不是CV_32SC1
, 所以你应该使用uchar
而不是int
. -
bin.ptr<...>(i)
为您提供指向第 i 行开头的指针,因此您应该将其从内部循环中取出。 - 您应该比较值,而不是地址。
-
Point
以x
为参数(cols) 和y
(行),当你经过i
时(行)和j
(列)。所以你需要交换它们。 - 这个循环可以进一步优化,但对于你的任务,我强烈推荐
findNonZero
方法,所以我不在这里显示。
关于c++ - 如何保存到白色像素的 vector 坐标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34721692/