如何保存到白色像素的矢量坐标?

Fli*_*ppy 0 c++ opencv

我想遍历一个二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并让指针工作呢?

Mik*_*iki 5

您可以避免扫描图像。要将所有白色像素的坐标保存在向量中,您可以这样做:

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 行开头的指针,所以你应该把它从内部循环中取出。
  • 您应该比较,而不是地址
  • Pointx( cols ) 和y( rows )作为参数,同时传递i( rows ) 和j( cols )。所以你需要交换它们。
  • 这个循环可以进一步优化,但对于你的任务,我强烈推荐这种findNonZero方法,所以我不在这里展示。