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

时间:2016-01-11 12:33:19

标签: 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));
    }
}

此代码段不起作用,我不知道为什么。

  

example.exe中的0x76C6C42D抛出异常:Microsoft C ++异常:cv ::内存位置0x0019E4F4的异常。

     

example.exe中0x76C6C42D处的未处理异常:Microsoft C ++异常:cv ::内存位置0x0019E4F4处的异常。

那么如何计算h并让指针工作?

2 个答案:

答案 0 :(得分:4)

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

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 rows ),当您传递{{1}时()和i cols )。所以你需要交换它们。
  • 此循环可以进一步优化,但对于您的任务,我强烈推荐使用j方法,因此我不会在此处显示。

答案 1 :(得分:0)

  1. 您只应在内循环中增加h
  2. 您应该将p指向的值与h进行比较,而不是将ph的地址进行比较。
  3. 所以

    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++) {
        for (int j = 0; j < bin.cols; j++) {
            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));
        }
    }