获取顶部和底部白色像素的坐标以绘制线条

时间:2017-02-08 08:29:30

标签: c++ opencv bitmap coordinate

我在位图扩展中有以下二进制图像:

enter image description here

现在我想:

  1. 获取顶部和底部白色像素(蓝色标记)的坐标
  2. 画一条与黄色线相交的线(黄线)(如下图所示)
  3. enter image description here

    我尝试了image.at<uchar>(i,j)函数,Mat image = imread("Before.bmp"); int i=1; imshow("Before", image); vector<Point> locations; // output, locations of non-zero pixels cv::findNonZero(image, locations); Point pnt = locations[i]; /Assertion error for (int i = 0; i < image.rows; i++) { for (int j = 0; j < image.cols; j++) { if (image.at<uchar>(i,j) == 255 ) { cout << i << ", " << j << endl; //give wrong coordinate } } } //imshow("black", image); //imwrite("blackie.bmp", image); waitKey(0); return(0); 但没有成功。如果有人能帮助我,真的很感激。提前谢谢!

    {{1}}

1 个答案:

答案 0 :(得分:0)

您可以使用cv::findNonZero查找任何非零(即非黑色)像素的坐标。根据文档,此功能要求输入为单通道图像,因此您需要先转换为灰度。

在下面的例子中,我假设白线从顶部到底部的行一直是这样的,并且在图像的顶部和底部边缘处恰好有两条线(就像在你的形象)。您可能希望将其扩展为更灵活。

示例代码

#include <opencv2/opencv.hpp>

int main(int argc, char *argv[])
{
    cv::Mat image(cv::imread("foo.png"));

    cv::Mat gray;
    cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);

    std::vector<cv::Point> locations[2];

    // Top points
    cv::findNonZero(gray.row(0), locations[0]);

    // Bottom points (need to offset Y since we take a single row ROI)
    cv::findNonZero(gray.row(image.rows - 1), locations[1]);
    for (auto& p : locations[1]) {
        p.y += image.rows - 1;
    }

    // Validate our assumption of having exactly two points on both top as well as bottom row
    if ((locations[0].size() != 2) && (locations[0].size() != 2)) {
        std::cerr << "Unexpected input.\n";
        return -1;
    }

    for (int i(0); i < 2; ++i) {
        cv::line(image, locations[0][i], locations[1][i], cv::Scalar(0, 255, 255));
    }
    cv::imwrite("foo_out.png", image);
}

示例输出

enter image description here